* THE DREADED AUTO-PURGER now purges euid index records which point to
authorArt Cancro <ajc@citadel.org>
Thu, 6 Oct 2005 04:09:19 +0000 (04:09 +0000)
committerArt Cancro <ajc@citadel.org>
Thu, 6 Oct 2005 04:09:19 +0000 (04:09 +0000)
  messages that no longer exist.

citadel/ChangeLog
citadel/euidindex.c
citadel/msgbase.c
citadel/serv_expire.c

index 4df65e6ba3bec51905336e5e3f6883d7c6ee77c3..acc29f1c71a1efbaaa4ff9f3d1f7159d1bc82da8 100644 (file)
@@ -1,4 +1,8 @@
 $Log$
+Revision 655.22  2005/10/06 04:09:19  ajc
+* THE DREADED AUTO-PURGER now purges euid index records which point to
+  messages that no longer exist.
+
 Revision 655.21  2005/10/06 03:36:05  ajc
 * Changed the format of the euidindex record to contain the record's key.
   This will allow us to auto-purge stale records later.
@@ -7201,4 +7205,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import
-
index 9a8d5984316da31e9a543abadeb3af9024122fa8..ef2cb27801ede963d47bd65bd31fc9948771be60 100644 (file)
 #include "euidindex.h"
 
 /*
- * The structure of an EUID *index* is:
+ * The structure of an euidindex record *key* is:
  *
  * |----room_number----|----------EUID-------------|
  *    (sizeof long)       (actual length of euid)
  *
  *
- * The structure of an EUID *record* is:
+ * The structure of an euidindex record *value* is:
  *
  * |-----msg_number----|----room_number----|----------EUID-------------|
  *    (sizeof long)       (sizeof long)       (actual length of euid)
  *
  */
 
+
+/*
+ * Locate a message in a given room with a given euid, and return
+ * its message number.
+ */
 long locate_message_by_euid(char *euid, struct ctdlroom *qrbuf) {
        char *key;
        int key_len;
@@ -89,6 +94,11 @@ long locate_message_by_euid(char *euid, struct ctdlroom *qrbuf) {
        return(msgnum);
 }
 
+
+/*
+ * Store the euid index for a message, which has presumably just been
+ * stored in this room by the caller.
+ */
 void index_message_by_euid(char *euid, struct ctdlroom *qrbuf, long msgnum) {
        char *key;
        int key_len;
index ffddf5c7392bf988f3533429577f60ffa67d14fe..e1608b4cba898745fbc81e2c63377c3d328385cc 100644 (file)
@@ -1776,8 +1776,8 @@ int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, int do_repl_check,
        long highest_msg = 0L;
        struct CtdlMessage *msg = NULL;
 
-       lprintf(CTDL_DEBUG, "CtdlSaveMsgPointerInRoom(roomname=%s, msgid=%ld, do_repl_check=%d)\n",
-               roomname, msgid, do_repl_check);
+       /*lprintf(CTDL_DEBUG, "CtdlSaveMsgPointerInRoom(roomname=%s, msgid=%ld, do_repl_check=%d)\n",
+               roomname, msgid, do_repl_check);*/
 
        strcpy(hold_rm, CC->room.QRname);
 
@@ -2019,8 +2019,8 @@ void ReplicationChecks(struct CtdlMessage *msg) {
        if (msg == NULL) return;
        if (msg->cm_fields['E'] == NULL) return;
        if (strlen(msg->cm_fields['E']) == 0) return;
-       lprintf(CTDL_DEBUG, "Exclusive ID: <%s> for room <%s>\n",
-               msg->cm_fields['E'], CC->room.QRname);
+       /*lprintf(CTDL_DEBUG, "Exclusive ID: <%s> for room <%s>\n",
+               msg->cm_fields['E'], CC->room.QRname);*/
 
        old_msgnum = locate_message_by_euid(msg->cm_fields['E'], &CC->room);
        if (old_msgnum > 0L) {
@@ -2066,7 +2066,6 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
         * giving it one, right now.
         */
        if (msg->cm_fields['T'] == NULL) {
-               lprintf(CTDL_DEBUG, "Generating timestamp\n");
                snprintf(generated_timestamp, sizeof generated_timestamp, "%ld", (long)time(NULL));
                msg->cm_fields['T'] = strdup(generated_timestamp);
        }
@@ -2074,7 +2073,6 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
        /* If this message has no path, we generate one.
         */
        if (msg->cm_fields['P'] == NULL) {
-               lprintf(CTDL_DEBUG, "Generating path\n");
                if (msg->cm_fields['A'] != NULL) {
                        msg->cm_fields['P'] = strdup(msg->cm_fields['A']);
                        for (a=0; a<strlen(msg->cm_fields['P']); ++a) {
@@ -2096,7 +2094,6 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
        }
 
        /* Learn about what's inside, because it's what's inside that counts */
-       lprintf(CTDL_DEBUG, "Learning what's inside\n");
        if (msg->cm_fields['M'] == NULL) {
                lprintf(CTDL_ERR, "ERROR: attempt to save message with NULL body\n");
                return(-2);
@@ -2127,8 +2124,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
        }
 
        /* Goto the correct room */
-       lprintf(CTDL_DEBUG, "Selected room %s\n",
-               (recps) ? CC->room.QRname : SENTITEMS);
+       lprintf(CTDL_DEBUG, "Selected room %s\n", (recps) ? CC->room.QRname : SENTITEMS);
        strcpy(hold_rm, CC->room.QRname);
        strcpy(actual_rm, CC->room.QRname);
        if (recps != NULL) {
@@ -2136,12 +2132,11 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,     /* message to save */
        }
 
        /* If the user is a twit, move to the twit room for posting */
-       lprintf(CTDL_DEBUG, "Handling twit stuff: %s\n",
-                       (CC->user.axlevel == 2) ? config.c_twitroom : "OK");
        if (TWITDETECT) {
                if (CC->user.axlevel == 2) {
                        strcpy(hold_rm, actual_rm);
                        strcpy(actual_rm, config.c_twitroom);
+                       lprintf(CTDL_DEBUG, "Diverting to twit room\n");
                }
        }
 
index 0da8e381c4ac5a0ce4068dfaa66e3c4f538e076d..ba354fa2d5561509a06eb36db286c6c7e2ccc951 100644 (file)
@@ -97,7 +97,13 @@ struct ctdlroomref {
 
 struct UPurgeList {
        struct UPurgeList *next;
-       char up_key[SIZ];
+       char up_key[256];
+};
+
+struct EPurgeList {
+       struct EPurgeList *next;
+       int ep_keylen;
+       char *ep_key;
 };
 
 
@@ -604,7 +610,7 @@ int PurgeUseTable(void) {
                        uptr = (struct UPurgeList *) malloc(sizeof(struct UPurgeList));
                        if (uptr != NULL) {
                                uptr->next = ul;
-                               safestrncpy(uptr->up_key, ut.ut_msgid, SIZ);
+                               safestrncpy(uptr->up_key, ut.ut_msgid, sizeof uptr->up_key);
                                ul = uptr;
                        }
                        ++purged;
@@ -626,6 +632,61 @@ int PurgeUseTable(void) {
 }
 
 
+
+/*
+ * Purge the EUID Index of old records.
+ *
+ */
+int PurgeEuidIndexTable(void) {
+       int purged = 0;
+       struct cdbdata *cdbei;
+       struct EPurgeList *el = NULL;
+       struct EPurgeList *eptr; 
+       long msgnum;
+       struct CtdlMessage *msg;
+
+       /* Phase 1: traverse through the table, discovering old records... */
+       lprintf(CTDL_DEBUG, "Purge EUID index: phase 1\n");
+       cdb_rewind(CDB_EUIDINDEX);
+       while(cdbei = cdb_next_item(CDB_EUIDINDEX), cdbei != NULL) {
+
+               memcpy(&msgnum, cdbei->ptr, sizeof(long));
+
+               msg = CtdlFetchMessage(msgnum, 0);
+               if (msg != NULL) {
+                       CtdlFreeMessage(msg);   /* it still exists, so do nothing */
+               }
+               else {
+                       eptr = (struct EPurgeList *) malloc(sizeof(struct EPurgeList));
+                       if (eptr != NULL) {
+                               eptr->next = el;
+                               eptr->ep_keylen = cdbei->len - sizeof(long);
+                               eptr->ep_key = malloc(cdbei->len);
+                               memcpy(eptr->ep_key, &cdbei->ptr[sizeof(long)], eptr->ep_keylen);
+                               el = eptr;
+                       }
+                       ++purged;
+               }
+
+                cdb_free(cdbei);
+
+       }
+
+       /* Phase 2: delete the records */
+       lprintf(CTDL_DEBUG, "Purge euid index: phase 2\n");
+       while (el != NULL) {
+               cdb_delete(CDB_EUIDINDEX, el->ep_key, el->ep_keylen);
+               free(el->ep_key);
+               eptr = el->next;
+               free(el);
+               el = eptr;
+       }
+
+       lprintf(CTDL_DEBUG, "Purge euid index: finished (purged %d records)\n", purged);
+       return(purged);
+}
+
+
 void purge_databases(void) {
        int retval;
        static time_t last_purge = 0;
@@ -658,6 +719,9 @@ void purge_databases(void) {
        retval = PurgeUseTable();
        lprintf(CTDL_NOTICE, "Purged %d entries from the use table.\n", retval);
 
+       retval = PurgeEuidIndexTable();
+       lprintf(CTDL_NOTICE, "Purged %d entries from the EUID index.\n", retval);
+
        lprintf(CTDL_INFO, "Auto-purger: finished.\n");
 
        last_purge = now;       /* So we don't do it again soon */