X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Ftdb1_summary.c;fp=ccan%2Ftdb2%2Ftdb1_summary.c;h=0000000000000000000000000000000000000000;hp=b74b8f4474b87d8185aadde606f0635294cf2277;hb=b91dafc6ab5075355d508f051977a15dd7794b0e;hpb=0b93bd102aad6b61f1e569fb12aabc6352a1d7cd diff --git a/ccan/tdb2/tdb1_summary.c b/ccan/tdb2/tdb1_summary.c deleted file mode 100644 index b74b8f44..00000000 --- a/ccan/tdb2/tdb1_summary.c +++ /dev/null @@ -1,202 +0,0 @@ - /* - Trivial Database: human-readable summary code - Copyright (C) Rusty Russell 2010 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ -#include "tdb1_private.h" - -#define SUMMARY_FORMAT1 \ - "Size of file/data: %u/%zu\n" \ - "Number of records: %zu\n" \ - "Smallest/average/largest keys: %zu/%zu/%zu\n" \ - "Smallest/average/largest data: %zu/%zu/%zu\n" \ - "Smallest/average/largest padding: %zu/%zu/%zu\n" \ - "Number of dead records: %zu\n" \ - "Smallest/average/largest dead records: %zu/%zu/%zu\n" \ - "Number of free records: %zu\n" \ - "Smallest/average/largest free records: %zu/%zu/%zu\n" \ - "Number of hash chains: %zu\n" \ - "Smallest/average/largest hash chains: %zu/%zu/%zu\n" \ - "Number of uncoalesced records: %zu\n" \ - "Smallest/average/largest uncoalesced runs: %zu/%zu/%zu\n" \ - "Percentage keys/data/padding/free/dead/rechdrs&tailers/hashes: %.0f/%.0f/%.0f/%.0f/%.0f/%.0f/%.0f\n" - -/* We don't use tally module, to keep upstream happy. */ -struct tally { - size_t min, max, total; - size_t num; -}; - -static void tally1_init(struct tally *tally) -{ - tally->total = 0; - tally->num = 0; - tally->min = tally->max = 0; -} - -static void tally1_add(struct tally *tally, size_t len) -{ - if (tally->num == 0) - tally->max = tally->min = len; - else if (len > tally->max) - tally->max = len; - else if (len < tally->min) - tally->min = len; - tally->num++; - tally->total += len; -} - -static size_t tally1_mean(const struct tally *tally) -{ - if (!tally->num) - return 0; - return tally->total / tally->num; -} - -static size_t get_hash_length(struct tdb_context *tdb, unsigned int i) -{ - tdb1_off_t rec_ptr; - size_t count = 0; - - if (tdb1_ofs_read(tdb, TDB1_HASH_TOP(i), &rec_ptr) == -1) - return 0; - - /* keep looking until we find the right record */ - while (rec_ptr) { - struct tdb1_record r; - ++count; - if (tdb1_rec_read(tdb, rec_ptr, &r) == -1) - return 0; - rec_ptr = r.next; - } - return count; -} - -char *tdb1_summary(struct tdb_context *tdb) -{ - tdb1_off_t off, rec_off; - struct tally freet, keys, data, dead, extra, hash, uncoal; - struct tdb1_record rec; - char *ret = NULL; - bool locked; - size_t len, unc = 0; - struct tdb1_record recovery; - - /* We may have a write lock already, so don't lock. */ - if (tdb->file->allrecord_lock.count != 0) { - locked = false; - } else { - if (tdb_lockall_read(tdb) != TDB_SUCCESS) - return NULL; - locked = true; - } - - if (tdb1_recovery_area(tdb, tdb->tdb1.io, &rec_off, &recovery) != 0) { - goto unlock; - } - - tally1_init(&freet); - tally1_init(&keys); - tally1_init(&data); - tally1_init(&dead); - tally1_init(&extra); - tally1_init(&hash); - tally1_init(&uncoal); - - for (off = TDB1_DATA_START(tdb->tdb1.header.hash_size); - off < tdb->file->map_size - 1; - off += sizeof(rec) + rec.rec_len) { - if (tdb->tdb1.io->tdb1_read(tdb, off, &rec, sizeof(rec), - TDB1_DOCONV()) == -1) - goto unlock; - switch (rec.magic) { - case TDB1_MAGIC: - tally1_add(&keys, rec.key_len); - tally1_add(&data, rec.data_len); - tally1_add(&extra, rec.rec_len - (rec.key_len - + rec.data_len)); - if (unc > 1) - tally1_add(&uncoal, unc - 1); - unc = 0; - break; - case TDB1_FREE_MAGIC: - tally1_add(&freet, rec.rec_len); - unc++; - break; - /* If we crash after ftruncate, we can get zeroes or fill. */ - case TDB1_RECOVERY_INVALID_MAGIC: - case 0x42424242: - unc++; - /* If it's a valid recovery, we can trust rec_len. */ - if (off != rec_off) { - rec.rec_len = tdb1_dead_space(tdb, off) - - sizeof(rec); - } - /* Fall through */ - case TDB1_DEAD_MAGIC: - tally1_add(&dead, rec.rec_len); - break; - default: - tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, - TDB_LOG_ERROR, - "Unexpected record magic 0x%x" - " at offset %d", - rec.magic, off); - goto unlock; - } - } - if (unc > 1) - tally1_add(&uncoal, unc - 1); - - for (off = 0; off < tdb->tdb1.header.hash_size; off++) - tally1_add(&hash, get_hash_length(tdb, off)); - - /* 20 is max length of a %zu. */ - len = strlen(SUMMARY_FORMAT1) + 35*20 + 1; - ret = (char *)malloc(len); - if (!ret) - goto unlock; - - snprintf(ret, len, SUMMARY_FORMAT1, - (tdb1_len_t)tdb->file->map_size, keys.total+data.total, - keys.num, - keys.min, tally1_mean(&keys), keys.max, - data.min, tally1_mean(&data), data.max, - extra.min, tally1_mean(&extra), extra.max, - dead.num, - dead.min, tally1_mean(&dead), dead.max, - freet.num, - freet.min, tally1_mean(&freet), freet.max, - hash.num, - hash.min, tally1_mean(&hash), hash.max, - uncoal.total, - uncoal.min, tally1_mean(&uncoal), uncoal.max, - keys.total * 100.0 / tdb->file->map_size, - data.total * 100.0 / tdb->file->map_size, - extra.total * 100.0 / tdb->file->map_size, - freet.total * 100.0 / tdb->file->map_size, - dead.total * 100.0 / tdb->file->map_size, - (keys.num + freet.num + dead.num) - * (sizeof(struct tdb1_record) + sizeof(uint32_t)) - * 100.0 / tdb->file->map_size, - tdb->tdb1.header.hash_size * sizeof(tdb1_off_t) - * 100.0 / (tdb1_len_t)tdb->file->map_size); - -unlock: - if (locked) { - tdb_unlockall_read(tdb); - } - return ret; -}