Commit 8cca0397 authored by Rusty Russell's avatar Rusty Russell

tdb2: TDB_ATTRIBUTE_STATS access via tdb_get_attribute.

Now we have tdb_get_attribute, it makes sense to make that the method
of accessing statistics.  That way they are always available, and it's
probably cheaper doing the direct increment than even the unlikely()
branch.
parent 66ead2bc
......@@ -342,7 +342,7 @@ static tdb_bool_err coalesce(struct tdb_context *tdb,
struct tdb_free_record rec;
enum TDB_ERROR ecode;
add_stat(tdb, alloc_coalesce_tried, 1);
tdb->stats.alloc_coalesce_tried++;
end = off + sizeof(struct tdb_used_record) + data_len;
while (end < tdb->file->map_size) {
......@@ -376,7 +376,7 @@ static tdb_bool_err coalesce(struct tdb_context *tdb,
/* We may be violating lock order here, so best effort. */
if (tdb_lock_free_bucket(tdb, nb_off, TDB_LOCK_NOWAIT)
!= TDB_SUCCESS) {
add_stat(tdb, alloc_coalesce_lockfail, 1);
tdb->stats.alloc_coalesce_lockfail++;
break;
}
......@@ -388,14 +388,14 @@ static tdb_bool_err coalesce(struct tdb_context *tdb,
}
if (unlikely(frec_magic(&rec) != TDB_FREE_MAGIC)) {
add_stat(tdb, alloc_coalesce_race, 1);
tdb->stats.alloc_coalesce_race++;
tdb_unlock_free_bucket(tdb, nb_off);
break;
}
if (unlikely(frec_ftable(&rec) != ftable)
|| unlikely(size_to_bucket(frec_len(&rec)) != bucket)) {
add_stat(tdb, alloc_coalesce_race, 1);
tdb->stats.alloc_coalesce_race++;
tdb_unlock_free_bucket(tdb, nb_off);
break;
}
......@@ -409,7 +409,7 @@ static tdb_bool_err coalesce(struct tdb_context *tdb,
end += sizeof(struct tdb_used_record) + frec_len(&rec);
tdb_unlock_free_bucket(tdb, nb_off);
add_stat(tdb, alloc_coalesce_num_merged, 1);
tdb->stats.alloc_coalesce_num_merged++;
}
/* Didn't find any adjacent free? */
......@@ -446,7 +446,7 @@ static tdb_bool_err coalesce(struct tdb_context *tdb,
goto err;
}
add_stat(tdb, alloc_coalesce_succeeded, 1);
tdb->stats.alloc_coalesce_succeeded++;
tdb_unlock_free_bucket(tdb, b_off);
ecode = add_free_record(tdb, off, end - off);
......@@ -476,7 +476,7 @@ static tdb_off_t lock_and_alloc(struct tdb_context *tdb,
size_t size = adjust_size(keylen, datalen);
enum TDB_ERROR ecode;
add_stat(tdb, allocs, 1);
tdb->stats.allocs++;
again:
b_off = bucket_off(ftable_off, bucket);
......@@ -596,7 +596,7 @@ again:
/* Bucket of leftover will be <= current bucket, so nested
* locking is allowed. */
if (leftover) {
add_stat(tdb, alloc_leftover, 1);
tdb->stats.alloc_leftover++;
ecode = add_free_record(tdb,
best_off + sizeof(rec)
+ frec_len(&best) - leftover,
......@@ -649,9 +649,9 @@ static tdb_off_t get_free(struct tdb_context *tdb,
return off;
if (off != 0) {
if (b == start_b)
add_stat(tdb, alloc_bucket_exact, 1);
tdb->stats.alloc_bucket_exact++;
if (b == TDB_FREE_BUCKETS - 1)
add_stat(tdb, alloc_bucket_max, 1);
tdb->stats.alloc_bucket_max++;
/* Worked? Stay using this list. */
tdb->ftable_off = ftable_off;
tdb->ftable = ftable;
......@@ -758,7 +758,7 @@ static enum TDB_ERROR tdb_expand(struct tdb_context *tdb, tdb_len_t size)
/* We need to drop this lock before adding free record. */
tdb_unlock_expand(tdb, F_WRLCK);
add_stat(tdb, expands, 1);
tdb->stats.expands++;
return add_free_record(tdb, old_size, wanted);
}
......
......@@ -72,7 +72,7 @@ static tdb_bool_err key_matches(struct tdb_context *tdb,
const char *rkey;
if (rec_key_length(rec) != key->dsize) {
add_stat(tdb, compare_wrong_keylen, 1);
tdb->stats.compare_wrong_keylen++;
return ret;
}
......@@ -83,7 +83,7 @@ static tdb_bool_err key_matches(struct tdb_context *tdb,
if (memcmp(rkey, key->dptr, key->dsize) == 0)
ret = true;
else
add_stat(tdb, compare_wrong_keycmp, 1);
tdb->stats.compare_wrong_keycmp++;
tdb_access_release(tdb, rkey);
return ret;
}
......@@ -98,10 +98,10 @@ static tdb_bool_err match(struct tdb_context *tdb,
tdb_off_t off;
enum TDB_ERROR ecode;
add_stat(tdb, compares, 1);
tdb->stats.compares++;
/* Desired bucket must match. */
if (h->home_bucket != (val & TDB_OFF_HASH_GROUP_MASK)) {
add_stat(tdb, compare_wrong_bucket, 1);
tdb->stats.compare_wrong_bucket++;
return false;
}
......@@ -109,7 +109,7 @@ static tdb_bool_err match(struct tdb_context *tdb,
if (bits_from(val, TDB_OFF_HASH_EXTRA_BIT, TDB_OFF_UPPER_STEAL_EXTRA)
!= bits_from(h->h, 64 - h->hash_used - TDB_OFF_UPPER_STEAL_EXTRA,
TDB_OFF_UPPER_STEAL_EXTRA)) {
add_stat(tdb, compare_wrong_offsetbits, 1);
tdb->stats.compare_wrong_offsetbits++;
return false;
}
......@@ -120,7 +120,7 @@ static tdb_bool_err match(struct tdb_context *tdb,
}
if ((h->h & ((1 << 11)-1)) != rec_hash(rec)) {
add_stat(tdb, compare_wrong_rechash, 1);
tdb->stats.compare_wrong_rechash++;
return false;
}
......@@ -492,11 +492,11 @@ static enum TDB_ERROR expand_group(struct tdb_context *tdb, struct hash_info *h)
bucket = fullest_bucket(tdb, h->group, h->home_bucket);
if (h->hash_used == 64) {
add_stat(tdb, alloc_chain, 1);
tdb->stats.alloc_chain++;
subsize = sizeof(struct tdb_chain);
magic = TDB_CHAIN_MAGIC;
} else {
add_stat(tdb, alloc_subhash, 1);
tdb->stats.alloc_subhash++;
subsize = (sizeof(tdb_off_t) << TDB_SUBLEVEL_HASH_BITS);
magic = TDB_HTABLE_MAGIC;
}
......
......@@ -592,12 +592,6 @@ void tdb_inc_seqnum(struct tdb_context *tdb)
}
}
void add_stat_(struct tdb_context *tdb, uint64_t *s, size_t val)
{
if ((uintptr_t)s < (uintptr_t)tdb->stats + tdb->stats->size)
*s += val;
}
static const struct tdb_methods io_methods = {
tdb_read,
tdb_write,
......
......@@ -104,9 +104,9 @@ static int lock(struct tdb_context *tdb,
tdb->file->locker = getpid();
}
add_stat(tdb, lock_lowlevel, 1);
tdb->stats.lock_lowlevel++;
if (!waitflag)
add_stat(tdb, lock_nonblock, 1);
tdb->stats.lock_nonblock++;
return tdb->lock_fn(tdb->file->fd, rw, off, len, waitflag,
tdb->lock_data);
}
......@@ -359,7 +359,7 @@ static enum TDB_ERROR tdb_nest_lock(struct tdb_context *tdb,
return TDB_ERR_LOCK;
}
add_stat(tdb, locks, 1);
tdb->stats.locks++;
new_lck = find_nestlock(tdb, offset, NULL);
if (new_lck) {
......@@ -567,7 +567,7 @@ enum TDB_ERROR tdb_allrecord_lock(struct tdb_context *tdb, int ltype,
" can't upgrade a write lock");
}
add_stat(tdb, locks, 1);
tdb->stats.locks++;
again:
/* Lock hashes, gradually. */
ecode = tdb_lock_gradual(tdb, ltype, flags, TDB_HASH_LOCK_START,
......
......@@ -203,6 +203,12 @@ enum TDB_ERROR tdb_set_attribute(struct tdb_context *tdb,
: attr->base.attr == TDB_ATTRIBUTE_SEED
? "TDB_ATTRIBUTE_SEED"
: "TDB_ATTRIBUTE_OPENHOOK");
case TDB_ATTRIBUTE_STATS:
return tdb->last_error
= tdb_logerr(tdb, TDB_ERR_EINVAL,
TDB_LOG_USE_ERROR,
"tdb_set_attribute:"
" cannot set TDB_ATTRIBUTE_STATS");
case TDB_ATTRIBUTE_FLOCK:
tdb->lock_fn = attr->flock.lock;
tdb->unlock_fn = attr->flock.unlock;
......@@ -252,9 +258,13 @@ enum TDB_ERROR tdb_get_attribute(struct tdb_context *tdb,
TDB_LOG_USE_ERROR,
"tdb_get_attribute:"
" cannot get TDB_ATTRIBUTE_OPENHOOK");
case TDB_ATTRIBUTE_STATS:
/* FIXME */
return TDB_ERR_EINVAL;
case TDB_ATTRIBUTE_STATS: {
size_t size = attr->stats.size;
if (size > tdb->stats.size)
size = tdb->stats.size;
memcpy(&attr->stats, &tdb->stats, size);
break;
}
case TDB_ATTRIBUTE_FLOCK:
attr->flock.lock = tdb->lock_fn;
attr->flock.unlock = tdb->unlock_fn;
......@@ -291,7 +301,10 @@ void tdb_unset_attribute(struct tdb_context *tdb,
: "TDB_ATTRIBUTE_OPENHOOK");
break;
case TDB_ATTRIBUTE_STATS:
/* FIXME */
tdb_logerr(tdb, TDB_ERR_EINVAL,
TDB_LOG_USE_ERROR,
"tdb_unset_attribute:"
"cannot unset TDB_ATTRIBUTE_STATS");
break;
case TDB_ATTRIBUTE_FLOCK:
tdb->lock_fn = tdb_fcntl_lock;
......@@ -337,13 +350,15 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
tdb->flags = tdb_flags;
tdb->log_fn = NULL;
tdb->transaction = NULL;
tdb->stats = NULL;
tdb->access = NULL;
tdb->last_error = TDB_SUCCESS;
tdb->file = NULL;
tdb->lock_fn = tdb_fcntl_lock;
tdb->unlock_fn = tdb_fcntl_unlock;
tdb->hash_fn = jenkins_hash;
memset(&tdb->stats, 0, sizeof(tdb->stats));
tdb->stats.base.attr = TDB_ATTRIBUTE_STATS;
tdb->stats.size = sizeof(tdb->stats);
tdb_io_init(tdb);
while (attr) {
......@@ -355,12 +370,6 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
case TDB_ATTRIBUTE_SEED:
seed = &attr->seed;
break;
case TDB_ATTRIBUTE_STATS:
tdb->stats = &attr->stats;
/* They have stats we don't know about? Tell them. */
if (tdb->stats->size > sizeof(attr->stats))
tdb->stats->size = sizeof(attr->stats);
break;
case TDB_ATTRIBUTE_OPENHOOK:
openhook = &attr->openhook;
break;
......@@ -407,16 +416,6 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
if (ecode != TDB_SUCCESS) {
goto fail;
}
if (name) {
tdb->name = strdup(name);
if (!tdb->name) {
ecode = tdb_logerr(tdb, TDB_ERR_OOM,
TDB_LOG_ERROR,
"tdb_open: failed to"
" allocate name");
goto fail;
}
}
tdb_convert(tdb, &hdr.hash_seed, sizeof(hdr.hash_seed));
tdb->hash_seed = hdr.hash_seed;
tdb_ftable_init(tdb);
......@@ -525,13 +524,6 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
goto fail;
}
tdb->name = strdup(name);
if (!tdb->name) {
ecode = tdb_logerr(tdb, TDB_ERR_OOM, TDB_LOG_ERROR,
"tdb_open: failed to allocate name");
goto fail;
}
/* Clear any features we don't understand. */
if ((open_flags & O_ACCMODE) != O_RDONLY) {
hdr.features_used &= TDB_FEATURE_MASK;
......
......@@ -358,9 +358,6 @@ struct tdb_context {
/* mmap read only? */
int mmap_flags;
/* Error code for last tdb error. */
enum TDB_ERROR ecode;
/* the flags passed to tdb_open, for tdb_reopen. */
uint32_t flags;
......@@ -391,7 +388,8 @@ struct tdb_context {
/* IO methods: changes for transactions. */
const struct tdb_methods *methods;
struct tdb_attribute_stats *stats;
/* Our statistics. */
struct tdb_attribute_stats stats;
/* Direct access information */
struct tdb_access_hdr *access;
......@@ -535,14 +533,6 @@ enum TDB_ERROR tdb_read_convert(struct tdb_context *tdb, tdb_off_t off,
/* Bump the seqnum (caller checks for tdb->flags & TDB_SEQNUM) */
void tdb_inc_seqnum(struct tdb_context *tdb);
/* Adds a stat, if it's in range. */
void add_stat_(struct tdb_context *tdb, uint64_t *stat, size_t val);
#define add_stat(tdb, statname, val) \
do { \
if (unlikely((tdb)->stats)) \
add_stat_((tdb), &(tdb)->stats->statname, (val)); \
} while (0)
/* lock.c: */
/* Lock/unlock a range of hashes. */
enum TDB_ERROR tdb_lock_hashes(struct tdb_context *tdb,
......
......@@ -38,7 +38,7 @@ static enum TDB_ERROR replace_data(struct tdb_context *tdb,
/* We didn't like the existing one: remove it. */
if (old_off) {
add_stat(tdb, frees, 1);
tdb->stats.frees++;
ecode = add_free_record(tdb, old_off,
sizeof(struct tdb_used_record)
+ key.dsize + old_room);
......@@ -285,7 +285,7 @@ enum TDB_ERROR tdb_delete(struct tdb_context *tdb, struct tdb_data key)
}
/* Free the deleted entry. */
add_stat(tdb, frees, 1);
tdb->stats.frees++;
ecode = add_free_record(tdb, off,
sizeof(struct tdb_used_record)
+ rec_key_length(&rec)
......
......@@ -729,13 +729,13 @@ struct tdb_attribute_seed {
* struct tdb_attribute_stats - tdb operational statistics
*
* This attribute records statistics of various low-level TDB operations.
* This can be used to assist performance evaluation.
* This can be used to assist performance evaluation. This is only
* useful for tdb_get_attribute().
*
* New fields will be added at the end, hence the "size" argument which
* indicates how large your structure is. If your size is larger than
* that known about by this version of tdb, the size will be reduced to
* the known structure size. Thus you can detect older versions, and
* thus know that newer stats will not be updated.
* indicates how large your structure is: it must be filled in before
* calling tdb_get_attribute(), which will overwrite it with the size
* tdb knows about.
*/
struct tdb_attribute_stats {
struct tdb_attribute_base base; /* .attr = TDB_ATTRIBUTE_STATS */
......
......@@ -4,7 +4,7 @@
#include <stdbool.h>
/* FIXME: Check these! */
#define INITIAL_TDB_MALLOC "open.c", 324, FAILTEST_MALLOC
#define INITIAL_TDB_MALLOC "open.c", 337, FAILTEST_MALLOC
#define URANDOM_OPEN "open.c", 45, FAILTEST_OPEN
#define URANDOM_READ "open.c", 25, FAILTEST_READ
......
#include <ccan/tdb2/tdb.c>
#include <ccan/tdb2/open.c>
#include <ccan/tdb2/free.c>
#include <ccan/tdb2/lock.c>
#include <ccan/tdb2/io.c>
#include <ccan/tdb2/hash.c>
#include <ccan/tdb2/check.c>
#include <ccan/tdb2/transaction.c>
#include <ccan/tdb2/traverse.c>
#include <ccan/tap/tap.h>
#include "logging.h"
int main(int argc, char *argv[])
{
unsigned int i;
struct tdb_context *tdb;
int flags[] = { TDB_DEFAULT, TDB_NOMMAP,
TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT };
plan_tests(sizeof(flags) / sizeof(flags[0]) * 11);
for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
union tdb_attribute *attr;
struct tdb_data key = tdb_mkdata("key", 3);
tdb = tdb_open("run-91-get-stats.tdb", flags[i],
O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
ok1(tdb);
ok1(tdb_store(tdb, key, key, TDB_REPLACE) == 0);
/* Use malloc so valgrind will catch overruns. */
attr = malloc(sizeof *attr);
attr->stats.base.attr = TDB_ATTRIBUTE_STATS;
attr->stats.size = sizeof(*attr);
ok1(tdb_get_attribute(tdb, 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 tdb_attribute_stats, allocs)
+ sizeof(attr->stats.allocs));
attr->stats.base.attr = TDB_ATTRIBUTE_STATS;
attr->stats.size = offsetof(struct tdb_attribute_stats, allocs)
+ sizeof(attr->stats.allocs);
ok1(tdb_get_attribute(tdb, attr) == 0);
ok1(attr->stats.size == sizeof(*attr));
ok1(attr->stats.allocs > 0);
free(attr);
ok1(tap_log_messages == 0);
tdb_close(tdb);
}
return exit_status();
}
......@@ -43,55 +43,67 @@ 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_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);
(unsigned long long)stats.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_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("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);
(unsigned long long)stats.stats.locks);
printf(" lock_lowlevel = %llu\n",
(unsigned long long)stats->lock_lowlevel);
(unsigned long long)stats.stats.lock_lowlevel);
printf(" lock_nonblock = %llu\n",
(unsigned long long)stats->lock_nonblock);
(unsigned long long)stats.stats.lock_nonblock);
/* 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,
......@@ -109,7 +121,8 @@ int main(int argc, char *argv[])
TDB_DATA key, data;
struct tdb_context *tdb;
struct timeval start, stop;
union tdb_attribute seed, stats, log;
union tdb_attribute seed, log;
bool do_stats = false;
enum TDB_ERROR ecode;
/* Try to keep benchmarks even. */
......@@ -121,11 +134,6 @@ int main(int argc, char *argv[])
log.base.next = &seed;
log.log.fn = tdb_log;
memset(&stats, 0, sizeof(stats));
stats.base.attr = TDB_ATTRIBUTE_STATS;
stats.base.next = NULL;
stats.stats.size = sizeof(stats);
if (argv[1] && strcmp(argv[1], "--internal") == 0) {
flags = TDB_INTERNAL;
argc--;
......@@ -147,7 +155,7 @@ int main(int argc, char *argv[])
argv++;
}
if (argv[1] && strcmp(argv[1], "--stats") == 0) {
seed.base.next = &stats;
do_stats = true;
argc--;
argv++;
}
......@@ -196,8 +204,8 @@ int main(int argc, char *argv[])
printf("%s\n", sumstr);
free(sumstr);
}
if (seed.base.next)
dump_and_clear_stats(&stats.stats);
if (do_stats)
dump_and_clear_stats(&tdb, flags, &log);
if (++stage == stopat)
exit(0);
......@@ -228,8 +236,8 @@ int main(int argc, char *argv[])
printf("%s\n", sumstr);
free(sumstr);
}
if (seed.base.next)
dump_and_clear_stats(&stats.stats);
if (do_stats)
dump_and_clear_stats(&tdb, flags, &log);
if (++stage == stopat)
exit(0);
......@@ -258,8 +266,8 @@ int main(int argc, char *argv[])
printf("%s\n", sumstr);
free(sumstr);
}
if (seed.base.next)
dump_and_clear_stats(&stats.stats);
if (do_stats)
dump_and_clear_stats(&tdb, flags, &log);
if (++stage == stopat)
exit(0);
......@@ -286,8 +294,8 @@ int main(int argc, char *argv[])
printf("%s\n", sumstr);
free(sumstr);
}
if (seed.base.next)
dump_and_clear_stats(&stats.stats);
if (do_stats)
dump_and_clear_stats(&tdb, flags, &log);
if (++stage == stopat)
exit(0);
......@@ -315,8 +323,8 @@ int main(int argc, char *argv[])
printf("%s\n", sumstr);
free(sumstr);
}
if (seed.base.next)
dump_and_clear_stats(&stats.stats);
if (do_stats)
dump_and_clear_stats(&tdb, flags, &log);
if (++stage == stopat)
exit(0);
......@@ -344,8 +352,8 @@ int main(int argc, char *argv[])
printf("%s\n", sumstr);
free(sumstr);
}
if (seed.base.next)
dump_and_clear_stats(&stats.stats);
if (do_stats)
dump_and_clear_stats(&tdb, flags, &log);
if (++stage == stopat)
exit(0);
......@@ -403,8 +411,8 @@ int main(int argc, char *argv[])
printf("%s\n", sumstr);
free(sumstr);
}
if (seed.base.next)
dump_and_clear_stats(&stats.stats);
if (do_stats)
dump_and_clear_stats(&tdb, flags, &log);
if (++stage == stopat)
exit(0);
......
......@@ -682,7 +682,7 @@ static enum TDB_ERROR tdb_recovery_allocate(struct tdb_context *tdb,
us an area that is being currently used (as of the start of
the transaction) */
if (recovery_head != 0) {
add_stat(tdb, frees, 1);
tdb->stats.frees++;
ecode = add_free_record(tdb, recovery_head,
sizeof(rec) + rec.max_len);
if (ecode != TDB_SUCCESS) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment