Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-index/mail-cache-fields.c @ 2342:fa529dd77176 HEAD
Fixes for big endian systems.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 20 Jul 2004 20:52:38 +0300 |
parents | 406692edc12d |
children | f2acbe281ac1 |
rev | line source |
---|---|
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
1 /* Copyright (C) 2004 Timo Sirainen */ |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #include "lib.h" |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 #include "buffer.h" |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 #include "hash.h" |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
6 #include "write-full.h" |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 #include "mail-cache-private.h" |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 #include <stddef.h> |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 #define CACHE_HDR_PREFETCH 1024 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 static const unsigned char *null4[] = { 0, 0, 0, 0 }; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 void mail_cache_register_fields(struct mail_cache *cache, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 struct mail_cache_field *fields, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 size_t fields_count) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 void *orig_key, *orig_value; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 unsigned int new_idx; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 size_t i; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 new_idx = cache->fields_count; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 for (i = 0; i < fields_count; i++) { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 if (hash_lookup_full(cache->field_name_hash, fields[i].name, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 &orig_key, &orig_value)) { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 fields[i].idx = |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 POINTER_CAST_TO(orig_value, unsigned int); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
29 continue; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
30 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
31 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
32 fields[i].idx = new_idx++; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
33 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
34 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
35 if (new_idx == cache->fields_count) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 return; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
37 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 /* @UNSAFE */ |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 cache->fields = p_realloc(cache->field_pool, cache->fields, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 cache->fields_count * sizeof(*cache->fields), |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 new_idx * sizeof(*cache->fields)); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
42 cache->field_file_map = |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
43 p_realloc(cache->field_pool, cache->field_file_map, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 cache->fields_count * sizeof(*cache->field_file_map), |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 new_idx * sizeof(*cache->field_file_map)); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 for (i = 0; i < fields_count; i++) { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
48 unsigned int idx = fields[i].idx; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
49 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
50 if (idx < cache->fields_count) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
51 continue; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
52 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
53 /* new index - save it */ |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
54 cache->fields[idx].field = fields[i]; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
55 cache->fields[idx].field.name = |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 p_strdup(cache->field_pool, fields[i].name); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
57 cache->field_file_map[idx] = (uint32_t)-1; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
59 switch (cache->fields[idx].field.type) { |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
60 case MAIL_CACHE_FIELD_FIXED_SIZE: |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 case MAIL_CACHE_FIELD_BITMASK: |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
62 break; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
63 case MAIL_CACHE_FIELD_VARIABLE_SIZE: |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
64 case MAIL_CACHE_FIELD_STRING: |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 case MAIL_CACHE_FIELD_HEADER: |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
66 cache->fields[idx].field.field_size = (unsigned int)-1; |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
67 break; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
70 hash_insert(cache->field_name_hash, |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
71 (char *)cache->fields[idx].field.name, |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
72 POINTER_CAST(idx)); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
73 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 cache->fields_count = new_idx; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
76 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
77 unsigned int |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
78 mail_cache_register_lookup(struct mail_cache *cache, const char *name) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
79 { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
80 void *orig_key, *orig_value; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
81 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 if (hash_lookup_full(cache->field_name_hash, name, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
83 &orig_key, &orig_value)) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
84 return POINTER_CAST_TO(orig_value, unsigned int); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
85 else |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 return (unsigned int)-1; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 static int mail_cache_header_fields_get_offset(struct mail_cache *cache, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 uint32_t *offset_r) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 const struct mail_cache_header_fields *field_hdr; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 uint32_t offset, next_offset; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 if (MAIL_CACHE_IS_UNUSABLE(cache)) { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 *offset_r = 0; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 return 0; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
98 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
99 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
100 /* find the latest header */ |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
101 offset = 0; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 next_offset = |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
103 mail_cache_offset_to_uint32(cache->hdr->field_header_offset); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
104 while (next_offset != 0) { |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
105 if (next_offset == offset) { |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
106 mail_cache_set_corrupted(cache, |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
107 "next_offset in field header loops"); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
108 return -1; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
109 } |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 offset = next_offset; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 if (mail_cache_map(cache, offset, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 sizeof(*field_hdr) + CACHE_HDR_PREFETCH) < 0) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 return -1; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
115 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
116 field_hdr = CONST_PTR_OFFSET(cache->mmap_base, offset); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
117 next_offset = |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
118 mail_cache_offset_to_uint32(field_hdr->next_offset); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
119 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
120 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
121 *offset_r = offset; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
122 return 0; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
123 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
124 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
125 int mail_cache_header_fields_read(struct mail_cache *cache) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
126 { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
127 const struct mail_cache_header_fields *field_hdr = NULL; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
128 struct mail_cache_field field; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
129 const uint32_t *last_used, *sizes; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
130 const uint8_t *types, *decisions; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
131 const char *p, *names, *end; |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
132 void *orig_key, *orig_value; |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
133 uint32_t offset, i; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
134 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
135 if (mail_cache_header_fields_get_offset(cache, &offset) < 0) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
136 return -1; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
137 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
138 if (offset == 0) { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
139 /* no fields - the file is empty */ |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
140 return 0; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
141 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
142 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
143 field_hdr = CONST_PTR_OFFSET(cache->mmap_base, offset); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
144 if (offset + field_hdr->size > cache->mmap_length) { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
145 mail_cache_set_corrupted(cache, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
146 "field header points outside file"); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
147 return -1; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
148 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
149 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
150 /* check the fixed size of the header. name[] has to be checked |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
151 separately */ |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
152 if (field_hdr->size < sizeof(*field_hdr) + |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
153 field_hdr->fields_count * (sizeof(uint32_t)*2 + 1 + 2)) { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
154 mail_cache_set_corrupted(cache, "invalid field header size"); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
155 return -1; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
156 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
157 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
158 if (field_hdr->size > sizeof(*field_hdr) + CACHE_HDR_PREFETCH) { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
159 if (mail_cache_map(cache, offset, field_hdr->size) < 0) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
160 return -1; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
161 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
162 field_hdr = CONST_PTR_OFFSET(cache->mmap_base, offset); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
163 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
164 cache->file_field_map = |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
165 i_realloc(cache->file_field_map, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
166 cache->file_fields_count * sizeof(unsigned int), |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
167 field_hdr->fields_count * sizeof(unsigned int)); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
168 cache->file_fields_count = field_hdr->fields_count; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
169 |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
170 last_used = CONST_PTR_OFFSET(field_hdr, MAIL_CACHE_FIELD_LAST_USED()); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
171 sizes = CONST_PTR_OFFSET(field_hdr, |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
172 MAIL_CACHE_FIELD_SIZE(field_hdr->fields_count)); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
173 types = CONST_PTR_OFFSET(field_hdr, |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
174 MAIL_CACHE_FIELD_TYPE(field_hdr->fields_count)); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
175 decisions = CONST_PTR_OFFSET(field_hdr, |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
176 MAIL_CACHE_FIELD_DECISION(field_hdr->fields_count)); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
177 names = CONST_PTR_OFFSET(field_hdr, |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
178 MAIL_CACHE_FIELD_NAMES(field_hdr->fields_count)); |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
179 end = CONST_PTR_OFFSET(field_hdr, field_hdr->size); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
180 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
181 /* clear the old mapping */ |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
182 for (i = 0; i < cache->fields_count; i++) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
183 cache->field_file_map[i] = (uint32_t)-1; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
184 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
185 memset(&field, 0, sizeof(field)); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
186 for (i = 0; i < field_hdr->fields_count; i++) { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
187 for (p = names; p != end && *p != '\0'; p++) ; |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
188 if (p == end || *names == '\0') { |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
189 mail_cache_set_corrupted(cache, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
190 "field header names corrupted"); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
191 return -1; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
192 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
193 |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
194 if (hash_lookup_full(cache->field_name_hash, names, |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
195 &orig_key, &orig_value)) { |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
196 /* already exists, see if decision can be updated */ |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
197 field.idx = POINTER_CAST_TO(orig_value, unsigned int); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
198 if (!cache->fields[field.idx].decision_dirty) { |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
199 cache->fields[field.idx].field.decision = |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
200 decisions[i]; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
201 } |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
202 if (cache->fields[field.idx].field.type != types[i]) { |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
203 mail_cache_set_corrupted(cache, |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
204 "registered field type changed"); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
205 return -1; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
206 } |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
207 } else { |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
208 field.name = names; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
209 field.type = types[i]; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
210 field.field_size = sizes[i]; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
211 field.decision = decisions[i]; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
212 mail_cache_register_fields(cache, &field, 1); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
213 } |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
214 cache->field_file_map[field.idx] = i; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
215 cache->file_field_map[i] = field.idx; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
216 |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
217 /* update last_used if it's newer than ours */ |
2342 | 218 if (last_used[i] > cache->fields[field.idx].last_used) |
219 cache->fields[field.idx].last_used = last_used[i]; | |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
220 |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
221 names = p + 1; |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
222 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
223 return 0; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
224 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
225 |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
226 static void copy_to_buf(struct mail_cache *cache, buffer_t *dest, |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
227 size_t offset, size_t size) |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
228 { |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
229 const void *data; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
230 unsigned int i, field; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
231 |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
232 for (i = 0; i < cache->file_fields_count; i++) { |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
233 field = cache->file_field_map[i]; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
234 data = CONST_PTR_OFFSET(&cache->fields[field], offset); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
235 buffer_append(dest, data, size); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
236 } |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
237 for (i = 0; i < cache->fields_count; i++) { |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
238 if (cache->field_file_map[i] != (uint32_t)-1) |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
239 continue; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
240 data = CONST_PTR_OFFSET(&cache->fields[i], offset); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
241 buffer_append(dest, data, size); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
242 } |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
243 } |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
244 |
2342 | 245 static void copy_to_buf_byte(struct mail_cache *cache, buffer_t *dest, |
246 size_t offset) | |
247 { | |
248 const int *data; | |
249 unsigned int i, field; | |
250 uint8_t byte; | |
251 | |
252 for (i = 0; i < cache->file_fields_count; i++) { | |
253 field = cache->file_field_map[i]; | |
254 data = CONST_PTR_OFFSET(&cache->fields[field], offset); | |
255 byte = (uint8_t)*data; | |
256 buffer_append(dest, &byte, 1); | |
257 } | |
258 for (i = 0; i < cache->fields_count; i++) { | |
259 if (cache->field_file_map[i] != (uint32_t)-1) | |
260 continue; | |
261 data = CONST_PTR_OFFSET(&cache->fields[i], offset); | |
262 byte = (uint8_t)*data; | |
263 buffer_append(dest, &byte, 1); | |
264 } | |
265 } | |
266 | |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
267 int mail_cache_header_fields_update(struct mail_cache *cache) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
268 { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
269 int locked = cache->locked; |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
270 buffer_t *buffer; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
271 uint32_t i, offset; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
272 int ret = 0; |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
273 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
274 if (!locked) { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
275 if (mail_cache_lock(cache) <= 0) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
276 return -1; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
277 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
278 |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
279 if (mail_cache_header_fields_read(cache) < 0 || |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
280 mail_cache_header_fields_get_offset(cache, &offset) < 0) { |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
281 mail_cache_unlock(cache); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
282 return -1; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
283 } |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
284 |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
285 t_push(); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
286 buffer = buffer_create_dynamic(pool_datastack_create(), |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
287 256, (size_t)-1); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
288 |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
289 copy_to_buf(cache, buffer, |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
290 offsetof(struct mail_cache_field_private, last_used), |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
291 sizeof(uint32_t)); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
292 ret = pwrite_full(cache->fd, buffer_get_data(buffer, NULL), |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
293 sizeof(uint32_t) * cache->file_fields_count, |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
294 offset + MAIL_CACHE_FIELD_LAST_USED()); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
295 if (ret == 0) { |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
296 buffer_set_used_size(buffer, 0); |
2342 | 297 copy_to_buf_byte(cache, buffer, |
298 offsetof(struct mail_cache_field, decision)); | |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
299 |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
300 ret = pwrite_full(cache->fd, buffer_get_data(buffer, NULL), |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
301 sizeof(uint8_t) * cache->file_fields_count, offset + |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
302 MAIL_CACHE_FIELD_DECISION(cache->file_fields_count)); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
303 |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
304 if (ret == 0) { |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
305 for (i = 0; i < cache->fields_count; i++) |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
306 cache->fields[i].decision_dirty = FALSE; |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
307 } |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
308 } |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
309 t_pop(); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
310 |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
311 if (ret == 0) |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
312 cache->field_header_write_pending = FALSE; |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
313 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
314 if (!locked) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
315 mail_cache_unlock(cache); |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
316 return ret; |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
317 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
318 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
319 void mail_cache_header_fields_get(struct mail_cache *cache, buffer_t *dest) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
320 { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
321 struct mail_cache_header_fields hdr; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
322 unsigned int field; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
323 const char *name; |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
324 uint32_t i; |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
325 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
326 memset(&hdr, 0, sizeof(hdr)); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
327 hdr.fields_count = cache->fields_count; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
328 buffer_append(dest, &hdr, sizeof(hdr)); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
329 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
330 /* we have to keep the field order for the existing fields. */ |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
331 copy_to_buf(cache, dest, |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
332 offsetof(struct mail_cache_field_private, last_used), |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
333 sizeof(uint32_t)); |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
334 copy_to_buf(cache, dest, offsetof(struct mail_cache_field, field_size), |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
335 sizeof(uint32_t)); |
2342 | 336 copy_to_buf_byte(cache, dest, offsetof(struct mail_cache_field, type)); |
337 copy_to_buf_byte(cache, dest, | |
338 offsetof(struct mail_cache_field, decision)); | |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
339 |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
340 i_assert(buffer_get_used_size(dest) == sizeof(hdr) + |
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
341 (sizeof(uint32_t)*2 + 2) * hdr.fields_count); |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
342 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
343 for (i = 0; i < cache->file_fields_count; i++) { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
344 field = cache->file_field_map[i]; |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
345 name = cache->fields[field].field.name; |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
346 buffer_append(dest, name, strlen(name)+1); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
347 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
348 for (i = 0; i < cache->fields_count; i++) { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
349 if (cache->field_file_map[i] != (uint32_t)-1) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
350 continue; |
2339
406692edc12d
Cache fixes. Decisions are saved again.
Timo Sirainen <tss@iki.fi>
parents:
2327
diff
changeset
|
351 name = cache->fields[i].field.name; |
2327
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
352 buffer_append(dest, name, strlen(name)+1); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
353 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
354 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
355 hdr.size = buffer_get_used_size(dest); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
356 buffer_write(dest, 0, &hdr, sizeof(hdr)); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
357 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
358 if ((hdr.size & 3) != 0) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
359 buffer_append(dest, null4, 4 - (hdr.size & 3)); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
360 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
361 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
362 int mail_cache_header_fields_get_next_offset(struct mail_cache *cache, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
363 uint32_t *offset_r) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
364 { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
365 if (mail_cache_header_fields_get_offset(cache, offset_r) < 0) |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
366 return -1; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
367 |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
368 if (*offset_r == 0) { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
369 *offset_r = offsetof(struct mail_cache_header, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
370 field_header_offset); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
371 } else { |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
372 *offset_r += offsetof(struct mail_cache_header_fields, |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
373 next_offset); |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
374 } |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
375 return 0; |
7d02e2a7672d
Header caching redesigned. New design allows caching decisions per field, so
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
376 } |