int main(int argc, char *argv[]) { unsigned int i; struct ntdb_context *ntdb; struct agent *agent; union ntdb_attribute cif; NTDB_DATA key = ntdb_mkdata(KEY_STR, strlen(KEY_STR)); int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; cif.openhook.base.attr = NTDB_ATTRIBUTE_OPENHOOK; cif.openhook.base.next = &tap_log_attr; cif.openhook.fn = clear_if_first; cif.openhook.data = clear_if_first; agent = prepare_external_agent(); plan_tests(sizeof(flags) / sizeof(flags[0]) * 13); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { /* Create it */ ntdb = ntdb_open("run-83-openhook.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, NULL); ok1(ntdb); ok1(ntdb_store(ntdb, key, key, NTDB_REPLACE) == 0); ntdb_close(ntdb); /* Now, open with CIF, should clear it. */ ntdb = ntdb_open("run-83-openhook.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR, 0, &cif); ok1(ntdb); ok1(!ntdb_exists(ntdb, key)); ok1(ntdb_store(ntdb, key, key, NTDB_REPLACE) == 0); /* Agent should not clear it, since it's still open. */ ok1(external_agent_operation(agent, OPEN_WITH_HOOK, "run-83-openhook.ntdb") == SUCCESS); ok1(external_agent_operation(agent, FETCH, KEY_STR "=" KEY_STR) == SUCCESS); ok1(external_agent_operation(agent, CLOSE, "") == SUCCESS); /* Still exists for us too. */ ok1(ntdb_exists(ntdb, key)); /* Close it, now agent should clear it. */ ntdb_close(ntdb); ok1(external_agent_operation(agent, OPEN_WITH_HOOK, "run-83-openhook.ntdb") == SUCCESS); ok1(external_agent_operation(agent, FETCH, KEY_STR "=" KEY_STR) == FAILED); ok1(external_agent_operation(agent, CLOSE, "") == SUCCESS); ok1(tap_log_messages == 0); } free_external_agent(agent); return exit_status(); }
int main(int argc, char *argv[]) { unsigned int i; struct agent *agent; struct ntdb_context *ntdb; NTDB_DATA d = ntdb_mkdata("hello", 5); const char filename[] = "run-remap-in-read_traverse.ntdb"; plan_tests(4); agent = prepare_external_agent(); ntdb = ntdb_open(filename, MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); ok1(external_agent_operation(agent, OPEN, filename) == SUCCESS); i = add_records_to_grow(agent, ntdb->file->fd, ntdb->file->map_size); /* Do a traverse. */ ok1(ntdb_traverse(ntdb, NULL, NULL) == i); /* Now store something! */ ok1(ntdb_store(ntdb, d, d, NTDB_INSERT) == 0); ok1(tap_log_messages == 0); ntdb_close(ntdb); free_external_agent(agent); return exit_status(); }
int main(int argc, char *argv[]) { unsigned int i; struct ntdb_context *ntdb; int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP, NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; NTDB_DATA key = ntdb_mkdata("key", 3); NTDB_DATA data = ntdb_mkdata("data", 4); plan_tests(sizeof(flags) / sizeof(flags[0]) * 7 + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { ntdb = ntdb_open("run-simple-delete.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); ok1(ntdb); if (ntdb) { /* Delete should fail. */ ok1(ntdb_delete(ntdb, key) == NTDB_ERR_NOEXIST); ok1(ntdb_check(ntdb, NULL, NULL) == 0); /* Insert should succeed. */ ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0); ok1(ntdb_check(ntdb, NULL, NULL) == 0); /* Delete should now work. */ ok1(ntdb_delete(ntdb, key) == 0); ok1(ntdb_check(ntdb, NULL, NULL) == 0); ntdb_close(ntdb); } } ok1(tap_log_messages == 0); return exit_status(); }
static void store_ntdb(char *keyname, size_t keylen, char* data, size_t datalen) { NTDB_DATA key, dbuf; enum NTDB_ERROR ecode; if ((keyname == NULL) || (keylen == 0)) { terror(NTDB_SUCCESS, "need key"); return; } if ((data == NULL) || (datalen == 0)) { terror(NTDB_SUCCESS, "need data"); return; } key.dptr = (unsigned char *)keyname; key.dsize = keylen; dbuf.dptr = (unsigned char *)data; dbuf.dsize = datalen; printf("Storing key:\n"); print_rec(ntdb, key, dbuf, NULL); ecode = ntdb_store(ntdb, key, dbuf, NTDB_REPLACE); if (ecode) { terror(ecode, "store failed"); } }
int main(int argc, char *argv[]) { unsigned int i, j; struct ntdb_context *ntdb; int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; NTDB_DATA key = { (unsigned char *)&j, sizeof(j) }; NTDB_DATA data = { (unsigned char *)&j, sizeof(j) }; plan_tests(sizeof(flags) / sizeof(flags[0]) * 8 + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { uint64_t features; ntdb = ntdb_open("run-features.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); ok1(ntdb); if (!ntdb) continue; /* Put some stuff in there. */ for (j = 0; j < 100; j++) { if (ntdb_store(ntdb, key, data, NTDB_REPLACE) != 0) fail("Storing in ntdb"); } /* Mess with features fields in hdr. */ features = (~NTDB_FEATURE_MASK ^ 1); ok1(ntdb_write_convert(ntdb, offsetof(struct ntdb_header, features_used), &features, sizeof(features)) == 0); ok1(ntdb_write_convert(ntdb, offsetof(struct ntdb_header, features_offered), &features, sizeof(features)) == 0); ntdb_close(ntdb); ntdb = ntdb_open("run-features.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR, 0, &tap_log_attr); ok1(ntdb); if (!ntdb) continue; /* Should not have changed features offered. */ ok1(ntdb_read_convert(ntdb, offsetof(struct ntdb_header, features_offered), &features, sizeof(features)) == 0); ok1(features == (~NTDB_FEATURE_MASK ^ 1)); /* Should have cleared unknown bits in features_used. */ ok1(ntdb_read_convert(ntdb, offsetof(struct ntdb_header, features_used), &features, sizeof(features)) == 0); ok1(features == (1 & NTDB_FEATURE_MASK)); ntdb_close(ntdb); } ok1(tap_log_messages == 0); return exit_status(); }
static enum NTDB_ERROR parse(NTDB_DATA key, NTDB_DATA data, NTDB_DATA *expected) { NTDB_DATA add = ntdb_mkdata("another", strlen("another")); if (!ntdb_deq(data, *expected)) { return NTDB_ERR_EINVAL; } /* These should all fail.*/ if (!xfail(ntdb_store(ntdb, add, add, NTDB_INSERT))) { return NTDB_ERR_EINVAL; } tap_log_messages--; if (!xfail(ntdb_append(ntdb, key, add))) { return NTDB_ERR_EINVAL; } tap_log_messages--; if (!xfail(ntdb_delete(ntdb, key))) { return NTDB_ERR_EINVAL; } tap_log_messages--; if (!xfail(ntdb_transaction_start(ntdb))) { return NTDB_ERR_EINVAL; } tap_log_messages--; if (!xfail(ntdb_chainlock(ntdb, key))) { return NTDB_ERR_EINVAL; } tap_log_messages--; if (!xfail(ntdb_lockall(ntdb))) { return NTDB_ERR_EINVAL; } tap_log_messages--; if (!xfail(ntdb_wipe_all(ntdb))) { return NTDB_ERR_EINVAL; } tap_log_messages--; if (!xfail(ntdb_repack(ntdb))) { return NTDB_ERR_EINVAL; } tap_log_messages--; /* Access the record one more time. */ if (!ntdb_deq(data, *expected)) { return NTDB_ERR_EINVAL; } return NTDB_SUCCESS; }
/* traverse function for repacking */ static int repack_traverse(struct ntdb_context *ntdb, NTDB_DATA key, NTDB_DATA data, struct traverse_state *state) { state->error = ntdb_store(state->dest_db, key, data, NTDB_INSERT); if (state->error != NTDB_SUCCESS) { return -1; } return 0; }
static bool store_records(struct ntdb_context *ntdb) { int i; NTDB_DATA key = { (unsigned char *)&i, sizeof(i) }; NTDB_DATA data = { (unsigned char *)&i, sizeof(i) }; for (i = 0; i < NUM_RECORDS; i++) if (ntdb_store(ntdb, key, data, NTDB_REPLACE) != 0) return false; return true; }
static bool store_all(struct ntdb_context *ntdb) { unsigned int i; NTDB_DATA key = { (unsigned char *)&i, sizeof(i) }; NTDB_DATA dbuf = { (unsigned char *)&i, sizeof(i) }; for (i = 0; i < NUM_TESTS; i++) { if (ntdb_store(ntdb, key, dbuf, NTDB_INSERT) != NTDB_SUCCESS) return false; } return true; }
int main(int argc, char *argv[]) { unsigned int i; struct ntdb_context *ntdb; int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP, NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; NTDB_DATA key = ntdb_mkdata("key", 3); NTDB_DATA data; data.dptr = malloc(MAX_SIZE); memset(data.dptr, 0x24, MAX_SIZE); plan_tests(sizeof(flags) / sizeof(flags[0]) * (3 + (1 + (MAX_SIZE/SIZE_STEP)) * 2) + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { ntdb = ntdb_open("run-record-expand.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); ok1(ntdb); if (!ntdb) continue; data.dsize = 0; ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0); ok1(ntdb_check(ntdb, NULL, NULL) == 0); for (data.dsize = 0; data.dsize < MAX_SIZE; data.dsize += SIZE_STEP) { memset(data.dptr, data.dsize, data.dsize); ok1(ntdb_store(ntdb, key, data, NTDB_MODIFY) == 0); ok1(ntdb_check(ntdb, NULL, NULL) == 0); } ntdb_close(ntdb); } ok1(tap_log_messages == 0); free(data.dptr); return exit_status(); }
int main(int argc, char *argv[]) { unsigned int i; struct ntdb_context *ntdb; int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; plan_tests(sizeof(flags) / sizeof(flags[0]) * 11); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { union ntdb_attribute *attr; NTDB_DATA key = ntdb_mkdata("key", 3), data; ntdb = ntdb_open("run-91-get-stats.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); ok1(ntdb); /* Force an expansion */ data.dsize = 65536; data.dptr = calloc(data.dsize, 1); ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == 0); free(data.dptr); /* Use malloc so valgrind will catch overruns. */ attr = malloc(sizeof *attr); attr->stats.base.attr = NTDB_ATTRIBUTE_STATS; attr->stats.size = sizeof(*attr); ok1(ntdb_get_attribute(ntdb, attr) == 0); ok1(attr->stats.size == sizeof(*attr)); ok1(attr->stats.allocs > 0); ok1(attr->stats.expands > 0); ok1(attr->stats.locks > 0); free(attr); /* Try short one. */ attr = malloc(offsetof(struct ntdb_attribute_stats, allocs) + sizeof(attr->stats.allocs)); attr->stats.base.attr = NTDB_ATTRIBUTE_STATS; attr->stats.size = offsetof(struct ntdb_attribute_stats, allocs) + sizeof(attr->stats.allocs); ok1(ntdb_get_attribute(ntdb, attr) == 0); ok1(attr->stats.size == sizeof(*attr)); ok1(attr->stats.allocs > 0); free(attr); ok1(tap_log_messages == 0); ntdb_close(ntdb); } return exit_status(); }
int main(int argc, char *argv[]) { unsigned int i, j; struct ntdb_context *ntdb; int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP, NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; NTDB_DATA key = { (unsigned char *)&j, sizeof(j) }; NTDB_DATA data = { (unsigned char *)&j, sizeof(j) }; char *summary; plan_tests(sizeof(flags) / sizeof(flags[0]) * (1 + 2 * 5) + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { ntdb = ntdb_open("run-summary.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); ok1(ntdb); if (!ntdb) continue; /* Put some stuff in there. */ for (j = 0; j < 500; j++) { /* Make sure padding varies to we get some graphs! */ data.dsize = j % (sizeof(j) + 1); if (ntdb_store(ntdb, key, data, NTDB_REPLACE) != 0) fail("Storing in ntdb"); } for (j = 0; j <= NTDB_SUMMARY_HISTOGRAMS; j += NTDB_SUMMARY_HISTOGRAMS) { ok1(ntdb_summary(ntdb, j, &summary) == NTDB_SUCCESS); ok1(strstr(summary, "Number of records: 500\n")); ok1(strstr(summary, "Smallest/average/largest keys: 4/4/4\n")); ok1(strstr(summary, "Smallest/average/largest data: 0/2/4\n")); if (j == NTDB_SUMMARY_HISTOGRAMS) { ok1(strstr(summary, "|") && strstr(summary, "*")); } else { ok1(!strstr(summary, "|") && !strstr(summary, "*")); } free(summary); } ntdb_close(ntdb); } ok1(tap_log_messages == 0); return exit_status(); }
int main(int argc, char *argv[]) { unsigned int i, j; union ntdb_attribute alloc_attr; struct ntdb_context *ntdb; int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP, NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; NTDB_DATA key = { (unsigned char *)&j, sizeof(j) }; NTDB_DATA data = { (unsigned char *)&j, sizeof(j) }; alloc_attr.base.next = &tap_log_attr; alloc_attr.base.attr = NTDB_ATTRIBUTE_ALLOCATOR; alloc_attr.alloc.alloc = test_alloc; alloc_attr.alloc.expand = test_expand; alloc_attr.alloc.free = test_free; alloc_attr.alloc.priv_data = &owner_weird_count; plan_tests(sizeof(flags) / sizeof(flags[0]) * (1 + 700 * 3 + 4) + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { curr_ntdb = NULL; curr_file = NULL; ntdb = ntdb_open("run-12-store.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &alloc_attr); ok1(ntdb); if (!ntdb) continue; for (j = 0; j < 700; j++) { NTDB_DATA d = { NULL, 0 }; /* Bogus GCC warning */ ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == 0); ok1(ntdb_fetch(ntdb, key, &d) == NTDB_SUCCESS); ok1(ntdb_deq(d, data)); test_free(d.dptr, &owner_weird_count); } ntdb_close(ntdb); ok1(owner_null_count == 2+i*2); ok1(owner_weird_count == 0); ok1(alloc_count == free_count); ok1(expand_count != 0); } ok1(tap_log_messages == 0); return exit_status(); }
static NTSTATUS db_ntdb_store(struct db_record *rec, NTDB_DATA data, int flag) { int ntdb_flag = tdb_store_flag_to_ntdb(flag); struct db_ntdb_ctx *ctx = talloc_get_type_abort(rec->private_data, struct db_ntdb_ctx); /* * This has a bug: We need to replace rec->value for correct * operation, but right now brlock and locking don't use the value * anymore after it was stored. */ if (ntdb_store(ctx->ntdb, rec->key, data, ntdb_flag) == NTDB_SUCCESS) { return NT_STATUS_OK; } return NT_STATUS_UNSUCCESSFUL; }
int main(int argc, char *argv[]) { unsigned int i; int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP, NTDB_CONVERT }; NTDB_DATA key = ntdb_mkdata("hello", 5), data = ntdb_mkdata("world", 5); plan_tests(sizeof(flags) / sizeof(flags[0]) * 2 + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { ntdb = ntdb_open("api-95-read-only-during-parse.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == NTDB_SUCCESS); ok1(ntdb_parse_record(ntdb, key, parse, &data) == NTDB_SUCCESS); ntdb_close(ntdb); } ok1(tap_log_messages == 0); return exit_status(); }
static void insert_ntdb(char *keyname, size_t keylen, char* data, size_t datalen) { NTDB_DATA key, dbuf; enum NTDB_ERROR ecode; if ((keyname == NULL) || (keylen == 0)) { terror(NTDB_SUCCESS, "need key"); return; } key.dptr = (unsigned char *)keyname; key.dsize = keylen; dbuf.dptr = (unsigned char *)data; dbuf.dsize = datalen; ecode = ntdb_store(ntdb, key, dbuf, NTDB_INSERT); if (ecode) { terror(ecode, "insert failed"); } }
static void move_rec(char *keyname, size_t keylen, char* tdbname) { NTDB_DATA key, dbuf; struct ntdb_context *dst_ntdb; enum NTDB_ERROR ecode; if ((keyname == NULL) || (keylen == 0)) { terror(NTDB_SUCCESS, "need key"); return; } if ( !tdbname ) { terror(NTDB_SUCCESS, "need destination ntdb name"); return; } key.dptr = (unsigned char *)keyname; key.dsize = keylen; ecode = ntdb_fetch(ntdb, key, &dbuf); if (ecode) { terror(ecode, "fetch failed"); return; } print_rec(ntdb, key, dbuf, NULL); dst_ntdb = ntdb_open(tdbname, 0, O_RDWR, 0600, NULL); if ( !dst_ntdb ) { terror(NTDB_SUCCESS, "unable to open destination ntdb"); return; } ecode = ntdb_store( dst_ntdb, key, dbuf, NTDB_REPLACE); if (ecode) terror(ecode, "failed to move record"); else printf("record moved\n"); ntdb_close( dst_ntdb ); }
int main(int argc, char *argv[]) { const int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; int i; struct ntdb_context *ntdb; NTDB_DATA key, data; plan_tests(sizeof(flags)/sizeof(flags[0]) * 5); agent = prepare_external_agent(); if (!agent) err(1, "preparing agent"); unlock_callback = after_unlock; for (i = 0; i < sizeof(flags)/sizeof(flags[0]); i++) { diag("Test with %s and %s\n", (flags[i] & NTDB_CONVERT) ? "CONVERT" : "DEFAULT", (flags[i] & NTDB_NOMMAP) ? "no mmap" : "mmap"); unlink(TEST_DBNAME); ntdb = ntdb_open(TEST_DBNAME, flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); ok1(ntdb); opened = true; ok1(ntdb_transaction_start(ntdb) == 0); key = ntdb_mkdata("hi", strlen("hi")); data = ntdb_mkdata("world", strlen("world")); ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0); ok1(ntdb_transaction_commit(ntdb) == 0); ok(!errors, "We had %u open errors", errors); opened = false; ntdb_close(ntdb); } return exit_status(); }
int main(int argc, char *argv[]) { unsigned int i; struct ntdb_context *ntdb; int flags[] = { NTDB_INTERNAL, NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT }; NTDB_DATA key = ntdb_mkdata("key", 3); NTDB_DATA data = ntdb_mkdata("data", 4); failtest_init(argc, argv); failtest_hook = block_repeat_failures; failtest_exit_check = exit_check_log; failtest_suppress = true; plan_tests(sizeof(flags) / sizeof(flags[0]) * 3 + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { ntdb = ntdb_open("run-12-check.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); ok1(ntdb); ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0); /* This is what we really want to test: ntdb_check(). */ failtest_suppress = false; if (!ok1(ntdb_check(ntdb, NULL, NULL) == 0)) goto fail; failtest_suppress = true; ntdb_close(ntdb); } ok1(tap_log_messages == 0); failtest_exit(exit_status()); fail: failtest_suppress = true; ntdb_close(ntdb); failtest_exit(exit_status()); }
static enum NTDB_ERROR fork_in_parse(NTDB_DATA key, NTDB_DATA data, struct ntdb_context *ntdb) { int status; if (fork() == 0) { am_child = true; /* We expect this to fail. */ if (ntdb_store(ntdb, key, data, NTDB_REPLACE) != NTDB_ERR_LOCK) exit(1); if (ntdb_fetch(ntdb, key, &data) != NTDB_ERR_LOCK) exit(1); if (tap_log_messages != 2) exit(2); return NTDB_SUCCESS; } wait(&status); ok1(WIFEXITED(status) && WEXITSTATUS(status) == 0); return NTDB_SUCCESS; }
int main(int argc, char *argv[]) { unsigned int i, j; int num; struct trav_data td; NTDB_DATA k; struct ntdb_context *ntdb; union ntdb_attribute seed_attr; enum NTDB_ERROR ecode; int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP, NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; seed_attr.base.attr = NTDB_ATTRIBUTE_SEED; seed_attr.base.next = &tap_log_attr; seed_attr.seed.seed = 6334326220117065685ULL; plan_tests(sizeof(flags) / sizeof(flags[0]) * (NUM_RECORDS*6 + (NUM_RECORDS-1)*3 + 22) + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { ntdb = ntdb_open("api-firstkey-nextkey.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &seed_attr); ok1(ntdb); if (!ntdb) continue; ok1(ntdb_firstkey(ntdb, &k) == NTDB_ERR_NOEXIST); /* One entry... */ k.dptr = (unsigned char *)# k.dsize = sizeof(num); num = 0; ok1(ntdb_store(ntdb, k, k, NTDB_INSERT) == 0); ok1(ntdb_firstkey(ntdb, &k) == NTDB_SUCCESS); ok1(k.dsize == sizeof(num)); ok1(memcmp(k.dptr, &num, sizeof(num)) == 0); ok1(ntdb_nextkey(ntdb, &k) == NTDB_ERR_NOEXIST); /* Two entries. */ k.dptr = (unsigned char *)# k.dsize = sizeof(num); num = 1; ok1(ntdb_store(ntdb, k, k, NTDB_INSERT) == 0); ok1(ntdb_firstkey(ntdb, &k) == NTDB_SUCCESS); ok1(k.dsize == sizeof(num)); memcpy(&num, k.dptr, sizeof(num)); ok1(num == 0 || num == 1); ok1(ntdb_nextkey(ntdb, &k) == NTDB_SUCCESS); ok1(k.dsize == sizeof(j)); memcpy(&j, k.dptr, sizeof(j)); ok1(j == 0 || j == 1); ok1(j != num); ok1(ntdb_nextkey(ntdb, &k) == NTDB_ERR_NOEXIST); /* Clean up. */ k.dptr = (unsigned char *)# k.dsize = sizeof(num); num = 0; ok1(ntdb_delete(ntdb, k) == 0); num = 1; ok1(ntdb_delete(ntdb, k) == 0); /* Now lots of records. */ ok1(store_records(ntdb)); td.calls = 0; num = ntdb_traverse(ntdb, trav, &td); ok1(num == NUM_RECORDS); ok1(td.calls == NUM_RECORDS); /* Simple loop should match ntdb_traverse */ for (j = 0, ecode = ntdb_firstkey(ntdb, &k); j < td.calls; j++) { int val; ok1(ecode == NTDB_SUCCESS); ok1(k.dsize == sizeof(val)); memcpy(&val, k.dptr, k.dsize); ok1(td.records[j] == val); ecode = ntdb_nextkey(ntdb, &k); } /* But arbitrary orderings should work too. */ for (j = td.calls-1; j > 0; j--) { k.dptr = (unsigned char *)&td.records[j-1]; k.dsize = sizeof(td.records[j-1]); k = dup_key(k); ok1(ntdb_nextkey(ntdb, &k) == NTDB_SUCCESS); ok1(k.dsize == sizeof(td.records[j])); ok1(memcmp(k.dptr, &td.records[j], k.dsize) == 0); free(k.dptr); } /* Even delete should work. */ for (j = 0, ecode = ntdb_firstkey(ntdb, &k); ecode != NTDB_ERR_NOEXIST; j++) { ok1(ecode == NTDB_SUCCESS); ok1(k.dsize == 4); ok1(ntdb_delete(ntdb, k) == 0); ecode = ntdb_nextkey(ntdb, &k); } diag("delete using first/nextkey gave %u of %u records", j, NUM_RECORDS); ok1(j == NUM_RECORDS); ntdb_close(ntdb); } ok1(tap_log_messages == 0); return exit_status(); }
int main(int argc, char *argv[]) { unsigned int i; struct ntdb_context *ntdb; int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; NTDB_DATA key = ntdb_mkdata("key", 3); NTDB_DATA data = ntdb_mkdata("data", 4), d; union ntdb_attribute seed_attr; unsigned int msgs = 0; failtest_init(argc, argv); failtest_hook = block_repeat_failures; failtest_exit_check = exit_check_log; seed_attr.base.attr = NTDB_ATTRIBUTE_SEED; seed_attr.base.next = &tap_log_attr; seed_attr.seed.seed = 0; failtest_suppress = true; plan_tests(sizeof(flags) / sizeof(flags[0]) * 11); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { ntdb = ntdb_open("run-05-readonly-open.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &seed_attr); ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0); ntdb_close(ntdb); failtest_suppress = false; ntdb = ntdb_open("run-05-readonly-open.ntdb", flags[i]|MAYBE_NOSYNC, O_RDONLY, 0600, &tap_log_attr); if (!ok1(ntdb)) break; ok1(tap_log_messages == msgs); /* Fetch should succeed, stores should fail. */ if (!ok1(ntdb_fetch(ntdb, key, &d) == 0)) goto fail; ok1(ntdb_deq(d, data)); free(d.dptr); if (!ok1(ntdb_store(ntdb, key, data, NTDB_MODIFY) == NTDB_ERR_RDONLY)) goto fail; ok1(tap_log_messages == ++msgs); if (!ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == NTDB_ERR_RDONLY)) goto fail; ok1(tap_log_messages == ++msgs); failtest_suppress = true; ok1(ntdb_check(ntdb, NULL, NULL) == 0); ntdb_close(ntdb); ok1(tap_log_messages == msgs); /* SIGH: failtest bug, it doesn't save the ntdb file because * we have it read-only. If we go around again, it gets * changed underneath us and things get screwy. */ if (failtest_has_failed()) break; } failtest_exit(exit_status()); fail: failtest_suppress = true; ntdb_close(ntdb); failtest_exit(exit_status()); }
int main(int argc, char *argv[]) { unsigned int i, seq; struct ntdb_context *ntdb; NTDB_DATA d = { NULL, 0 }; /* Bogus GCC warning */ NTDB_DATA key = ntdb_mkdata("key", 3); NTDB_DATA data = ntdb_mkdata("data", 4); int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP, NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; plan_tests(sizeof(flags) / sizeof(flags[0]) * 15 + 4 * 13); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { ntdb = ntdb_open("api-81-seqnum.ntdb", flags[i]|NTDB_SEQNUM|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); if (!ok1(ntdb)) continue; seq = 0; ok1(ntdb_get_seqnum(ntdb) == seq); ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0); ok1(ntdb_get_seqnum(ntdb) == ++seq); /* Fetch doesn't change seqnum */ if (ok1(ntdb_fetch(ntdb, key, &d) == NTDB_SUCCESS)) free(d.dptr); ok1(ntdb_get_seqnum(ntdb) == seq); ok1(ntdb_append(ntdb, key, data) == NTDB_SUCCESS); ok1(ntdb_get_seqnum(ntdb) == ++seq); ok1(ntdb_delete(ntdb, key) == NTDB_SUCCESS); ok1(ntdb_get_seqnum(ntdb) == ++seq); /* Empty append works */ ok1(ntdb_append(ntdb, key, data) == NTDB_SUCCESS); ok1(ntdb_get_seqnum(ntdb) == ++seq); ok1(ntdb_wipe_all(ntdb) == NTDB_SUCCESS); ok1(ntdb_get_seqnum(ntdb) == ++seq); if (!(flags[i] & NTDB_INTERNAL)) { ok1(ntdb_transaction_start(ntdb) == NTDB_SUCCESS); ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0); ok1(ntdb_get_seqnum(ntdb) == ++seq); ok1(ntdb_append(ntdb, key, data) == NTDB_SUCCESS); ok1(ntdb_get_seqnum(ntdb) == ++seq); ok1(ntdb_delete(ntdb, key) == NTDB_SUCCESS); ok1(ntdb_get_seqnum(ntdb) == ++seq); ok1(ntdb_transaction_commit(ntdb) == NTDB_SUCCESS); ok1(ntdb_get_seqnum(ntdb) == seq); ok1(ntdb_transaction_start(ntdb) == NTDB_SUCCESS); ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0); ok1(ntdb_get_seqnum(ntdb) == seq + 1); ntdb_transaction_cancel(ntdb); ok1(ntdb_get_seqnum(ntdb) == seq); } ntdb_close(ntdb); ok1(tap_log_messages == 0); } return exit_status(); }
int main(int argc, char *argv[]) { unsigned int i; struct ntdb_context *ntdb; int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; NTDB_DATA key = ntdb_mkdata("key", 3); NTDB_DATA data = ntdb_mkdata("data", 4); plan_tests(sizeof(flags) / sizeof(flags[0]) * 14); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { int status; tap_log_messages = 0; ntdb = ntdb_open("run-fork-test.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); if (!ok1(ntdb)) continue; /* Put a record in here. */ ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == NTDB_SUCCESS); ok1(ntdb_chainlock(ntdb, key) == NTDB_SUCCESS); if (fork() == 0) { /* We expect this to fail. */ if (ntdb_store(ntdb, key, data, NTDB_REPLACE) != NTDB_ERR_LOCK) return 1; if (ntdb_fetch(ntdb, key, &data) != NTDB_ERR_LOCK) return 1; if (tap_log_messages != 2) return 2; /* Child can do this without any complaints. */ ntdb_chainunlock(ntdb, key); if (tap_log_messages != 2) return 3; ntdb_close(ntdb); if (tap_log_messages != 2) return 4; return 0; } wait(&status); ok1(WIFEXITED(status) && WEXITSTATUS(status) == 0); ntdb_chainunlock(ntdb, key); ok1(ntdb_lockall(ntdb) == NTDB_SUCCESS); if (fork() == 0) { /* We expect this to fail. */ if (ntdb_store(ntdb, key, data, NTDB_REPLACE) != NTDB_ERR_LOCK) return 1; if (ntdb_fetch(ntdb, key, &data) != NTDB_ERR_LOCK) return 1; if (tap_log_messages != 2) return 2; /* Child can do this without any complaints. */ ntdb_unlockall(ntdb); if (tap_log_messages != 2) return 3; ntdb_close(ntdb); if (tap_log_messages != 2) return 4; return 0; } wait(&status); ok1(WIFEXITED(status) && WEXITSTATUS(status) == 0); ntdb_unlockall(ntdb); ok1(ntdb_lockall_read(ntdb) == NTDB_SUCCESS); if (fork() == 0) { /* We expect this to fail. */ /* This would always fail anyway... */ if (ntdb_store(ntdb, key, data, NTDB_REPLACE) != NTDB_ERR_LOCK) return 1; if (ntdb_fetch(ntdb, key, &data) != NTDB_ERR_LOCK) return 1; if (tap_log_messages != 2) return 2; /* Child can do this without any complaints. */ ntdb_unlockall_read(ntdb); if (tap_log_messages != 2) return 3; ntdb_close(ntdb); if (tap_log_messages != 2) return 4; return 0; } wait(&status); ok1(WIFEXITED(status) && WEXITSTATUS(status) == 0); ntdb_unlockall_read(ntdb); ok1(ntdb_transaction_start(ntdb) == NTDB_SUCCESS); /* If transactions is empty, noop "commit" succeeds. */ ok1(ntdb_delete(ntdb, key) == NTDB_SUCCESS); if (fork() == 0) { int last_log_messages; /* We expect this to fail. */ if (ntdb_store(ntdb, key, data, NTDB_REPLACE) != NTDB_ERR_LOCK) return 1; if (ntdb_fetch(ntdb, key, &data) != NTDB_ERR_LOCK) return 1; if (tap_log_messages != 2) return 2; if (ntdb_transaction_prepare_commit(ntdb) != NTDB_ERR_LOCK) return 3; if (tap_log_messages == 2) return 4; last_log_messages = tap_log_messages; /* Child can do this without any complaints. */ ntdb_transaction_cancel(ntdb); if (tap_log_messages != last_log_messages) return 4; ntdb_close(ntdb); if (tap_log_messages != last_log_messages) return 4; return 0; } wait(&status); ok1(WIFEXITED(status) && WEXITSTATUS(status) == 0); ntdb_transaction_cancel(ntdb); ok1(ntdb_parse_record(ntdb, key, fork_in_parse, ntdb) == NTDB_SUCCESS); ntdb_close(ntdb); if (am_child) { /* Child can return from parse without complaints. */ if (tap_log_messages != 2) exit(3); exit(0); } ok1(tap_log_messages == 0); } return exit_status(); }
int main(int argc, char *argv[]) { unsigned int i; struct ntdb_context *ntdb; NTDB_DATA key = ntdb_mkdata("key", 3); NTDB_DATA data = ntdb_mkdata("data", 4); int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; plan_tests(sizeof(flags) / sizeof(flags[0]) * 48); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { /* RW -> R0 */ ntdb = ntdb_open("run-92-get-set-readonly.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); ok1(ntdb); ok1(!(ntdb_get_flags(ntdb) & NTDB_RDONLY)); ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == NTDB_SUCCESS); ntdb_add_flag(ntdb, NTDB_RDONLY); ok1(ntdb_get_flags(ntdb) & NTDB_RDONLY); /* Can't store, append, delete. */ ok1(ntdb_store(ntdb, key, data, NTDB_MODIFY) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 1); ok1(ntdb_append(ntdb, key, data) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 2); ok1(ntdb_delete(ntdb, key) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 3); /* Can't start a transaction, or any write lock. */ ok1(ntdb_transaction_start(ntdb) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 4); ok1(ntdb_chainlock(ntdb, key) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 5); ok1(ntdb_lockall(ntdb) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 6); ok1(ntdb_wipe_all(ntdb) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 7); /* Back to RW. */ ntdb_remove_flag(ntdb, NTDB_RDONLY); ok1(!(ntdb_get_flags(ntdb) & NTDB_RDONLY)); ok1(ntdb_store(ntdb, key, data, NTDB_MODIFY) == NTDB_SUCCESS); ok1(ntdb_append(ntdb, key, data) == NTDB_SUCCESS); ok1(ntdb_delete(ntdb, key) == NTDB_SUCCESS); ok1(ntdb_transaction_start(ntdb) == NTDB_SUCCESS); ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == NTDB_SUCCESS); ok1(ntdb_transaction_commit(ntdb) == NTDB_SUCCESS); ok1(ntdb_chainlock(ntdb, key) == NTDB_SUCCESS); ntdb_chainunlock(ntdb, key); ok1(ntdb_lockall(ntdb) == NTDB_SUCCESS); ntdb_unlockall(ntdb); ok1(ntdb_wipe_all(ntdb) == NTDB_SUCCESS); ok1(tap_log_messages == 7); ntdb_close(ntdb); /* R0 -> RW */ ntdb = ntdb_open("run-92-get-set-readonly.ntdb", flags[i]|MAYBE_NOSYNC, O_RDONLY, 0600, &tap_log_attr); ok1(ntdb); ok1(ntdb_get_flags(ntdb) & NTDB_RDONLY); /* Can't store, append, delete. */ ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 8); ok1(ntdb_append(ntdb, key, data) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 9); ok1(ntdb_delete(ntdb, key) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 10); /* Can't start a transaction, or any write lock. */ ok1(ntdb_transaction_start(ntdb) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 11); ok1(ntdb_chainlock(ntdb, key) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 12); ok1(ntdb_lockall(ntdb) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 13); ok1(ntdb_wipe_all(ntdb) == NTDB_ERR_RDONLY); ok1(tap_log_messages == 14); /* Can't remove NTDB_RDONLY since we opened with O_RDONLY */ ntdb_remove_flag(ntdb, NTDB_RDONLY); ok1(tap_log_messages == 15); ok1(ntdb_get_flags(ntdb) & NTDB_RDONLY); ntdb_close(ntdb); ok1(tap_log_messages == 15); tap_log_messages = 0; } return exit_status(); }
int main(int argc, char *argv[]) { unsigned int i, j, num = 1000, stage = 0, stopat = -1; int flags = NTDB_DEFAULT; bool transaction = false, summary = false; NTDB_DATA key, data; struct ntdb_context *ntdb; struct timeval start, stop; union ntdb_attribute seed, log; bool do_stats = false; enum NTDB_ERROR ecode; /* Try to keep benchmarks even. */ seed.base.attr = NTDB_ATTRIBUTE_SEED; seed.base.next = NULL; seed.seed.seed = 0; log.base.attr = NTDB_ATTRIBUTE_LOG; log.base.next = &seed; log.log.fn = ntdb_log; if (argv[1] && strcmp(argv[1], "--internal") == 0) { flags = NTDB_INTERNAL; argc--; argv++; } if (argv[1] && strcmp(argv[1], "--transaction") == 0) { transaction = true; argc--; argv++; } if (argv[1] && strcmp(argv[1], "--no-sync") == 0) { flags |= NTDB_NOSYNC; argc--; argv++; } if (argv[1] && strcmp(argv[1], "--summary") == 0) { summary = true; argc--; argv++; } if (argv[1] && strcmp(argv[1], "--stats") == 0) { do_stats = true; argc--; argv++; } ntdb = ntdb_open("/tmp/speed.ntdb", flags, O_RDWR|O_CREAT|O_TRUNC, 0600, &log); if (!ntdb) err(1, "Opening /tmp/speed.ntdb"); key.dptr = (void *)&i; key.dsize = sizeof(i); data = key; if (argv[1]) { num = atoi(argv[1]); argv++; argc--; } if (argv[1]) { stopat = atoi(argv[1]); argv++; argc--; } /* Add 1000 records. */ printf("Adding %u records: ", num); fflush(stdout); if (transaction && (ecode = ntdb_transaction_start(ntdb))) errx(1, "starting transaction: %s", ntdb_errorstr(ecode)); gettimeofday(&start, NULL); for (i = 0; i < num; i++) if ((ecode = ntdb_store(ntdb, key, data, NTDB_INSERT)) != 0) errx(1, "Inserting key %u in ntdb: %s", i, ntdb_errorstr(ecode)); gettimeofday(&stop, NULL); if (transaction && (ecode = ntdb_transaction_commit(ntdb))) errx(1, "committing transaction: %s", ntdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); if (ntdb_check(ntdb, NULL, NULL)) errx(1, "ntdb_check failed!"); if (summary) { char *sumstr = NULL; ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr); printf("%s\n", sumstr); free(sumstr); } if (do_stats) dump_and_clear_stats(&ntdb, flags, &log); if (++stage == stopat) exit(0); /* Finding 1000 records. */ printf("Finding %u records: ", num); fflush(stdout); if (transaction && (ecode = ntdb_transaction_start(ntdb))) errx(1, "starting transaction: %s", ntdb_errorstr(ecode)); gettimeofday(&start, NULL); for (i = 0; i < num; i++) { NTDB_DATA dbuf; if ((ecode = ntdb_fetch(ntdb, key, &dbuf)) != NTDB_SUCCESS || *(int *)dbuf.dptr != i) { errx(1, "Fetching key %u in ntdb gave %u", i, ecode ? ecode : *(int *)dbuf.dptr); } } gettimeofday(&stop, NULL); if (transaction && (ecode = ntdb_transaction_commit(ntdb))) errx(1, "committing transaction: %s", ntdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); if (ntdb_check(ntdb, NULL, NULL)) errx(1, "ntdb_check failed!"); if (summary) { char *sumstr = NULL; ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr); printf("%s\n", sumstr); free(sumstr); } if (do_stats) dump_and_clear_stats(&ntdb, flags, &log); if (++stage == stopat) exit(0); /* Missing 1000 records. */ printf("Missing %u records: ", num); fflush(stdout); if (transaction && (ecode = ntdb_transaction_start(ntdb))) errx(1, "starting transaction: %s", ntdb_errorstr(ecode)); gettimeofday(&start, NULL); for (i = num; i < num*2; i++) { NTDB_DATA dbuf; ecode = ntdb_fetch(ntdb, key, &dbuf); if (ecode != NTDB_ERR_NOEXIST) errx(1, "Fetching key %u in ntdb gave %s", i, ntdb_errorstr(ecode)); } gettimeofday(&stop, NULL); if (transaction && (ecode = ntdb_transaction_commit(ntdb))) errx(1, "committing transaction: %s", ntdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); if (ntdb_check(ntdb, NULL, NULL)) errx(1, "ntdb_check failed!"); if (summary) { char *sumstr = NULL; ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr); printf("%s\n", sumstr); free(sumstr); } if (do_stats) dump_and_clear_stats(&ntdb, flags, &log); if (++stage == stopat) exit(0); /* Traverse 1000 records. */ printf("Traversing %u records: ", num); fflush(stdout); if (transaction && (ecode = ntdb_transaction_start(ntdb))) errx(1, "starting transaction: %s", ntdb_errorstr(ecode)); i = 0; gettimeofday(&start, NULL); if (ntdb_traverse(ntdb, count_record, &i) != num) errx(1, "Traverse returned wrong number of records"); if (i != (num - 1) * (num / 2)) errx(1, "Traverse tallied to %u", i); gettimeofday(&stop, NULL); if (transaction && (ecode = ntdb_transaction_commit(ntdb))) errx(1, "committing transaction: %s", ntdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); if (ntdb_check(ntdb, NULL, NULL)) errx(1, "ntdb_check failed!"); if (summary) { char *sumstr = NULL; ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr); printf("%s\n", sumstr); free(sumstr); } if (do_stats) dump_and_clear_stats(&ntdb, flags, &log); if (++stage == stopat) exit(0); /* Delete 1000 records (not in order). */ printf("Deleting %u records: ", num); fflush(stdout); if (transaction && (ecode = ntdb_transaction_start(ntdb))) errx(1, "starting transaction: %s", ntdb_errorstr(ecode)); gettimeofday(&start, NULL); for (j = 0; j < num; j++) { i = (j + 100003) % num; if ((ecode = ntdb_delete(ntdb, key)) != NTDB_SUCCESS) errx(1, "Deleting key %u in ntdb: %s", i, ntdb_errorstr(ecode)); } gettimeofday(&stop, NULL); if (transaction && (ecode = ntdb_transaction_commit(ntdb))) errx(1, "committing transaction: %s", ntdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); if (ntdb_check(ntdb, NULL, NULL)) errx(1, "ntdb_check failed!"); if (summary) { char *sumstr = NULL; ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr); printf("%s\n", sumstr); free(sumstr); } if (do_stats) dump_and_clear_stats(&ntdb, flags, &log); if (++stage == stopat) exit(0); /* Re-add 1000 records (not in order). */ printf("Re-adding %u records: ", num); fflush(stdout); if (transaction && (ecode = ntdb_transaction_start(ntdb))) errx(1, "starting transaction: %s", ntdb_errorstr(ecode)); gettimeofday(&start, NULL); for (j = 0; j < num; j++) { i = (j + 100003) % num; if ((ecode = ntdb_store(ntdb, key, data, NTDB_INSERT)) != 0) errx(1, "Inserting key %u in ntdb: %s", i, ntdb_errorstr(ecode)); } gettimeofday(&stop, NULL); if (transaction && (ecode = ntdb_transaction_commit(ntdb))) errx(1, "committing transaction: %s", ntdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); if (ntdb_check(ntdb, NULL, NULL)) errx(1, "ntdb_check failed!"); if (summary) { char *sumstr = NULL; ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr); printf("%s\n", sumstr); free(sumstr); } if (do_stats) dump_and_clear_stats(&ntdb, flags, &log); if (++stage == stopat) exit(0); /* Append 1000 records. */ if (transaction && (ecode = ntdb_transaction_start(ntdb))) errx(1, "starting transaction: %s", ntdb_errorstr(ecode)); printf("Appending %u records: ", num); fflush(stdout); gettimeofday(&start, NULL); for (i = 0; i < num; i++) if ((ecode = ntdb_append(ntdb, key, data)) != NTDB_SUCCESS) errx(1, "Appending key %u in ntdb: %s", i, ntdb_errorstr(ecode)); gettimeofday(&stop, NULL); if (transaction && (ecode = ntdb_transaction_commit(ntdb))) errx(1, "committing transaction: %s", ntdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); if (ntdb_check(ntdb, NULL, NULL)) errx(1, "ntdb_check failed!"); if (summary) { char *sumstr = NULL; ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr); printf("%s\n", sumstr); free(sumstr); } if (++stage == stopat) exit(0); /* Churn 1000 records: not in order! */ if (transaction && (ecode = ntdb_transaction_start(ntdb))) errx(1, "starting transaction: %s", ntdb_errorstr(ecode)); printf("Churning %u records: ", num); fflush(stdout); gettimeofday(&start, NULL); for (j = 0; j < num; j++) { i = (j + 1000019) % num; if ((ecode = ntdb_delete(ntdb, key)) != NTDB_SUCCESS) errx(1, "Deleting key %u in ntdb: %s", i, ntdb_errorstr(ecode)); i += num; if ((ecode = ntdb_store(ntdb, key, data, NTDB_INSERT)) != 0) errx(1, "Inserting key %u in ntdb: %s", i, ntdb_errorstr(ecode)); } gettimeofday(&stop, NULL); if (transaction && (ecode = ntdb_transaction_commit(ntdb))) errx(1, "committing transaction: %s", ntdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); if (ntdb_check(ntdb, NULL, NULL)) errx(1, "ntdb_check failed!"); if (summary) { char *sumstr = NULL; ntdb_summary(ntdb, NTDB_SUMMARY_HISTOGRAMS, &sumstr); printf("%s\n", sumstr); free(sumstr); } if (do_stats) dump_and_clear_stats(&ntdb, flags, &log); if (++stage == stopat) exit(0); return 0; }
int main(int argc, char *argv[]) { unsigned int i; struct ntdb_context *ntdb; unsigned char *buffer; int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP, NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT }; NTDB_DATA key = ntdb_mkdata("key", 3); NTDB_DATA data; buffer = malloc(1000); for (i = 0; i < 1000; i++) buffer[i] = i; plan_tests(sizeof(flags) / sizeof(flags[0]) * 20 + 1); for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { ntdb = ntdb_open("run-55-transaction.ntdb", flags[i]|MAYBE_NOSYNC, O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr); ok1(ntdb); if (!ntdb) continue; ok1(ntdb_transaction_start(ntdb) == 0); data.dptr = buffer; data.dsize = 1000; ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0); ok1(ntdb_fetch(ntdb, key, &data) == NTDB_SUCCESS); ok1(data.dsize == 1000); ok1(memcmp(data.dptr, buffer, data.dsize) == 0); free(data.dptr); /* Cancelling a transaction means no store */ ntdb_transaction_cancel(ntdb); ok1(ntdb->file->allrecord_lock.count == 0 && ntdb->file->num_lockrecs == 0); ok1(ntdb_check(ntdb, NULL, NULL) == 0); ok1(ntdb_fetch(ntdb, key, &data) == NTDB_ERR_NOEXIST); /* Commit the transaction. */ ok1(ntdb_transaction_start(ntdb) == 0); data.dptr = buffer; data.dsize = 1000; ok1(ntdb_store(ntdb, key, data, NTDB_INSERT) == 0); ok1(ntdb_fetch(ntdb, key, &data) == NTDB_SUCCESS); ok1(data.dsize == 1000); ok1(memcmp(data.dptr, buffer, data.dsize) == 0); free(data.dptr); ok1(ntdb_transaction_commit(ntdb) == 0); ok1(ntdb->file->allrecord_lock.count == 0 && ntdb->file->num_lockrecs == 0); ok1(ntdb_check(ntdb, NULL, NULL) == 0); ok1(ntdb_fetch(ntdb, key, &data) == NTDB_SUCCESS); ok1(data.dsize == 1000); ok1(memcmp(data.dptr, buffer, data.dsize) == 0); free(data.dptr); ntdb_close(ntdb); } ok1(tap_log_messages == 0); free(buffer); return exit_status(); }
static void speed_ntdb(const char *tlimit) { unsigned timelimit = tlimit?atoi(tlimit):0; double t; int ops; if (timelimit == 0) timelimit = 5; ops = 0; printf("Testing store speed for %u seconds\n", timelimit); _start_timer(); do { long int r = random(); NTDB_DATA key, dbuf; key = ntdb_mkdata("store test", strlen("store test")); dbuf.dptr = (unsigned char *)&r; dbuf.dsize = sizeof(r); ntdb_store(ntdb, key, dbuf, NTDB_REPLACE); t = _end_timer(); ops++; } while (t < timelimit); printf("%10.3f ops/sec\n", ops/t); ops = 0; printf("Testing fetch speed for %u seconds\n", timelimit); _start_timer(); do { long int r = random(); NTDB_DATA key, dbuf; key = ntdb_mkdata("store test", strlen("store test")); dbuf.dptr = (unsigned char *)&r; dbuf.dsize = sizeof(r); ntdb_fetch(ntdb, key, &dbuf); t = _end_timer(); ops++; } while (t < timelimit); printf("%10.3f ops/sec\n", ops/t); ops = 0; printf("Testing transaction speed for %u seconds\n", timelimit); _start_timer(); do { long int r = random(); NTDB_DATA key, dbuf; key = ntdb_mkdata("transaction test", strlen("transaction test")); dbuf.dptr = (unsigned char *)&r; dbuf.dsize = sizeof(r); ntdb_transaction_start(ntdb); ntdb_store(ntdb, key, dbuf, NTDB_REPLACE); ntdb_transaction_commit(ntdb); t = _end_timer(); ops++; } while (t < timelimit); printf("%10.3f ops/sec\n", ops/t); ops = 0; printf("Testing traverse speed for %u seconds\n", timelimit); _start_timer(); do { ntdb_traverse(ntdb, traverse_fn, NULL); t = _end_timer(); ops++; } while (t < timelimit); printf("%10.3f ops/sec\n", ops/t); }
static enum agent_return do_operation(enum operation op, const char *name) { NTDB_DATA k, d; enum agent_return ret; NTDB_DATA data; enum NTDB_ERROR ecode; union ntdb_attribute cif; const char *eq; if (op != OPEN && op != OPEN_WITH_HOOK && !ntdb) { diag("external: No ntdb open!"); return OTHER_FAILURE; } diag("external: %s", operation_name(op)); eq = strchr(name, '='); if (eq) { k = ntdb_mkdata(name, eq - name); d = ntdb_mkdata(eq + 1, strlen(eq+1)); } else { k = ntdb_mkdata(name, strlen(name)); d.dsize = 0; d.dptr = NULL; } locking_would_block = 0; switch (op) { case OPEN: if (ntdb) { diag("Already have ntdb %s open", ntdb_name(ntdb)); return OTHER_FAILURE; } ntdb = ntdb_open(name, MAYBE_NOSYNC, O_RDWR, 0, &tap_log_attr); if (!ntdb) { if (!locking_would_block) diag("Opening ntdb gave %s", strerror(errno)); forget_locking(); ret = OTHER_FAILURE; } else ret = SUCCESS; break; case OPEN_WITH_HOOK: if (ntdb) { diag("Already have ntdb %s open", ntdb_name(ntdb)); return OTHER_FAILURE; } cif.openhook.base.attr = NTDB_ATTRIBUTE_OPENHOOK; cif.openhook.base.next = &tap_log_attr; cif.openhook.fn = clear_if_first; ntdb = ntdb_open(name, MAYBE_NOSYNC, O_RDWR, 0, &cif); if (!ntdb) { if (!locking_would_block) diag("Opening ntdb gave %s", strerror(errno)); forget_locking(); ret = OTHER_FAILURE; } else ret = SUCCESS; break; case FETCH: ecode = ntdb_fetch(ntdb, k, &data); if (ecode == NTDB_ERR_NOEXIST) { ret = FAILED; } else if (ecode < 0) { ret = OTHER_FAILURE; } else if (!ntdb_deq(data, d)) { ret = OTHER_FAILURE; external_agent_free(data.dptr); } else { ret = SUCCESS; external_agent_free(data.dptr); } break; case STORE: ret = ntdb_store(ntdb, k, d, 0) == 0 ? SUCCESS : OTHER_FAILURE; break; case TRANSACTION_START: ret = ntdb_transaction_start(ntdb) == 0 ? SUCCESS : OTHER_FAILURE; break; case TRANSACTION_COMMIT: ret = ntdb_transaction_commit(ntdb)==0 ? SUCCESS : OTHER_FAILURE; break; case NEEDS_RECOVERY: ret = external_agent_needs_rec(ntdb); break; case CHECK: ret = ntdb_check(ntdb, NULL, NULL) == 0 ? SUCCESS : OTHER_FAILURE; break; case CLOSE: ret = ntdb_close(ntdb) == 0 ? SUCCESS : OTHER_FAILURE; ntdb = NULL; break; case SEND_SIGNAL: /* We do this async */ ret = SUCCESS; break; default: ret = OTHER_FAILURE; } if (locking_would_block) ret = WOULD_HAVE_BLOCKED; return ret; }