X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Ftdb2%2Ftools%2Fspeed.c;h=ccb5ae349d894f43d57ce0349b280d6539713e7d;hb=926996e88c32445c874ff9c4f47f159db6b45995;hp=216a051fe9f060dae65d96de48fa53f9f0bb8ee3;hpb=5f388eef7e9293db3438811dda7e0962c6a0c71b;p=ccan diff --git a/ccan/tdb2/tools/speed.c b/ccan/tdb2/tools/speed.c index 216a051f..ccb5ae34 100644 --- a/ccan/tdb2/tools/speed.c +++ b/ccan/tdb2/tools/speed.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include "tdb2.h" /* Nanoseconds per operation */ static size_t normalize(const struct timeval *start, @@ -43,66 +43,109 @@ static int count_record(struct tdb_context *tdb, return 0; } -static void dump_and_clear_stats(struct tdb_attribute_stats *stats) +static void dump_and_clear_stats(struct tdb_context **tdb, + int flags, + union tdb_attribute *attr) { + union tdb_attribute stats; + enum TDB_ERROR ecode; + + stats.base.attr = TDB_ATTRIBUTE_STATS; + stats.stats.size = sizeof(stats.stats); + ecode = tdb_get_attribute(*tdb, &stats); + if (ecode != TDB_SUCCESS) + errx(1, "Getting stats: %s", tdb_errorstr(ecode)); + printf("allocs = %llu\n", - (unsigned long long)stats->allocs); + (unsigned long long)stats.stats.allocs); printf(" alloc_subhash = %llu\n", - (unsigned long long)stats->alloc_subhash); + (unsigned long long)stats.stats.alloc_subhash); printf(" alloc_chain = %llu\n", - (unsigned long long)stats->alloc_chain); + (unsigned long long)stats.stats.alloc_chain); printf(" alloc_bucket_exact = %llu\n", - (unsigned long long)stats->alloc_bucket_exact); + (unsigned long long)stats.stats.alloc_bucket_exact); printf(" alloc_bucket_max = %llu\n", - (unsigned long long)stats->alloc_bucket_max); + (unsigned long long)stats.stats.alloc_bucket_max); printf(" alloc_leftover = %llu\n", - (unsigned long long)stats->alloc_leftover); + (unsigned long long)stats.stats.alloc_leftover); printf(" alloc_coalesce_tried = %llu\n", - (unsigned long long)stats->alloc_coalesce_tried); + (unsigned long long)stats.stats.alloc_coalesce_tried); + printf(" alloc_coalesce_iterate_clash = %llu\n", + (unsigned long long)stats.stats.alloc_coalesce_iterate_clash); printf(" alloc_coalesce_lockfail = %llu\n", - (unsigned long long)stats->alloc_coalesce_lockfail); + (unsigned long long)stats.stats.alloc_coalesce_lockfail); printf(" alloc_coalesce_race = %llu\n", - (unsigned long long)stats->alloc_coalesce_race); + (unsigned long long)stats.stats.alloc_coalesce_race); printf(" alloc_coalesce_succeeded = %llu\n", - (unsigned long long)stats->alloc_coalesce_succeeded); - printf(" alloc_coalesce_num_merged = %llu\n", - (unsigned long long)stats->alloc_coalesce_num_merged); + (unsigned long long)stats.stats.alloc_coalesce_succeeded); + printf(" alloc_coalesce_num_merged = %llu\n", + (unsigned long long)stats.stats.alloc_coalesce_num_merged); printf("compares = %llu\n", - (unsigned long long)stats->compares); + (unsigned long long)stats.stats.compares); printf(" compare_wrong_bucket = %llu\n", - (unsigned long long)stats->compare_wrong_bucket); + (unsigned long long)stats.stats.compare_wrong_bucket); printf(" compare_wrong_offsetbits = %llu\n", - (unsigned long long)stats->compare_wrong_offsetbits); + (unsigned long long)stats.stats.compare_wrong_offsetbits); printf(" compare_wrong_keylen = %llu\n", - (unsigned long long)stats->compare_wrong_keylen); + (unsigned long long)stats.stats.compare_wrong_keylen); printf(" compare_wrong_rechash = %llu\n", - (unsigned long long)stats->compare_wrong_rechash); + (unsigned long long)stats.stats.compare_wrong_rechash); printf(" compare_wrong_keycmp = %llu\n", - (unsigned long long)stats->compare_wrong_keycmp); + (unsigned long long)stats.stats.compare_wrong_keycmp); + printf("transactions = %llu\n", + (unsigned long long)stats.stats.transactions); + printf(" transaction_cancel = %llu\n", + (unsigned long long)stats.stats.transaction_cancel); + printf(" transaction_nest = %llu\n", + (unsigned long long)stats.stats.transaction_nest); + printf(" transaction_expand_file = %llu\n", + (unsigned long long)stats.stats.transaction_expand_file); + printf(" transaction_read_direct = %llu\n", + (unsigned long long)stats.stats.transaction_read_direct); + printf(" transaction_read_direct_fail = %llu\n", + (unsigned long long)stats.stats.transaction_read_direct_fail); + printf(" transaction_write_direct = %llu\n", + (unsigned long long)stats.stats.transaction_write_direct); + printf(" transaction_write_direct_fail = %llu\n", + (unsigned long long)stats.stats.transaction_write_direct_fail); printf("expands = %llu\n", - (unsigned long long)stats->expands); + (unsigned long long)stats.stats.expands); printf("frees = %llu\n", - (unsigned long long)stats->frees); + (unsigned long long)stats.stats.frees); printf("locks = %llu\n", - (unsigned long long)stats->locks); - printf(" lock_lowlevel = %llu\n", - (unsigned long long)stats->lock_lowlevel); - printf(" lock_nonblock = %llu\n", - (unsigned long long)stats->lock_nonblock); + (unsigned long long)stats.stats.locks); + printf(" lock_lowlevel = %llu\n", + (unsigned long long)stats.stats.lock_lowlevel); + printf(" lock_nonblock = %llu\n", + (unsigned long long)stats.stats.lock_nonblock); + printf(" lock_nonblock_fail = %llu\n", + (unsigned long long)stats.stats.lock_nonblock_fail); /* Now clear. */ - memset(&stats->allocs, 0, (char *)(stats+1) - (char *)&stats->allocs); + tdb_close(*tdb); + *tdb = tdb_open("/tmp/speed.tdb", flags, O_RDWR, 0, attr); +} + +static void tdb_log(struct tdb_context *tdb, + enum tdb_log_level level, + enum TDB_ERROR ecode, + const char *message, + void *data) +{ + fprintf(stderr, "tdb:%s:%s:%s\n", + tdb_name(tdb), tdb_errorstr(ecode), message); } int main(int argc, char *argv[]) { unsigned int i, j, num = 1000, stage = 0, stopat = -1; int flags = TDB_DEFAULT; - bool transaction = false; + bool transaction = false, summary = false; TDB_DATA key, data; struct tdb_context *tdb; struct timeval start, stop; - union tdb_attribute seed, stats; + union tdb_attribute seed, log; + bool do_stats = false; enum TDB_ERROR ecode; /* Try to keep benchmarks even. */ @@ -110,10 +153,9 @@ int main(int argc, char *argv[]) seed.base.next = NULL; seed.seed.seed = 0; - memset(&stats, 0, sizeof(stats)); - stats.base.attr = TDB_ATTRIBUTE_STATS; - stats.base.next = NULL; - stats.stats.size = sizeof(stats); + log.base.attr = TDB_ATTRIBUTE_LOG; + log.base.next = &seed; + log.log.fn = tdb_log; if (argv[1] && strcmp(argv[1], "--internal") == 0) { flags = TDB_INTERNAL; @@ -130,14 +172,19 @@ int main(int argc, char *argv[]) argc--; argv++; } + if (argv[1] && strcmp(argv[1], "--summary") == 0) { + summary = true; + argc--; + argv++; + } if (argv[1] && strcmp(argv[1], "--stats") == 0) { - seed.base.next = &stats; + do_stats = true; argc--; argv++; } tdb = tdb_open("/tmp/speed.tdb", flags, O_RDWR|O_CREAT|O_TRUNC, - 0600, &seed); + 0600, &log); if (!tdb) err(1, "Opening /tmp/speed.tdb"); @@ -157,11 +204,10 @@ int main(int argc, char *argv[]) argc--; } - if (transaction && (ecode = tdb_transaction_start(tdb))) - errx(1, "starting transaction: %s", tdb_errorstr(ecode)); - /* Add 1000 records. */ printf("Adding %u records: ", num); fflush(stdout); + if (transaction && (ecode = tdb_transaction_start(tdb))) + errx(1, "starting transaction: %s", tdb_errorstr(ecode)); gettimeofday(&start, NULL); for (i = 0; i < num; i++) if ((ecode = tdb_store(tdb, key, data, TDB_INSERT)) != 0) @@ -173,16 +219,24 @@ int main(int argc, char *argv[]) printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); - if (seed.base.next) - dump_and_clear_stats(&stats.stats); + if (tdb_check(tdb, NULL, NULL)) + errx(1, "tdb_check failed!"); + if (summary) { + char *sumstr = NULL; + tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr); + printf("%s\n", sumstr); + free(sumstr); + } + if (do_stats) + dump_and_clear_stats(&tdb, flags, &log); + if (++stage == stopat) exit(0); - if (transaction && (ecode = tdb_transaction_start(tdb))) - errx(1, "starting transaction: %s", tdb_errorstr(ecode)); - /* Finding 1000 records. */ printf("Finding %u records: ", num); fflush(stdout); + if (transaction && (ecode = tdb_transaction_start(tdb))) + errx(1, "starting transaction: %s", tdb_errorstr(ecode)); gettimeofday(&start, NULL); for (i = 0; i < num; i++) { struct tdb_data dbuf; @@ -197,16 +251,23 @@ int main(int argc, char *argv[]) errx(1, "committing transaction: %s", tdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); - if (seed.base.next) - dump_and_clear_stats(&stats.stats); + if (tdb_check(tdb, NULL, NULL)) + errx(1, "tdb_check failed!"); + if (summary) { + char *sumstr = NULL; + tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr); + printf("%s\n", sumstr); + free(sumstr); + } + if (do_stats) + dump_and_clear_stats(&tdb, flags, &log); if (++stage == stopat) exit(0); - if (transaction && (ecode = tdb_transaction_start(tdb))) - errx(1, "starting transaction: %s", tdb_errorstr(ecode)); - /* Missing 1000 records. */ printf("Missing %u records: ", num); fflush(stdout); + if (transaction && (ecode = tdb_transaction_start(tdb))) + errx(1, "starting transaction: %s", tdb_errorstr(ecode)); gettimeofday(&start, NULL); for (i = num; i < num*2; i++) { struct tdb_data dbuf; @@ -220,16 +281,23 @@ int main(int argc, char *argv[]) errx(1, "committing transaction: %s", tdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); - if (seed.base.next) - dump_and_clear_stats(&stats.stats); + if (tdb_check(tdb, NULL, NULL)) + errx(1, "tdb_check failed!"); + if (summary) { + char *sumstr = NULL; + tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr); + printf("%s\n", sumstr); + free(sumstr); + } + if (do_stats) + dump_and_clear_stats(&tdb, flags, &log); if (++stage == stopat) exit(0); - if (transaction && (ecode = tdb_transaction_start(tdb))) - errx(1, "starting transaction: %s", tdb_errorstr(ecode)); - /* Traverse 1000 records. */ printf("Traversing %u records: ", num); fflush(stdout); + if (transaction && (ecode = tdb_transaction_start(tdb))) + errx(1, "starting transaction: %s", tdb_errorstr(ecode)); i = 0; gettimeofday(&start, NULL); if (tdb_traverse(tdb, count_record, &i) != num) @@ -241,16 +309,23 @@ int main(int argc, char *argv[]) errx(1, "committing transaction: %s", tdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); - if (seed.base.next) - dump_and_clear_stats(&stats.stats); + if (tdb_check(tdb, NULL, NULL)) + errx(1, "tdb_check failed!"); + if (summary) { + char *sumstr = NULL; + tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr); + printf("%s\n", sumstr); + free(sumstr); + } + if (do_stats) + dump_and_clear_stats(&tdb, flags, &log); if (++stage == stopat) exit(0); - if (transaction && (ecode = tdb_transaction_start(tdb))) - errx(1, "starting transaction: %s", tdb_errorstr(ecode)); - /* Delete 1000 records (not in order). */ printf("Deleting %u records: ", num); fflush(stdout); + if (transaction && (ecode = tdb_transaction_start(tdb))) + errx(1, "starting transaction: %s", tdb_errorstr(ecode)); gettimeofday(&start, NULL); for (j = 0; j < num; j++) { i = (j + 100003) % num; @@ -263,16 +338,23 @@ int main(int argc, char *argv[]) errx(1, "committing transaction: %s", tdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); - if (seed.base.next) - dump_and_clear_stats(&stats.stats); + if (tdb_check(tdb, NULL, NULL)) + errx(1, "tdb_check failed!"); + if (summary) { + char *sumstr = NULL; + tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr); + printf("%s\n", sumstr); + free(sumstr); + } + if (do_stats) + dump_and_clear_stats(&tdb, flags, &log); if (++stage == stopat) exit(0); - if (transaction && (ecode = tdb_transaction_start(tdb))) - errx(1, "starting transaction: %s", tdb_errorstr(ecode)); - /* Re-add 1000 records (not in order). */ printf("Re-adding %u records: ", num); fflush(stdout); + if (transaction && (ecode = tdb_transaction_start(tdb))) + errx(1, "starting transaction: %s", tdb_errorstr(ecode)); gettimeofday(&start, NULL); for (j = 0; j < num; j++) { i = (j + 100003) % num; @@ -285,15 +367,22 @@ int main(int argc, char *argv[]) errx(1, "committing transaction: %s", tdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); - if (seed.base.next) - dump_and_clear_stats(&stats.stats); + if (tdb_check(tdb, NULL, NULL)) + errx(1, "tdb_check failed!"); + if (summary) { + char *sumstr = NULL; + tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr); + printf("%s\n", sumstr); + free(sumstr); + } + if (do_stats) + dump_and_clear_stats(&tdb, flags, &log); if (++stage == stopat) exit(0); + /* Append 1000 records. */ if (transaction && (ecode = tdb_transaction_start(tdb))) errx(1, "starting transaction: %s", tdb_errorstr(ecode)); - - /* Append 1000 records. */ printf("Appending %u records: ", num); fflush(stdout); gettimeofday(&start, NULL); for (i = 0; i < num; i++) @@ -305,13 +394,20 @@ int main(int argc, char *argv[]) errx(1, "committing transaction: %s", tdb_errorstr(ecode)); printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); + if (tdb_check(tdb, NULL, NULL)) + errx(1, "tdb_check failed!"); + if (summary) { + char *sumstr = NULL; + tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr); + printf("%s\n", sumstr); + free(sumstr); + } if (++stage == stopat) exit(0); + /* Churn 1000 records: not in order! */ if (transaction && (ecode = tdb_transaction_start(tdb))) errx(1, "starting transaction: %s", tdb_errorstr(ecode)); - - /* Churn 1000 records: not in order! */ printf("Churning %u records: ", num); fflush(stdout); gettimeofday(&start, NULL); for (j = 0; j < num; j++) { @@ -330,8 +426,16 @@ int main(int argc, char *argv[]) printf(" %zu ns (%zu bytes)\n", normalize(&start, &stop, num), file_size()); - if (seed.base.next) - dump_and_clear_stats(&stats.stats); + if (tdb_check(tdb, NULL, NULL)) + errx(1, "tdb_check failed!"); + if (summary) { + char *sumstr = NULL; + tdb_summary(tdb, TDB_SUMMARY_HISTOGRAMS, &sumstr); + printf("%s\n", sumstr); + free(sumstr); + } + if (do_stats) + dump_and_clear_stats(&tdb, flags, &log); if (++stage == stopat) exit(0);