/** * Basic tests of ndn_btree_io_from_directory() and its methods. * * Assumes TEST_DIRECTORY has been set. */ static int test_btree_io(void) { int res; struct ndn_btree_node nodespace = {0}; struct ndn_btree_node *node = &nodespace; struct ndn_btree_io *io = NULL; /* Open it up. */ io = ndn_btree_io_from_directory(getenv("TEST_DIRECTORY"), NULL); CHKPTR(io); node->buf = ndn_charbuf_create(); CHKPTR(node->buf); node->nodeid = 12345; res = io->btopen(io, node); CHKSYS(res); FAILIF(node->iodata == NULL); ndn_charbuf_putf(node->buf, "smoke"); res = io->btwrite(io, node); CHKSYS(res); node->buf->length = 0; ndn_charbuf_putf(node->buf, "garbage"); res = io->btread(io, node, 500000); CHKSYS(res); FAILIF(node->buf->length != 5); FAILIF(node->buf->limit > 10000); node->clean = 5; ndn_charbuf_putf(node->buf, "r"); res = io->btwrite(io, node); CHKSYS(res); node->buf->length--; ndn_charbuf_putf(node->buf, "d"); res = io->btread(io, node, 1000); CHKSYS(res); FAILIF(0 != strcmp("smoker", ndn_charbuf_as_string(node->buf))); node->buf->length--; res = io->btwrite(io, node); CHKSYS(res); node->buf->length = 0; ndn_charbuf_putf(node->buf, "garbage"); node->clean = 0; res = io->btread(io, node, 1000); CHKSYS(res); res = io->btclose(io, node); CHKSYS(res); FAILIF(node->iodata != NULL); FAILIF(0 != strcmp("smoke", ndn_charbuf_as_string(node->buf))); res = io->btdestroy(&io); CHKSYS(res); ndn_charbuf_destroy(&node->buf); return(res); }
/** * Use standard mkdtemp() to create a subdirectory of the * current working directory, and set the TEST_DIRECTORY environment * variable with its name. */ static int test_directory_creation(void) { int res; struct ndn_charbuf *dirbuf; char *temp; dirbuf = ndn_charbuf_create(); CHKPTR(dirbuf); res = ndn_charbuf_putf(dirbuf, "./%s", "_bt_XXXXXX"); CHKSYS(res); temp = mkdtemp(ndn_charbuf_as_string(dirbuf)); CHKPTR(temp); res = ndn_charbuf_putf(dirbuf, "/%s", "_test"); CHKSYS(res); res = mkdir(ndn_charbuf_as_string(dirbuf), 0777); CHKSYS(res); printf("Created directory %s\n", ndn_charbuf_as_string(dirbuf)); setenv("TEST_DIRECTORY", ndn_charbuf_as_string(dirbuf), 1); ndn_charbuf_destroy(&dirbuf); return(res); }
/** * Test that the lockfile works. */ int test_btree_lockfile(void) { int res; struct ndn_btree_io *io = NULL; struct ndn_btree_io *io2 = NULL; io = ndn_btree_io_from_directory(getenv("TEST_DIRECTORY"), NULL); CHKPTR(io); /* Make sure the locking works */ errno = 0; io2 = ndn_btree_io_from_directory(getenv("TEST_DIRECTORY"), NULL); FAILIF(io2 != NULL || errno == 0); errno=EINVAL; res = io->btdestroy(&io); CHKSYS(res); FAILIF(io != NULL); return(res); }
PUBLIC void r_store_init(struct ccnr_handle *h) { struct ccn_btree *btree = NULL; struct ccn_btree_node *node = NULL; struct hashtb_param param = {0}; int i; int j; int res; struct ccn_charbuf *path = NULL; struct ccn_charbuf *msgs = NULL; off_t offset; path = ccn_charbuf_create(); param.finalize_data = h; param.finalize = 0; h->cob_limit = r_init_confval(h, "CCNR_CONTENT_CACHE", 16, 2000000, 4201); h->cookie_limit = choose_limit(h->cob_limit, (ccnr_cookie)(~0U)); h->content_by_cookie = calloc(h->cookie_limit, sizeof(h->content_by_cookie[0])); CHKPTR(h->content_by_cookie); h->content_by_accession_tab = hashtb_create(sizeof(struct content_by_accession_entry), NULL); CHKPTR(h->content_by_accession_tab); h->btree = btree = ccn_btree_create(); CHKPTR(btree); FAILIF(btree->nextnodeid != 1); ccn_charbuf_putf(path, "%s/index", h->directory); res = mkdir(ccn_charbuf_as_string(path), 0700); if (res != 0 && errno != EEXIST) r_init_fail(h, __LINE__, ccn_charbuf_as_string(path), errno); else { msgs = ccn_charbuf_create(); btree->io = ccn_btree_io_from_directory(ccn_charbuf_as_string(path), msgs); if (btree->io == NULL) res = errno; if (msgs->length != 0 && CCNSHOULDLOG(h, sffdsdf, CCNL_WARNING)) { ccnr_msg(h, "while initializing %s - %s", ccn_charbuf_as_string(path), ccn_charbuf_as_string(msgs)); } ccn_charbuf_destroy(&msgs); if (btree->io == NULL) r_init_fail(h, __LINE__, ccn_charbuf_as_string(path), res); } node = ccn_btree_getnode(btree, 1, 0); if (btree->io != NULL) btree->nextnodeid = btree->io->maxnodeid + 1; CHKPTR(node); if (node->buf->length == 0) { res = ccn_btree_init_node(node, 0, 'R', 0); CHKSYS(res); } ccn_charbuf_destroy(&path); if (h->running == -1) return; r_store_read_stable_point(h); h->active_in_fd = -1; h->active_out_fd = r_io_open_repo_data_file(h, "repoFile1", 1); /* output */ offset = lseek(h->active_out_fd, 0, SEEK_END); h->startupbytes = offset; if (offset != h->stable || node->corrupt != 0) { ccnr_msg(h, "Index not current - resetting"); ccn_btree_init_node(node, 0, 'R', 0); node = NULL; ccn_btree_destroy(&h->btree); path = ccn_charbuf_create(); /* Remove old index files to avoid confusion */ for (i = 1, j = 0; i > 0 && j < 3; i++) { path->length = 0; res = ccn_charbuf_putf(path, "%s/index/%d", h->directory, i); if (res >= 0) res = unlink(ccn_charbuf_as_string(path)); if (res < 0) j++; } h->btree = btree = ccn_btree_create(); path->length = 0; ccn_charbuf_putf(path, "%s/index", h->directory); btree->io = ccn_btree_io_from_directory(ccn_charbuf_as_string(path), msgs); CHKPTR(btree->io); btree->io->maxnodeid = 0; btree->nextnodeid = 1; node = ccn_btree_getnode(btree, 1, 0); btree->nextnodeid = btree->io->maxnodeid + 1; ccn_btree_init_node(node, 0, 'R', 0); h->stable = 0; h->active_in_fd = r_io_open_repo_data_file(h, "repoFile1", 0); /* input */ ccn_charbuf_destroy(&path); if (CCNSHOULDLOG(h, dfds, CCNL_INFO)) ccn_schedule_event(h->sched, 50000, r_store_reindexing, NULL, 0); } if (CCNSHOULDLOG(h, weuyg, CCNL_FINEST)) { FILE *dumpfile = NULL; path = ccn_charbuf_create(); ccn_charbuf_putf(path, "%s/index/btree_check.out", h->directory); dumpfile = fopen(ccn_charbuf_as_string(path), "w"); res = ccn_btree_check(btree, dumpfile); if (dumpfile != NULL) { fclose(dumpfile); dumpfile = NULL; } else path->length = 0; ccnr_msg(h, "ccn_btree_check returned %d (%s)", res, ccn_charbuf_as_string(path)); ccn_charbuf_destroy(&path); if (res < 0) r_init_fail(h, __LINE__, "index is corrupt", res); } btree->full = r_init_confval(h, "CCNR_BTREE_MAX_FANOUT", 4, 9999, 1999); btree->full0 = r_init_confval(h, "CCNR_BTREE_MAX_LEAF_ENTRIES", 4, 9999, 1999); btree->nodebytes = r_init_confval(h, "CCNR_BTREE_MAX_NODE_BYTES", 1024, 8388608, 2097152); btree->nodepool = r_init_confval(h, "CCNR_BTREE_NODE_POOL", 16, 2000000, 512); if (h->running != -1) r_store_index_needs_cleaning(h); }