diff -r eb310b0d0966 src/plugins/fts-squat/squat-trie.c --- a/src/plugins/fts-squat/squat-trie.c Sat Feb 16 13:22:11 2008 +0200 +++ b/src/plugins/fts-squat/squat-trie.c Sat Feb 16 14:21:34 2008 +0200 @@ -30,6 +30,33 @@ #define TRIE_READAHEAD_SIZE \ I_MAX(4096, 1 + 256 + TRIE_BYTES_LEFT(256)) +#include +#include +#include +#include "ioloop.h" +void i_debug(const char *format, ...) +{ + static FILE *f = NULL; + va_list args; + struct timeval tv; + + gettimeofday(&tv, NULL); + + va_start(args, format); + t_push(); + if (!f) { + const char *dir = t_strdup_printf("/tmp/dovecot/%d", (int)ioloop_time/10); + mkdir(dir, 0700); + f = fopen(t_strdup_printf("%s/%d", dir, getpid()), "a+"); + setbuf(f, NULL); + } + fprintf(f, "%10u.%06u PID=%s %s\n", + (unsigned)tv.tv_sec, (unsigned)tv.tv_usec, + dec2str(getpid()), t_strdup_vprintf(format, args)); + t_pop(); + va_end(args); +} + struct squat_trie_build_context { struct squat_trie *trie; struct ostream *output; @@ -54,6 +81,24 @@ struct squat_trie_iterate_context { bool failed; }; +static const char *uidrange2str(const ARRAY_TYPE(seq_range) *uids) +{ + const struct seq_range *range; + unsigned int i, count; + string_t *str = t_str_new(256); + + range = array_get(uids, &count); + for (i = 0; i < count; i++) { + if (i != 0) + str_append_c(str, ','); + if (range[i].seq1 == range[i].seq2) + str_printfa(str, "%u", range[i].seq1); + else + str_printfa(str, "%u-%u", range[i].seq1, range[i].seq2); + } + return str_c(str); +} + static int squat_trie_map(struct squat_trie *trie, bool building); void squat_trie_delete(struct squat_trie *trie) @@ -67,6 +112,7 @@ static void squat_trie_set_corrupted(str { trie->corrupted = TRUE; i_error("Corrupted file %s", trie->path); + abort(); squat_trie_delete(trie); } @@ -1056,7 +1102,8 @@ squat_trie_iterate_first(struct squat_tr static struct squat_node * squat_trie_iterate_next(struct squat_trie_iterate_context *ctx, - ARRAY_TYPE(seq_range) *shifts_r) + ARRAY_TYPE(seq_range) *shifts_r, + struct squat_node **parent_r) { struct squat_trie_iterate_node *iter_nodes; struct squat_node *children; @@ -1075,6 +1122,7 @@ squat_trie_iterate_next(struct squat_tri array_delete(&ctx->parents, count-1, 1); } + *parent_r = ctx->cur.node; *shifts_r = ctx->cur.shifts; if (array_is_created(&ctx->cur.shifts)) shift_count = array_count(&ctx->cur.shifts); @@ -1083,7 +1131,7 @@ squat_trie_iterate_next(struct squat_tri while (children[ctx->cur.idx++].uid_list_idx == 0) { if (ctx->cur.idx == ctx->cur.node->child_count) { /* no more non-empty children in this node */ - return squat_trie_iterate_next(ctx, shifts_r); + return squat_trie_iterate_next(ctx, shifts_r, parent_r); } } array_append(&ctx->parents, &ctx->cur, 1); @@ -1101,7 +1149,8 @@ squat_uidlist_update_expunged_uids(const ARRAY_TYPE(seq_range) *child_shifts, ARRAY_TYPE(seq_range) *uids_arr, struct squat_trie *trie, - struct squat_node *node, bool do_shifts) + struct squat_node *node, + struct squat_node *parent, bool do_shifts) { const struct seq_range *shifts; struct seq_range *uids, shift; @@ -1109,10 +1158,18 @@ squat_uidlist_update_expunged_uids(const uint32_t child_shift_seq1, child_shift_count, seq_high; unsigned int shift_sum = 0, child_sum = 0; - if (!array_is_created(shifts_arr)) { + if (!array_is_created(shifts_arr) || array_count(shifts_arr) == 0) { i_assert(node->uid_list_idx != 0 || node->child_count == 0); return; } + i_assert(array_is_created(child_shifts)); + + /*if (do_shifts) { + i_debug("before unused_uids=%u child_count=%u: %s", + node->unused_uids, node->child_count, + uidrange2str(uids_arr)); + i_debug(" - shifts: %s", uidrange2str(shifts_arr)); + }*/ /* we'll recalculate this */ node->unused_uids = 0; @@ -1229,13 +1286,25 @@ squat_uidlist_update_expunged_uids(const node->have_sequential = FALSE; node->next_uid = 0; } else { - if (do_shifts) + unsigned int n = uids[0].seq1; + for (i = 1; i < uid_count; i++) + n += uids[i].seq1 - uids[i-1].seq2 - 1; + i_assert(n == node->unused_uids); + if (do_shifts) { node->next_uid = uids[uid_count-1].seq2 + 1; - else { + i_assert(node->next_uid <= parent->next_uid - parent->unused_uids); + } else { node->unused_uids += (node->next_uid - 1) - uids[uid_count-1].seq2; } } + + /*if (do_shifts) { + i_debug("after: unused_uids=%u child_count=%u: %s", + node->unused_uids, node->child_count, + uidrange2str(uids_arr)); + i_debug(" - child_shifts: %s", uidrange2str(child_shifts)); + }*/ } static int @@ -1244,10 +1313,12 @@ squat_trie_expunge_uidlists(struct squat struct squat_trie_iterate_context *iter, const ARRAY_TYPE(seq_range) *expunged_uids) { - struct squat_node *node; + struct squat_node *node, *parent; ARRAY_TYPE(seq_range) uid_range, shifts; bool shift = FALSE; int ret = 0; + + i_debug("expunges: %s", uidrange2str(expunged_uids)); node = squat_trie_iterate_first(iter); if (node->uid_list_idx == 0) @@ -1255,8 +1326,10 @@ squat_trie_expunge_uidlists(struct squat i_array_init(&uid_range, 1024); i_array_init(&shifts, array_count(expunged_uids)); + i_array_init(&iter->cur.shifts, array_count(expunged_uids)); array_append_array(&shifts, expunged_uids); + parent = NULL; do { i_assert(node->uid_list_idx != 0); array_clear(&uid_range); @@ -1268,12 +1341,12 @@ squat_trie_expunge_uidlists(struct squat } squat_uidlist_update_expunged_uids(&shifts, &iter->cur.shifts, &uid_range, ctx->trie, node, - shift); + parent, shift); node->uid_list_idx = squat_uidlist_rebuild_nextu(rebuild_ctx, &uid_range); i_assert(node->uid_list_idx != 0 || node->next_uid == 0); - node = squat_trie_iterate_next(iter, &shifts); + node = squat_trie_iterate_next(iter, &shifts, &parent); shift = TRUE; } while (node != NULL); array_free(&uid_range); @@ -1308,7 +1381,7 @@ squat_trie_renumber_uidlists2(struct squ node->uid_list_idx = squat_uidlist_rebuild_next(rebuild_ctx, &uids); } - node = squat_trie_iterate_next(iter, &shifts); + node = squat_trie_iterate_next(iter, &shifts, NULL); } array_free(&uids); return ret; diff -r eb310b0d0966 src/plugins/fts-squat/squat-uidlist.c --- a/src/plugins/fts-squat/squat-uidlist.c Sat Feb 16 13:22:11 2008 +0200 +++ b/src/plugins/fts-squat/squat-uidlist.c Sat Feb 16 14:21:34 2008 +0200 @@ -103,6 +103,7 @@ static void squat_uidlist_set_corrupted( uidlist->corrupted = TRUE; i_error("Corrupted squat uidlist file %s: %s", uidlist->path, reason); + abort(); //FIXME squat_trie_delete(uidlist->trie); } @@ -844,6 +845,7 @@ int squat_uidlist_rebuild_init(struct sq const char *temp_path; int fd; +#if 0 if (build_ctx->build_hdr.link_count == 0) return 0; @@ -852,6 +854,7 @@ int squat_uidlist_rebuild_init(struct sq build_ctx->build_hdr.count*2/3) return 0; } +#endif temp_path = t_strconcat(build_ctx->uidlist->path, ".tmp", NULL); fd = open(temp_path, O_RDWR | O_TRUNC | O_CREAT, 0600);