[dovecot-cvs] dovecot/src/lib-index mail-cache-compress.c, 1.14, 1.15 mail-cache-lookup.c, 1.17, 1.18

cras at dovecot.org cras at dovecot.org
Sat Sep 4 13:26:39 EEST 2004


Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv27684/lib-index

Modified Files:
	mail-cache-compress.c mail-cache-lookup.c 
Log Message:
Added support for bitmask type.



Index: mail-cache-compress.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-compress.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- mail-cache-compress.c	31 Jul 2004 03:06:48 -0000	1.14
+++ mail-cache-compress.c	4 Sep 2004 10:26:36 -0000	1.15
@@ -14,26 +14,67 @@
 	uint8_t field_seen_value;
 };
 
+static void mail_cache_merge_bitmask(struct mail_cache *cache, buffer_t *buffer,
+				     uint32_t file_field, const void *data,
+				     size_t data_size)
+{
+	void *buf_data;
+	uint32_t field, buf_file_field;
+	unsigned int i, buf_data_size;
+	size_t pos, buf_size;
+
+	buf_data = buffer_get_modifyable_data(buffer, &buf_size);
+	for (pos = sizeof(struct mail_cache_record); pos < buf_size; ) {
+		buf_file_field = *((uint32_t *)PTR_OFFSET(buf_data, pos));
+		pos += sizeof(uint32_t);
+
+		field = cache->file_field_map[file_field];
+		buf_data_size = cache->fields[field].field.field_size;
+		if (buf_data_size == (unsigned int)-1) {
+			buf_data_size =
+				*((uint32_t *)PTR_OFFSET(buf_data, pos));
+			pos += sizeof(uint32_t);
+		}
+
+		if (buf_file_field == file_field) {
+			/* found it, do the merging */
+			unsigned char *dest = PTR_OFFSET(buf_data, pos);
+
+			i_assert(buf_data_size == data_size);
+			for (i = 0; i < buf_data_size; i++)
+				dest[i] |= ((const unsigned char*)data)[i];
+			break;
+		}
+		pos += (data_size + 3) & ~3;
+	}
+}
+
 static int
 mail_cache_compress_callback(struct mail_cache_view *view, uint32_t file_field,
 			     const void *data, size_t data_size, void *context)
 {
 	struct mail_cache_copy_context *ctx = context;
+        struct mail_cache_field *cache_field;
 	enum mail_cache_decision_type dec;
 	unsigned int field;
 	uint8_t *field_seen;
 	uint32_t size32;
 
+	field = view->cache->file_field_map[file_field];
+	cache_field = &view->cache->fields[field].field;
+
 	field_seen = buffer_get_space_unsafe(ctx->field_seen, file_field, 1);
 	if (*field_seen == ctx->field_seen_value) {
 		/* duplicate */
+		if (cache_field->type == MAIL_CACHE_FIELD_BITMASK) {
+			mail_cache_merge_bitmask(view->cache, ctx->buffer,
+						 field, data, data_size);
+		}
 		return 1;
 	}
 	*field_seen = ctx->field_seen_value;
 
-	field = view->cache->file_field_map[file_field];
-	dec = view->cache->fields[field].field.decision &
-		~MAIL_CACHE_DECISION_FORCED;
+	dec = cache_field->decision & ~MAIL_CACHE_DECISION_FORCED;
 	if (ctx->new_msg) {
 		if (dec == MAIL_CACHE_DECISION_NO)
 			return 1;
@@ -44,7 +85,7 @@
 
 	buffer_append(ctx->buffer, &file_field, sizeof(file_field));
 
-	if (view->cache->fields[field].field.field_size == (unsigned int)-1) {
+	if (cache_field->field_size == (unsigned int)-1) {
 		size32 = (uint32_t)data_size;
 		buffer_append(ctx->buffer, &size32, sizeof(size32));
 	}

Index: mail-cache-lookup.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-lookup.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- mail-cache-lookup.c	15 Aug 2004 02:50:29 -0000	1.17
+++ mail-cache-lookup.c	4 Sep 2004 10:26:36 -0000	1.18
@@ -73,7 +73,8 @@
 		       mail_cache_foreach_callback_t *callback, void *context)
 {
 	struct mail_cache *cache = view->cache;
-	size_t pos, next_pos, max_size, data_size;
+	size_t pos, next_pos, max_size;
+	unsigned int data_size;
 	uint32_t file_field;
 	unsigned int field;
 	int ret;
@@ -204,6 +205,7 @@
 	uint32_t file_field;
 	size_t size;
 
+	i_assert(seq > 0);
 	i_assert(field < view->cache->fields_count);
 
 	file_field = view->cache->field_file_map[field];
@@ -231,6 +233,7 @@
 struct mail_cache_lookup_context {
 	buffer_t *dest_buf;
 	uint32_t file_field;
+	int found;
 };
 
 static int
@@ -244,13 +247,35 @@
 		return 1;
 
 	buffer_append(ctx->dest_buf, data, data_size);
+	ctx->found = TRUE;
 	return 0;
 }
 
+static int
+mail_cache_lookup_bitmask_callback(struct mail_cache_view *view __attr_unused__,
+				   uint32_t file_field, const void *data,
+				   size_t data_size, void *context)
+{
+        struct mail_cache_lookup_context *ctx = context;
+	unsigned char *dest;
+	size_t i;
+
+	if (ctx->file_field != file_field)
+		return 1;
+
+	/* merge all bits */
+	dest = buffer_get_space_unsafe(ctx->dest_buf, 0, data_size);
+	for (i = 0; i < data_size; i++)
+		dest[i] |= ((const unsigned char *)data)[i];
+	ctx->found = TRUE;
+	return 1;
+}
+
 int mail_cache_lookup_field(struct mail_cache_view *view, buffer_t *dest_buf,
 			    uint32_t seq, unsigned int field)
 {
 	struct mail_cache_lookup_context ctx;
+	unsigned int data_size;
 	int ret;
 
 	if ((ret = mail_cache_field_exists(view, seq, field)) <= 0)
@@ -261,8 +286,21 @@
 	/* should exist. find it. */
 	ctx.file_field = view->cache->field_file_map[field];
 	ctx.dest_buf = dest_buf;
-	return mail_cache_foreach(view, seq, mail_cache_lookup_callback,
-				  &ctx) == 0;
+	ctx.found = FALSE;
+	if (view->cache->fields[field].field.type != MAIL_CACHE_FIELD_BITMASK) {
+		ret = mail_cache_foreach(view, seq, mail_cache_lookup_callback,
+					 &ctx);
+	} else {
+		/* make sure we're cleared first */
+		data_size = view->cache->fields[field].field.field_size;
+		memset(buffer_get_space_unsafe(dest_buf, 0, data_size),
+		       0, data_size);
+
+		ret = mail_cache_foreach(view, seq,
+					 mail_cache_lookup_bitmask_callback,
+					 &ctx);
+	}
+	return ret < 0 ? -1 : ctx.found;
 }
 
 struct header_lookup_data_rec {



More information about the dovecot-cvs mailing list