]> code.citadel.org Git - citadel.git/commitdiff
* Added supplementary message info records for info that may change
authorArt Cancro <ajc@citadel.org>
Mon, 12 Jul 1999 03:35:52 +0000 (03:35 +0000)
committerArt Cancro <ajc@citadel.org>
Mon, 12 Jul 1999 03:35:52 +0000 (03:35 +0000)
          at some time later than when the message is saved (i.e. ref counts)
        * Implemented msg reference count increment/decrement; delete messages
          whose reference count reaches zero

citadel/ChangeLog
citadel/msgbase.c
citadel/msgbase.h
citadel/room_ops.c
citadel/serv_expire.c
citadel/server.h

index 5a3142cb8c894186671ea7168cecf1c6e8bc95eb..c2ac59b813c2c76699563f1584f77859ef8a0164 100644 (file)
@@ -4,6 +4,10 @@ Sun Jul 11 18:46:48 EDT 1999 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
        * room_ops.c: eliminate room name parameter in putroom() and its ilk;
          get data from quickroom.QRname instead; prevents incorrect indexes
        * Tentative implementation of "personal rooms" (user-private namespace)
+       * Added supplementary message info records for info that may change
+         at some time later than when the message is saved (i.e. ref counts)
+       * Implemented msg reference count increment/decrement; delete messages
+         whose reference count reaches zero
 
 Wed Jul  7 23:25:09 EDT 1999 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
        * control.c: create citadel.control if it doesn't exist (yikes!)
index c1c290308ee74bb88c6053a14d73774a7252a7e6..00be780f59ad337cd8d86395aee1fdf10fc9486d 100644 (file)
@@ -1337,7 +1337,7 @@ void cmd_dele(char *delstr)
        put_msglist(&CC->quickroom);
        lputroom(&CC->quickroom);
        if (ok==1) {
-               cdb_delete(CDB_MSGMAIN, &delnum, sizeof(long));
+               AdjRefCount(delnum, -1); 
                cprintf("%d Message deleted.\n",OK);
                }
        else cprintf("%d No message %ld.\n",ERROR,delnum);
@@ -1400,3 +1400,88 @@ void cmd_move(char *args)
 
        cprintf("%d Message moved.\n", OK);
        }
+
+
+
+/*
+ * GetSuppMsgInfo()  -  Get the supplementary record for a message
+ */
+void GetSuppMsgInfo(struct SuppMsgInfo *smibuf, long msgnum) {
+
+        struct cdbdata *cdbsmi;
+       long TheIndex;
+
+        memset(smibuf, 0, sizeof(struct SuppMsgInfo));
+       smibuf->smi_msgnum = msgnum;
+       smibuf->smi_refcount = 1;       /* Default reference count is 1 */
+
+       /* Use the negative of the message number for its supp record index */
+       TheIndex = (0L - msgnum);
+
+        cdbsmi = cdb_fetch(CDB_MSGMAIN, &TheIndex, sizeof(long) );
+        if (cdbsmi == NULL) {
+                return;      /* record not found; go with defaults */
+        }
+
+        memcpy(smibuf, cdbsmi->ptr,
+                ( (cdbsmi->len > sizeof(struct SuppMsgInfo)) ?
+                sizeof(struct SuppMsgInfo) : cdbsmi->len) );
+        cdb_free(cdbsmi);
+       return;
+}
+   
+
+/*
+ * PutSuppMsgInfo()  -  (re)write supplementary record for a message
+ */
+void PutSuppMsgInfo(struct SuppMsgInfo *smibuf)
+{
+        long TheIndex;
+
+       /* Use the negative of the message number for its supp record index */
+       TheIndex = (0L - smibuf->smi_msgnum);
+
+        cdb_store(CDB_MSGMAIN,
+                &TheIndex, sizeof(long),
+                smibuf, sizeof(struct SuppMsgInfo));
+
+        }         
+
+
+
+/*
+ * AdjRefCount  -  change the reference count for a message;
+ *                 delete the message if it reaches zero
+ */
+void AdjRefCount(long msgnum, int incr) {
+
+       struct SuppMsgInfo smi;
+       long delnum;
+
+       lprintf(9, "Adjust msg <%ld> ref count by <%d>\n",
+               msgnum, incr);
+
+       /* This is a *tight* critical section; please keep it that way, as
+        * it may get called while nested in other critical sections.  
+        * Complicating this any further will surely cause deadlock!
+        */
+       begin_critical_section(S_SUPPMSGMAIN);
+       GetSuppMsgInfo(&smi, msgnum);
+       smi.smi_refcount += incr;
+       PutSuppMsgInfo(&smi);
+       end_critical_section(S_SUPPMSGMAIN);
+
+       lprintf(9, "Ref count for message <%ld> after write is <%d>\n",
+               msgnum, smi.smi_refcount);
+
+       /* If the reference count is now zero, delete the message
+        * (and its supplementary record as well).
+        */
+       if (smi.smi_refcount == 0) {
+               lprintf(9, "Deleting message <%ld>\n", msgnum);
+               delnum = msgnum;
+               cdb_delete(CDB_MSGMAIN, &delnum, sizeof(long));   
+               delnum = (0L - msgnum);
+               cdb_delete(CDB_MSGMAIN, &delnum, sizeof(long));   
+       }
+}
index 4331d598b099bca73e48534bd18dfb5120449ba4..40bdab65b16d4055b5b2b0aac0374eacdba7f99c 100644 (file)
@@ -25,3 +25,6 @@ void cmd_ent0 (char *entargs);
 void cmd_ent3 (char *entargs);
 void cmd_dele (char *delstr);
 void cmd_move (char *args);
+void GetSuppMsgInfo(struct SuppMsgInfo *, long);
+void PutSuppMsgInfo(struct SuppMsgInfo *);
+void AdjRefCount(long, int);
index e81a1e415cf21c3182147f39afc950d4586ebe61..d6a37b282fc57fb6da2956d8a73c0036f0e05e23 100644 (file)
@@ -1232,7 +1232,7 @@ void delete_room(struct quickroom *qrbuf)
        if (CC->num_msgs > 0)
                for (a = 0; a < CC->num_msgs; ++a) {
                        MsgToDelete = MessageFromList(a);
-                       cdb_delete(CDB_MSGMAIN, &MsgToDelete, sizeof(long));
+                       AdjRefCount(MsgToDelete, -1);
                }
        put_msglist(qrbuf);
        phree(CC->msglist);
index 3a191652751de1bdb4cf9f431345438cca71cb5b..bc93cb92470603044773227d89eeca20d0543503 100644 (file)
@@ -142,7 +142,7 @@ void DoPurgeMessages(struct quickroom *qrbuf) {
                while (CC->num_msgs > epbuf.expire_value) {
                        delnum = MessageFromList(0);
                        lprintf(5, "Expiring message %ld\n", delnum);
-                       cdb_delete(CDB_MSGMAIN, &delnum, sizeof(long));
+                       AdjRefCount(delnum, -1); 
                        memcpy(&CC->msglist[0], &CC->msglist[1],
                                (sizeof(long)*(CC->num_msgs - 1)));
                        CC->num_msgs = CC->num_msgs - 1;
@@ -160,7 +160,7 @@ void DoPurgeMessages(struct quickroom *qrbuf) {
                        if ((xtime > 0L)
                           && (now - xtime > (time_t)(epbuf.expire_value * 86400L))) {
                                lprintf(5, "Expiring message %ld\n", delnum);
-                               cdb_delete(CDB_MSGMAIN, &delnum, sizeof(long));
+                               AdjRefCount(delnum, -1); 
                                SetMessageInList(a, 0L);
                                ++messages_purged;
                                }
index 5516181e1dd487a8fdffa5ef8a3fc815910c2a72..add73474afd142e17e43023d7426e6b7849c5da8 100644 (file)
@@ -140,6 +140,7 @@ enum {
        S_HOUSEKEEPING,
        S_DATABASE,
        S_NETDB,
+       S_SUPPMSGMAIN,
        MAX_SEMAPHORES
 };
 
@@ -260,6 +261,17 @@ struct visit {
 #define UA_ZAPPED              16
 
 
+/* Supplementary data for a message on disk
+ * (These are kept separately from the message itself because they are
+ * fields whose values may change at some point after the message is saved.)
+ */
+struct SuppMsgInfo {
+       long smi_msgnum;        /* Redundant, but useful for self-check */
+       int smi_refcount;       /* Number of rooms which point to this msg */
+       /* more stuff will be added to this record in the future */
+};
+
+
 
 /* Built-in debuggable stuff for checking for memory leaks */
 #ifdef DEBUG_MEMORY_LEAKS