CtdlDeleteMessages() now has a bulk API. Updated all of the
authorArt Cancro <ajc@citadel.org>
Fri, 28 Jul 2006 03:30:57 +0000 (03:30 +0000)
committerArt Cancro <ajc@citadel.org>
Fri, 28 Jul 2006 03:30:57 +0000 (03:30 +0000)
callers to use it.  Also updated the IMAP and POP3 expunge functions to actually
make use of the bulk delete.  This should significantly improve performance
when used with large folders.

citadel/msgbase.c
citadel/msgbase.h
citadel/room_ops.c
citadel/serv_calendar.c
citadel/serv_expire.c
citadel/serv_imap.c
citadel/serv_network.c
citadel/serv_pop3.c
citadel/serv_smtp.c
citadel/serv_vcard.c

index 3934cd290b29789e5240b099839334a2586c1c91..a95ecd450ff8c4807de54f61dd76eb8541076d96 100644 (file)
@@ -2165,7 +2165,7 @@ void ReplicationChecks(struct CtdlMessage *msg) {
        old_msgnum = locate_message_by_euid(msg->cm_fields['E'], &CC->room);
        if (old_msgnum > 0L) {
                lprintf(CTDL_DEBUG, "ReplicationChecks() replacing message %ld\n", old_msgnum);
-               CtdlDeleteMessages(CC->room.QRname, old_msgnum, "", 0);
+               CtdlDeleteMessages(CC->room.QRname, &old_msgnum, 1, "", 0);
        }
 }
 
@@ -3295,7 +3295,8 @@ void cmd_ent0(char *entargs)
  * (returns the actual number of messages deleted)
  */
 int CtdlDeleteMessages(char *room_name,                /* which room */
-                       long dmsgnum,           /* or "0" for any */
+                       long *dmsgnums,         /* array of msg numbers to be deleted */
+                       int num_dmsgnums,       /* number of msgs to be deleted, or 0 for "any" */
                        char *content_type,     /* or "" for any */
                        int deferred            /* let TDAP sweep it later */
 )
@@ -3306,13 +3307,13 @@ int CtdlDeleteMessages(char *room_name,         /* which room */
        long *msglist = NULL;
        long *dellist = NULL;
        int num_msgs = 0;
-       int i;
+       int i, j;
        int num_deleted = 0;
        int delete_this;
        struct MetaData smi;
 
-       lprintf(CTDL_DEBUG, "CtdlDeleteMessages(%s, %ld, %s, %d)\n",
-               room_name, dmsgnum, content_type, deferred);
+       lprintf(CTDL_DEBUG, "CtdlDeleteMessages(%s, %d msgs, %s, %d)\n",
+               room_name, num_dmsgnums, content_type, deferred);
 
        /* get room record, obtaining a lock... */
        if (lgetroom(&qrbuf, room_name) != 0) {
@@ -3335,9 +3336,20 @@ int CtdlDeleteMessages(char *room_name,          /* which room */
 
                        /* Set/clear a bit for each criterion */
 
-                       if ((dmsgnum == 0L) || (msglist[i] == dmsgnum)) {
+                       /* 0 messages in the list or a null list means that we are
+                        * interested in deleting any messages which meet the other criteria.
+                        */
+                       if ((num_dmsgnums == 0) || (dmsgnums == NULL)) {
                                delete_this |= 0x01;
                        }
+                       else {
+                               for (j=0; j<num_dmsgnums; ++j) {
+                                       if (msglist[i] == dmsgnums[j]) {
+                                               delete_this |= 0x01;
+                                       }
+                               }
+                       }
+
                        if (strlen(content_type) == 0) {
                                delete_this |= 0x02;
                        } else {
@@ -3431,7 +3443,7 @@ void cmd_dele(char *delstr)
        }
        delnum = extract_long(delstr, 0);
 
-       num_deleted = CtdlDeleteMessages(CC->room.QRname, delnum, "", 1);
+       num_deleted = CtdlDeleteMessages(CC->room.QRname, &delnum, 1, "", 1);
 
        if (num_deleted) {
                cprintf("%d %d message%s deleted.\n", CIT_OK,
@@ -3532,7 +3544,7 @@ void cmd_move(char *args)
         * if this is a 'move' rather than a 'copy' operation.
         */
        if (is_copy == 0) {
-               CtdlDeleteMessages(CC->room.QRname, num, "", 0);
+               CtdlDeleteMessages(CC->room.QRname, &num, 1, "", 0);
        }
 
        cprintf("%d Message %s.\n", CIT_OK, (is_copy ? "copied" : "moved") );
@@ -3742,7 +3754,7 @@ void CtdlWriteObject(char *req_room,              /* Room to stuff it in */
         */
        if (is_unique) {
                lprintf(CTDL_DEBUG, "Deleted %d other msgs of this type\n",
-                       CtdlDeleteMessages(roomname, 0L, content_type, 0)
+                       CtdlDeleteMessages(roomname, NULL, 0, content_type, 0)
                );
        }
        /* Now write the data */
index 4282a75e40baf0af33858a130a8ad60ceca49a99..49571ba7b9208e2148e8d6124368120756b9a33e 100644 (file)
@@ -104,7 +104,7 @@ int CtdlForEachMessage(int mode, long ref,
                        struct CtdlMessage *compare,
                         void (*CallBack) (long, void *),
                        void *userdata);
-int CtdlDeleteMessages(char *, long, char *, int);
+int CtdlDeleteMessages(char *, long *, int, char *, int);
 void CtdlWriteObject(char *, char *, char *, struct ctdluser *,
                        int, int, unsigned int);
 struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body);
index 9386c7d0d2fe4d2f2fdc27f6e319b03f4fa76eec..17dd4ff9ebf7aca9caa01efabe133e4da22204dd 100644 (file)
@@ -1607,7 +1607,7 @@ void delete_room(struct ctdlroom *qrbuf)
        /* Delete the messages in the room
         * (Careful: this opens an S_ROOMS critical section!)
         */
-       CtdlDeleteMessages(qrbuf->QRname, 0L, "", 0);
+       CtdlDeleteMessages(qrbuf->QRname, NULL, 0, "", 0);
 
        /* Flag the room record as not in use */
        lgetroom(qrbuf, qrbuf->QRname);
index 56d8294b17feecf67f05b2121d5d014559956912..596271cc95e3e1cfb181acbf06bf621b555ff656 100644 (file)
@@ -430,7 +430,7 @@ void ical_respond(long msgnum, char *partnum, char *action) {
                /* Now that we've processed this message, we don't need it
                 * anymore.  So delete it.
                 */
-               CtdlDeleteMessages(CC->room.QRname, msgnum, "", 1);
+               CtdlDeleteMessages(CC->room.QRname, &msgnum, 1, "", 1);
 
                /* Free the memory we allocated and return a response. */
                icalcomponent_free(ird.cal);
@@ -777,7 +777,7 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) {
                /* Now that we've processed this message, we don't need it
                 * anymore.  So delete it.  (Maybe make this optional?)
                 */
-               CtdlDeleteMessages(CC->room.QRname, msgnum, "", 1);
+               CtdlDeleteMessages(CC->room.QRname, &msgnum, 1, "", 1);
 
                /* Free the memory we allocated and return a response. */
                icalcomponent_free(ird.cal);
@@ -1473,7 +1473,7 @@ void ical_putics(void)
         * the entire calendar with an entire new (or updated) calendar.
         * (Careful: this opens an S_ROOMS critical section!)
         */
-       CtdlDeleteMessages(CC->room.QRname, 0L, "", 0);
+       CtdlDeleteMessages(CC->room.QRname, NULL, 0, "", 0);
 
        /* If the top-level component is *not* a VCALENDAR, we can drop it right
         * in.  This will almost never happen.
index 5b6fda96abab792500278b7251387f1ac63f1ab5..28b0968de4a6591faa26aed310af74196c865ac8 100644 (file)
@@ -212,7 +212,7 @@ void DoPurgeMessages(FILE *purgelist) {
                if (!strncasecmp(buf, "m=", 2)) {
                        msgnum = atol(&buf[2]);
                        if (msgnum > 0L) {
-                               CtdlDeleteMessages(roomname, msgnum, "", 0);
+                               CtdlDeleteMessages(roomname, &msgnum, 1, "", 0);
                        }
                }
        }
index f8edbb8e3aa7ba4cc7f660e591b101608e04b571..fd64162af26a53ea7370303c1ae1f09a8ca79263 100644 (file)
@@ -706,26 +706,30 @@ void imap_select(int num_parms, char *parms[])
 
 /*
  * Does the real work for expunge.
- * FIXME do this with the new bulk API
  */
 int imap_do_expunge(void)
 {
        int i;
        int num_expunged = 0;
+       long *delmsgs = NULL;
+       int num_delmsgs = 0;
 
        lprintf(CTDL_DEBUG, "imap_do_expunge() called\n");
        if (IMAP->selected == 0) {
                return (0);
        }
 
-       if (IMAP->num_msgs > 0)
+       if (IMAP->num_msgs > 0) {
+               delmsgs = malloc(IMAP->num_msgs * sizeof(long));
                for (i = 0; i < IMAP->num_msgs; ++i) {
                        if (IMAP->flags[i] & IMAP_DELETED) {
-                               CtdlDeleteMessages(CC->room.QRname,
-                                                  IMAP->msgids[i], "", 1);
-                               ++num_expunged;
+                               delmsgs[num_delmsgs++] = IMAP->msgids[i];
                        }
                }
+               CtdlDeleteMessages(CC->room.QRname, delmsgs, num_delmsgs, "", 1);
+               num_expunged += num_delmsgs;
+               free(delmsgs);
+       }
 
        if (num_expunged > 0) {
                imap_rescan_msgids();
index 01220281a1eb2b6ba721f2dd6d3b04f3515b498a..27704f10321fe5af6d06c033df307f9755cb7717 100644 (file)
@@ -865,7 +865,7 @@ void network_spool_msg(long msgnum, void *userdata) {
 
        /* Delete this message if delete-after-send is set */
        if (delete_after_send) {
-               CtdlDeleteMessages(CC->room.QRname, msgnum, "", 0);
+               CtdlDeleteMessages(CC->room.QRname, &msgnum, 1, "", 0);
        }
 
 }
index 684611277f0da6a1248f4487c096e1f59214528d..a015e429db116e5b875ea1948d8c18b5699fcf88 100644 (file)
@@ -466,12 +466,19 @@ void pop3_update(void) {
        int i;
         struct visit vbuf;
 
+       long *deletemsgs = NULL;
+       int num_deletemsgs = 0;
+
        /* Remove messages marked for deletion */
-       if (POP3->num_msgs > 0) for (i=0; i<POP3->num_msgs; ++i) {
-               if (POP3->msgs[i].deleted) {
-                       CtdlDeleteMessages(MAILROOM,
-                               POP3->msgs[i].msgnum, "", 1);
+       if (POP3->num_msgs > 0) {
+               deletemsgs = malloc(POP3->num_msgs * sizeof(long));
+               for (i=0; i<POP3->num_msgs; ++i) {
+                       if (POP3->msgs[i].deleted) {
+                               deletemsgs[num_deletemsgs++] = POP3->msgs[i].msgnum;
+                       }
                }
+               CtdlDeleteMessages(MAILROOM, deletemsgs, num_deletemsgs, "", 1);
+               free(deletemsgs);
        }
 
        /* Set last read pointer */
index dfa9c65bf35c531720b5499e0fb7edf2ab80347a..e1a933475207541eec10b63e70c30ae05dcae20c 100644 (file)
@@ -1641,17 +1641,18 @@ void smtp_do_procmsg(long msgnum, void *userdata) {
         * message and the message message.
         */
        if (incomplete_deliveries_remaining <= 0) {
-               CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "", 0);
-               CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, text_msgid, "", 0);
+               long delmsgs[2];
+               delmsgs[0] = msgnum;
+               delmsgs[1] = text_msgid;
+               CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, delmsgs, 2, "", 0);
        }
 
-
        /*
         * Uncompleted delivery instructions remain, so delete the old
         * instructions and replace with the updated ones.
         */
        if (incomplete_deliveries_remaining > 0) {
-               CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "", 0);
+               CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, &msgnum, 1, "", 0);
                msg = malloc(sizeof(struct CtdlMessage));
                memset(msg, 0, sizeof(struct CtdlMessage));
                msg->cm_magic = CTDLMESSAGE_MAGIC;
index c49ca6b6c1d495dac46ed9a3b60ae18aee894c13..51f7b29f56c810e4e3cbb08324923bf07eb74b26 100644 (file)
@@ -323,7 +323,7 @@ int vcard_upload_beforesave(struct CtdlMessage *msg) {
                                 * vCard in the user's config room at all times.
                                 */
                                CtdlDeleteMessages(CC->room.QRname,
-                                               0L, "text/x-vcard", 1);
+                                               NULL, 0, "text/x-vcard", 1);
 
                                /* Make the author of the message the name of the user.
                                 */