amd: bugfixes; speed up expunging.
* libmailutils/base/amd.c (_amd_message_delete): Remove. (amd_array_expand): Fix element size. (amd_array_shrink): Rewrite. (amd_expunge): Shrink the array once, after everything has been expunged. Generate MU_EVT_MAILBOX_MESSAGE_EXPUNGE for each expunged message.
Showing
1 changed file
with
48 additions
and
54 deletions
... | @@ -100,8 +100,6 @@ static int amd_get_attr_flags (mu_attribute_t attr, int *pflags); | ... | @@ -100,8 +100,6 @@ static int amd_get_attr_flags (mu_attribute_t attr, int *pflags); |
100 | static int amd_set_attr_flags (mu_attribute_t attr, int flags); | 100 | static int amd_set_attr_flags (mu_attribute_t attr, int flags); |
101 | static int amd_unset_attr_flags (mu_attribute_t attr, int flags); | 101 | static int amd_unset_attr_flags (mu_attribute_t attr, int flags); |
102 | 102 | ||
103 | static void _amd_message_delete (struct _amd_data *amd, | ||
104 | struct _amd_message *msg); | ||
105 | static int amd_pool_open (struct _amd_message *mhm); | 103 | static int amd_pool_open (struct _amd_message *mhm); |
106 | static int amd_pool_open_count (struct _amd_data *amd); | 104 | static int amd_pool_open_count (struct _amd_data *amd); |
107 | static void amd_pool_flush (struct _amd_data *amd); | 105 | static void amd_pool_flush (struct _amd_data *amd); |
... | @@ -233,7 +231,7 @@ amd_array_expand (struct _amd_data *amd, size_t index) | ... | @@ -233,7 +231,7 @@ amd_array_expand (struct _amd_data *amd, size_t index) |
233 | struct _amd_message **p; | 231 | struct _amd_message **p; |
234 | 232 | ||
235 | amd->msg_max += AMD_MSG_INC; /* FIXME: configurable? */ | 233 | amd->msg_max += AMD_MSG_INC; /* FIXME: configurable? */ |
236 | p = realloc (amd->msg_array, amd->msg_max * amd->msg_size); | 234 | p = realloc (amd->msg_array, amd->msg_max * sizeof (amd->msg_array[0])); |
237 | if (!p) | 235 | if (!p) |
238 | { | 236 | { |
239 | amd->msg_max -= AMD_MSG_INC; | 237 | amd->msg_max -= AMD_MSG_INC; |
... | @@ -243,20 +241,21 @@ amd_array_expand (struct _amd_data *amd, size_t index) | ... | @@ -243,20 +241,21 @@ amd_array_expand (struct _amd_data *amd, size_t index) |
243 | } | 241 | } |
244 | if (amd->msg_count > index) | 242 | if (amd->msg_count > index) |
245 | memmove (&amd->msg_array[index+1], &amd->msg_array[index], | 243 | memmove (&amd->msg_array[index+1], &amd->msg_array[index], |
246 | (amd->msg_count-index) * amd->msg_size); | 244 | (amd->msg_count-index) * sizeof (amd->msg_array[0])); |
247 | amd->msg_count++; | 245 | amd->msg_count++; |
248 | return 0; | 246 | return 0; |
249 | } | 247 | } |
250 | 248 | ||
251 | /* Shrink the message array by removing element at INDEX-1 and | 249 | /* Shrink the message array by removing element at INDEX-COUNT and |
252 | shifting left by one position all the elements on the right of | 250 | shifting left by COUNT positions all the elements on the right of |
253 | it. */ | 251 | it. */ |
254 | int | 252 | int |
255 | amd_array_shrink (struct _amd_data *amd, size_t index) | 253 | amd_array_shrink (struct _amd_data *amd, size_t index, size_t count) |
256 | { | 254 | { |
257 | memmove (&amd->msg_array[index-1], &amd->msg_array[index], | 255 | if (amd->msg_count-index-1 && index < amd->msg_count) |
258 | (amd->msg_count-index) * amd->msg_size); | 256 | memmove (&amd->msg_array[index-count+1], &amd->msg_array[index + 1], |
259 | amd->msg_count--; | 257 | (amd->msg_count-index-1) * sizeof (amd->msg_array[0])); |
258 | amd->msg_count -= count; | ||
260 | return 0; | 259 | return 0; |
261 | } | 260 | } |
262 | 261 | ||
... | @@ -1150,6 +1149,7 @@ amd_expunge (mu_mailbox_t mailbox) | ... | @@ -1150,6 +1149,7 @@ amd_expunge (mu_mailbox_t mailbox) |
1150 | size_t i; | 1149 | size_t i; |
1151 | int updated = amd->has_new_msg; | 1150 | int updated = amd->has_new_msg; |
1152 | size_t expcount = 0; | 1151 | size_t expcount = 0; |
1152 | size_t last_expunged = 0; | ||
1153 | 1153 | ||
1154 | if (amd == NULL) | 1154 | if (amd == NULL) |
1155 | return EINVAL; | 1155 | return EINVAL; |
... | @@ -1157,35 +1157,20 @@ amd_expunge (mu_mailbox_t mailbox) | ... | @@ -1157,35 +1157,20 @@ amd_expunge (mu_mailbox_t mailbox) |
1157 | if (amd->msg_count == 0) | 1157 | if (amd->msg_count == 0) |
1158 | return 0; | 1158 | return 0; |
1159 | 1159 | ||
1160 | /* Find the first dirty(modified) message. */ | ||
1161 | for (i = 0; i < amd->msg_count; i++) | 1160 | for (i = 0; i < amd->msg_count; i++) |
1162 | { | 1161 | { |
1163 | mhm = amd->msg_array[i]; | 1162 | mhm = amd->msg_array[i]; |
1164 | if ((mhm->attr_flags & MU_ATTRIBUTE_MODIFIED) || | ||
1165 | (mhm->attr_flags & MU_ATTRIBUTE_DELETED) || | ||
1166 | (mhm->message && mu_message_is_modified (mhm->message))) | ||
1167 | break; | ||
1168 | } | ||
1169 | |||
1170 | while (i < amd->msg_count) | ||
1171 | { | ||
1172 | mhm = amd->msg_array[i]; | ||
1173 | 1163 | ||
1174 | if (mhm->attr_flags & MU_ATTRIBUTE_DELETED) | 1164 | if (mhm->attr_flags & MU_ATTRIBUTE_DELETED) |
1175 | { | 1165 | { |
1176 | int rc; | 1166 | int rc; |
1167 | struct _amd_message **pp; | ||
1177 | 1168 | ||
1178 | if (amd->delete_msg) | 1169 | if (amd->delete_msg) |
1179 | { | 1170 | { |
1180 | size_t expevt[2] = { i + 1, expcount }; | ||
1181 | rc = amd->delete_msg (amd, mhm); | 1171 | rc = amd->delete_msg (amd, mhm); |
1182 | if (rc) | 1172 | if (rc) |
1183 | return rc; | 1173 | return rc; |
1184 | |||
1185 | mu_observable_notify (mailbox->observable, | ||
1186 | MU_EVT_MAILBOX_MESSAGE_EXPUNGE, | ||
1187 | expevt); | ||
1188 | ++expcount; | ||
1189 | } | 1174 | } |
1190 | else | 1175 | else |
1191 | { | 1176 | { |
... | @@ -1220,9 +1205,25 @@ amd_expunge (mu_mailbox_t mailbox) | ... | @@ -1220,9 +1205,25 @@ amd_expunge (mu_mailbox_t mailbox) |
1220 | free (old_name); | 1205 | free (old_name); |
1221 | free (new_name); | 1206 | free (new_name); |
1222 | } | 1207 | } |
1223 | _amd_message_delete (amd, mhm); | 1208 | |
1209 | pp = amd_pool_lookup (mhm); | ||
1210 | if (pp) | ||
1211 | *pp = NULL; | ||
1212 | mu_message_destroy (&mhm->message, mhm); | ||
1213 | if (amd->msg_free) | ||
1214 | amd->msg_free (mhm); | ||
1215 | free (mhm); | ||
1216 | amd->msg_array[i] = NULL; | ||
1217 | last_expunged = i; | ||
1224 | updated = 1; | 1218 | updated = 1; |
1225 | /* Do not increase i! */ | 1219 | |
1220 | { | ||
1221 | size_t expevt[2] = { i + 1, expcount }; | ||
1222 | mu_observable_notify (mailbox->observable, | ||
1223 | MU_EVT_MAILBOX_MESSAGE_EXPUNGE, | ||
1224 | expevt); | ||
1225 | ++expcount; | ||
1226 | } | ||
1226 | } | 1227 | } |
1227 | else | 1228 | else |
1228 | { | 1229 | { |
... | @@ -1233,10 +1234,28 @@ amd_expunge (mu_mailbox_t mailbox) | ... | @@ -1233,10 +1234,28 @@ amd_expunge (mu_mailbox_t mailbox) |
1233 | _amd_message_save (amd, mhm, 1); | 1234 | _amd_message_save (amd, mhm, 1); |
1234 | updated = 1; | 1235 | updated = 1; |
1235 | } | 1236 | } |
1236 | i++; /* Move to the next message */ | ||
1237 | } | 1237 | } |
1238 | } | 1238 | } |
1239 | 1239 | ||
1240 | if (expcount) | ||
1241 | { | ||
1242 | last_expunged++; | ||
1243 | do | ||
1244 | { | ||
1245 | size_t j; | ||
1246 | |||
1247 | for (j = 1; j < last_expunged && !amd->msg_array[last_expunged-j-1]; | ||
1248 | j++) | ||
1249 | ; | ||
1250 | amd_array_shrink (amd, last_expunged - 1, j); | ||
1251 | for (last_expunged -= j; | ||
1252 | last_expunged > 0 && amd->msg_array[last_expunged - 1]; | ||
1253 | last_expunged--) | ||
1254 | ; | ||
1255 | } | ||
1256 | while (last_expunged); | ||
1257 | } | ||
1258 | |||
1240 | if (updated && !amd->mailbox_size) | 1259 | if (updated && !amd->mailbox_size) |
1241 | { | 1260 | { |
1242 | mu_off_t size = 0; | 1261 | mu_off_t size = 0; |
... | @@ -1419,31 +1438,6 @@ amd_sort (struct _amd_data *amd) | ... | @@ -1419,31 +1438,6 @@ amd_sort (struct _amd_data *amd) |
1419 | msg_array_comp); | 1438 | msg_array_comp); |
1420 | } | 1439 | } |
1421 | 1440 | ||
1422 | static void | ||
1423 | _amd_message_delete (struct _amd_data *amd, struct _amd_message *msg) | ||
1424 | { | ||
1425 | size_t index; | ||
1426 | struct _amd_message **pp; | ||
1427 | |||
1428 | if (amd_msg_lookup (amd, msg, &index)) | ||
1429 | { | ||
1430 | /* FIXME: Not found? */ | ||
1431 | return; | ||
1432 | } | ||
1433 | |||
1434 | msg = _amd_get_message (amd, index); | ||
1435 | |||
1436 | pp = amd_pool_lookup (msg); | ||
1437 | if (pp) | ||
1438 | *pp = NULL; | ||
1439 | |||
1440 | mu_message_destroy (&msg->message, msg); | ||
1441 | if (amd->msg_free) | ||
1442 | amd->msg_free (msg); | ||
1443 | free (msg); | ||
1444 | amd_array_shrink (amd, index); | ||
1445 | } | ||
1446 | |||
1447 | /* Scan given message and fill amd_message_t fields. | 1441 | /* Scan given message and fill amd_message_t fields. |
1448 | NOTE: the function assumes mhm->stream != NULL. */ | 1442 | NOTE: the function assumes mhm->stream != NULL. */ |
1449 | static int | 1443 | static int | ... | ... |
-
Please register or sign in to post a comment