int fetch_hdr_callback(void *tree) { int r; struct tree *t = (struct tree*)tree; r = deserialize_hdr_from_disk(t->fd, t->block, &t->hdr); if (r != NESS_OK) __PANIC("fetch tree header from disk error, errno [%d]", r); return r; }
void sstdata_build(sst_data_t* sstdata) { __INFO("sstdata build : %s",sstdata->filename); sstdata->file = fopen(sstdata->filename,"wb+"); if(!sstdata->file) __PANIC("file open failed -- exiting:%s",sstdata->filename); sstdata->key_num = 0; sstdata->keys = (data_t*)xmalloc(sstdata->max * sizeof(data_t*)); }
// Create a mutex semaphore void _mwmutex_create(_lock_t *mutex_ptr) { #if _REENTRANT _lock_t sem = alloc_sema(); if (sem == 0) __PANIC(); sem->latch = rtos_latch_unlocked(); sem->count = 0; sem->th_id = 0; sem->next = 0; *mutex_ptr = sem; #endif }
int flush_node_callback(void *tree, struct node *n) { int r; struct timespec t1, t2; struct tree *t = (struct tree*)tree; gettime(&t1); r = serialize_node_to_disk(t->fd, t->block, n, t->hdr); gettime(&t2); t->status->tree_node_flush_costs += time_diff_ms(t1, t2); t->status->tree_node_flush_nums++; if (r != NESS_OK) __PANIC("flush node to disk error, errno [%d]", r); return r; }
int fetch_node_callback(void *tree, NID nid, struct node **n) { int r; struct timespec t1, t2; struct tree *t = (struct tree*)tree; gettime(&t1); r = deserialize_node_from_disk(t->fd, t->block, t->hdr, nid, n); gettime(&t2); atomic64_add(&t->status->tree_node_fetch_costs, (uint64_t)time_diff_ms(t1, t2)); atomic64_increment(&t->status->tree_node_fetch_nums); if (r != NESS_OK) __PANIC("fetch node from disk error, errno [%d]", r); return r; }
int _search_leaf(struct cursor *cur, struct search *so, struct node *n) { int i = 0; int bsms_size; struct ancestors *ances; ancestors_append(cur, n->u.l.le->bsm); ances = cur->ances; bsms_size = cur->ances_size; struct basement *bsms[bsms_size]; /* * bsms[0 - 1] is memtable basement * the last one is root's */ while (ances) { bsms[i++] = (struct basement*) ances->v; ances = ances->next; } switch (so->direction) { case SEARCH_FORWARD: return _findsmallest(bsms, bsms_size, cur, so); break; case SEARCH_BACKWARD: return _findlargest(bsms, bsms_size, cur, so); break; default: __PANIC("unsupport direction %u", so->direction); } }
int main(int argc, char **argv) { (void) argc; (void) argv; _svr.bindaddr = HOST; _svr.port = PORT; _svr.db = silokatana_open(); _svr.el = aeCreateEventLoop(11024); _svr.fd = anetTcpServer(_svr.neterr, _svr.port, _svr.bindaddr); if (_svr.fd == ANET_ERR) { __PANIC("openning port error #%d:%s", _svr.port, _svr.neterr); exit(1); } if (anetNonBlock(_svr.neterr, _svr.fd) == ANET_ERR) { __ERROR("set nonblock #%s",_svr.neterr); exit(1); } aeCreateTimeEvent(_svr.el, 3000, server_cron, NULL, NULL); if (aeCreateFileEvent(_svr.el, _svr.fd, AE_READABLE, accept_handler, NULL) == AE_ERR) __ERROR("creating file event"); __INFO("siloserver starting, port:%d, pid:%d", PORT, (long)getpid()); printf("%s", _ascii_logo); aeMain(_svr.el); __ERROR("oops,exit"); aeDeleteEventLoop(_svr.el); silokatana_close(_svr.db); return 1; }
/* * REQUIRES: * a) cache list read(write) lock * * PROCESSES: * a) lock hash chain * b) find pair via key * c) if found, lock the value and return * d) if not found: * d0) list lock * d1) add to cache/evict/clean list * d2) value lock * d3) list unlock * d4) disk-mtx lock * d5) fetch from disk * d6) disk-mtx unlock */ int cache_get_and_pin(struct cache_file *cf, NID k, struct node **n, enum lock_type locktype) { struct cpair *p; struct cache *c = cf->cache; TRY_PIN: /* make room for me, please */ _make_room(c); cpair_locked_by_key(c->table, k); p = cpair_htable_find(c->table, k); cpair_unlocked_by_key(c->table, k); if (p) { if (locktype != L_READ) { if (!try_write_lock(&p->value_lock)) goto TRY_PIN; } else { if (!try_read_lock(&p->value_lock)) goto TRY_PIN; } *n = p->v; return NESS_OK; } cpair_locked_by_key(c->table, k); p = cpair_htable_find(c->table, k); if (p) { /* * if we go here, means that someone got before us * try pin again */ cpair_unlocked_by_key(c->table, k); goto TRY_PIN; } struct tree_callback *tcb = cf->tcb; struct tree *tree = (struct tree*)cf->args; int r = tcb->fetch_node(tree, k, n); if (r != NESS_OK) { __PANIC("fetch node from disk error, nid [%" PRIu64 "], errno %d", k, r); goto ERR; } p = cpair_new(); cpair_init(p, *n, cf); /* add to cache list */ write_lock(&c->clock_lock); _cache_insert(c, p); write_unlock(&c->clock_lock); if (locktype != L_READ) { write_lock(&p->value_lock); } else { read_lock(&p->value_lock); } cpair_unlocked_by_key(c->table, k); return NESS_OK; ERR: return NESS_ERR; }
struct tree *tree_open(const char *dbname, struct env *e, struct tree_callback *tcb) { int fd; int flag; mode_t mode; int is_create = 0; struct tree *t; struct node *root; struct cache_file *cf; t = xcalloc(1, sizeof(*t)); t->e = e; mode = S_IRWXU | S_IRWXG | S_IRWXO; flag = O_RDWR | O_BINARY; if (e->use_directio) fd = ness_os_open_direct(dbname, flag, mode); else fd = ness_os_open(dbname, flag, mode); if (fd == -1) { if (e->use_directio) fd = ness_os_open(dbname, flag | O_CREAT, mode); else fd = ness_os_open_direct(dbname, flag | O_CREAT, mode); if (fd == -1) goto ERR; is_create = 1; } t->fd = fd; t->hdr = hdr_new(e); /* tree header */ if (!is_create) { tcb->fetch_hdr_cb(fd, t->hdr); } /* create cache file */ cf = cache_file_create(e->cache, t->fd, t->hdr, tcb); t->cf = cf; /* tree root node */ if (is_create) { NID nid = hdr_next_nid(t->hdr); node_create(nid, 0, 1, t->hdr->version, t->e, &root); cache_put_and_pin(cf, nid, root); root->isroot = 1; node_set_dirty(root); cache_unpin(cf, root->cpair, make_cpair_attr(root)); t->hdr->root_nid = root->nid; __DEBUG("create new root, NID %"PRIu64, root->nid); } else { /* get the root node */ if (cache_get_and_pin(cf, t->hdr->root_nid, (void**)&root, L_READ) != NESS_OK) __PANIC("get root from cache error [%" PRIu64 "]", t->hdr->root_nid); root->isroot = 1; cache_unpin(cf, root->cpair, make_cpair_attr(root)); __DEBUG("fetch root, NID %"PRIu64, root->nid); } return t; ERR: xfree(t); return NESS_ERR; }
void *_write_mmap(struct silopit *silopit, struct skipnode *x, size_t count, int need_new) { int i, j, c_clone; int fd; int sizes; int result; char file[FILE_PATH_SIZE]; struct skipnode *last; struct footer footer; struct stats stats; int fsize = sizeof(struct footer); memset(&footer, 0, fsize); _prepare_stats(x, count, &stats); sizes = stats.mmap_size; struct inner_block { char key[stats.max_len]; char offset[8]; }; struct inner_block *blks; memset(file, 0, FILE_PATH_SIZE); snprintf(file, FILE_PATH_SIZE, "%s/%s", silopit->basedir, silopit->name); fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0644); if (fd == -1) __PANIC("error creating silopit file"); if (lseek(fd, sizes - 1, SEEK_SET) == -1) __PANIC("error lseek silopit"); result = write(fd, "", 1); if (result == -1) __PANIC("error writing empty"); blks = mmap(0, sizes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (blks == MAP_FAILED) { __PANIC("error mapping block when write on process"); } last = x; c_clone = count; for (i = 0, j = 0; i < c_clone; i++) { if (x->opt == ADD) { buffer_putstr(silopit->buf, x->key); buffer_putc(silopit->buf, 0); buffer_putlong(silopit->buf, x->val); j++; } else count--; last = x; x = x->forward[0]; } char *strings = buffer_detach(silopit->buf); memcpy(blks, strings, sizes); #ifdef MSYNC if (msync(blks, sizes, MS_SYNC) == -1) { __ERROR("Error Msync"); } #endif if (munmap(blks, sizes) == -1) { __ERROR("Un-mmapping the file"); } footer.count = to_be32(count); footer.crc = to_be32(F_CRC); footer.size = to_be32(sizes); footer.max_len = to_be32(stats.max_len); memcpy(footer.key, last->key, strlen(last->key)); result = write(fd, &footer, fsize); if (result == -1) __PANIC("writing the footer"); struct meta_node mn; mn.count = count; memset(mn.end, 0, SILOKATANA_MAX_KEY_SIZE); memcpy(mn.end, last->key, SILOKATANA_MAX_KEY_SIZE); memset(mn.index_name, 0, FILE_NAME_SIZE); memcpy(mn.index_name, silopit->name, FILE_NAME_SIZE); if (need_new) meta_set(silopit->meta, &mn); else meta_set_byname(silopit->meta, &mn); close(fd); return x; }