dovecot: More squat fixes.
dovecot at dovecot.org
dovecot at dovecot.org
Sun Feb 10 21:55:06 EET 2008
details: http://hg.dovecot.org/dovecot/rev/e042b6385c7b
changeset: 7221:e042b6385c7b
user: Timo Sirainen <tss at iki.fi>
date: Sun Feb 10 21:54:57 2008 +0200
description:
More squat fixes.
diffstat:
2 files changed, 68 insertions(+), 27 deletions(-)
src/plugins/fts-squat/squat-trie-private.h | 3
src/plugins/fts-squat/squat-trie.c | 92 ++++++++++++++++++++--------
diffs (197 lines):
diff -r 21d1d0ced13e -r e042b6385c7b src/plugins/fts-squat/squat-trie-private.h
--- a/src/plugins/fts-squat/squat-trie-private.h Sat Feb 09 15:11:24 2008 +0200
+++ b/src/plugins/fts-squat/squat-trie-private.h Sun Feb 10 21:54:57 2008 +0200
@@ -61,7 +61,8 @@ struct squat_node {
first SEQUENTIAL_COUNT children have chars[n] = n. */
unsigned int have_sequential:1;
- /* Number of UIDs that exists in parent node but not in this one.
+ /* Number of UIDs that exists in parent node but not in this one
+ (i.e. number of UIDs [0..next_uid-1] not in this node's uidlist).
This is mainly used when adding new UIDs to our children to set
the UID to be relative to this node's UID list. */
uint32_t unused_uids;
diff -r 21d1d0ced13e -r e042b6385c7b src/plugins/fts-squat/squat-trie.c
--- a/src/plugins/fts-squat/squat-trie.c Sat Feb 09 15:11:24 2008 +0200
+++ b/src/plugins/fts-squat/squat-trie.c Sun Feb 10 21:54:57 2008 +0200
@@ -140,6 +140,22 @@ squat_trie_init(const char *path, uint32
return trie;
}
+static void squat_trie_close_fd(struct squat_trie *trie)
+{
+ trie->data = NULL;
+ trie->data_size = 0;
+
+ if (trie->mmap_size != 0) {
+ if (munmap(trie->mmap_base, trie->mmap_size) < 0)
+ i_error("munmap(%s) failed: %m", trie->path);
+ }
+ if (trie->fd != -1) {
+ if (close(trie->fd) < 0)
+ i_error("close(%s) failed: %m", trie->path);
+ trie->fd = -1;
+ }
+}
+
static void squat_trie_close(struct squat_trie *trie)
{
trie->corrupted = FALSE;
@@ -147,20 +163,9 @@ static void squat_trie_close(struct squa
memset(&trie->root, 0, sizeof(trie->root));
memset(&trie->hdr, 0, sizeof(trie->hdr));
- trie->data = NULL;
- trie->data_size = 0;
-
+ squat_trie_close_fd(trie);
if (trie->file_cache != NULL)
file_cache_free(&trie->file_cache);
- if (trie->mmap_size != 0) {
- if (munmap(trie->mmap_base, trie->mmap_size) < 0)
- i_error("munmap(%s) failed: %m", trie->path);
- }
- if (trie->fd != -1) {
- if (close(trie->fd) < 0)
- i_error("close(%s) failed: %m", trie->path);
- trie->fd = -1;
- }
trie->locked_file_size = 0;
}
@@ -232,8 +237,11 @@ static int squat_trie_is_file_stale(stru
}
trie->locked_file_size = st2.st_size;
- return st.st_ino == st2.st_ino &&
- CMP_DEV_T(st.st_dev, st2.st_dev) ? 0 : 1;
+ if (st.st_ino == st2.st_ino && CMP_DEV_T(st.st_dev, st2.st_dev)) {
+ i_assert(trie->locked_file_size >= trie->data_size);
+ return 0;
+ }
+ return 1;
}
void squat_trie_refresh(struct squat_trie *trie)
@@ -704,6 +712,7 @@ static int squat_build_add(struct squat_
level++;
if (node->have_sequential) {
+ i_assert(node->child_count >= SEQUENTIAL_COUNT);
if (*data < SEQUENTIAL_COUNT) {
idx = *data;
goto found;
@@ -1089,7 +1098,8 @@ squat_uidlist_update_expunged_uids(const
squat_uidlist_update_expunged_uids(const ARRAY_TYPE(seq_range) *shifts_arr,
ARRAY_TYPE(seq_range) *child_shifts,
ARRAY_TYPE(seq_range) *uids_arr,
- bool do_shifts)
+ struct squat_trie *trie,
+ struct squat_node *node, bool do_shifts)
{
const struct seq_range *shifts;
struct seq_range *uids, shift;
@@ -1097,8 +1107,13 @@ 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)) {
+ i_assert(node->uid_list_idx != 0 || node->child_count == 0);
return;
+ }
+
+ /* we'll recalculate this */
+ node->unused_uids = 0;
uids = array_get_modifiable(uids_arr, &uid_count);
shifts = array_get(shifts_arr, &shift_count);
@@ -1115,13 +1130,22 @@ squat_uidlist_update_expunged_uids(const
uids[uid_idx].seq1 + 1;
if (uid_idx > 0 &&
- uids[uid_idx-1].seq2 == uids[uid_idx].seq1 - 1) {
+ uids[uid_idx-1].seq2 >= uids[uid_idx].seq1 - 1) {
/* we can merge this and the previous range */
+ i_assert(uids[uid_idx-1].seq2 ==
+ uids[uid_idx].seq1 - 1);
uids[uid_idx-1].seq2 = uids[uid_idx].seq2;
array_delete(uids_arr, uid_idx, 1);
uids = array_get_modifiable(uids_arr,
&uid_count);
} else {
+ if (uid_idx == 0)
+ node->unused_uids += uids[0].seq1;
+ else {
+ node->unused_uids +=
+ uids[uid_idx].seq1 -
+ uids[uid_idx-1].seq2 - 1;
+ }
uid_idx++;
}
}
@@ -1186,6 +1210,24 @@ squat_uidlist_update_expunged_uids(const
shift_sum = 0;
}
}
+
+ if (uid_count == 0) {
+ /* no UIDs left, delete the node's children and mark it
+ unused */
+ i_assert(!NODE_IS_DYNAMIC_LEAF(node));
+ node_free(trie, node);
+
+ node->child_count = 0;
+ node->have_sequential = FALSE;
+ node->next_uid = 0;
+ } else {
+ if (do_shifts)
+ node->next_uid = uids[uid_count-1].seq2 + 1;
+ else {
+ node->unused_uids += (node->next_uid - 1) -
+ uids[uid_count-1].seq2;
+ }
+ }
}
static int
@@ -1217,13 +1259,12 @@ squat_trie_expunge_uidlists(struct squat
break;
}
squat_uidlist_update_expunged_uids(&shifts, &iter->cur.shifts,
- &uid_range, shift);
+ &uid_range, ctx->trie, node,
+ shift);
node->uid_list_idx =
squat_uidlist_rebuild_nextu(rebuild_ctx, &uid_range);
- if (node->uid_list_idx == 0) {
- node->child_count = 0;
- node->next_uid = 0;
- }
+ i_assert(node->uid_list_idx != 0 || node->next_uid == 0);
+
node = squat_trie_iterate_next(iter, &shifts);
shift = TRUE;
} while (node != NULL);
@@ -1434,6 +1475,7 @@ int squat_trie_build_init(struct squat_t
}
if (trie->file_cache != NULL)
file_cache_set_fd(trie->file_cache, trie->fd);
+ i_assert(trie->locked_file_size == 0);
}
/* uidlist locks building */
@@ -1557,11 +1599,9 @@ static int squat_trie_write(struct squat
if (unlink(path) < 0 && errno != ENOENT)
i_error("unlink(%s) failed: %m", path);
} else {
- if (trie->fd != -1) {
- if (close(trie->fd) < 0)
- i_error("close(%s) failed: %m", trie->path);
- }
+ squat_trie_close_fd(trie);
trie->fd = fd;
+ trie->locked_file_size = trie->hdr.used_file_size;
if (trie->file_cache != NULL)
file_cache_set_fd(trie->file_cache, trie->fd);
}
More information about the dovecot-cvs
mailing list