[Zope-Checkins] CVS: ZODB3/Persistence - ring.c:1.1.2.1 ring.h:1.1.2.1 cPersistence.c:1.72.8.24 cPersistence.h:1.25.122.6 cPickleCache.c:1.85.8.11

Jeremy Hylton jeremy@zope.com
Wed, 9 Jul 2003 15:38:21 -0400


Update of /cvs-repository/ZODB3/Persistence
In directory cvs.zope.org:/tmp/cvs-serv11084/Persistence

Modified Files:
      Tag: zodb33-devel-branch
	cPersistence.c cPersistence.h cPickleCache.c 
Added Files:
      Tag: zodb33-devel-branch
	ring.c ring.h 
Log Message:
Extract cache ring logic into helper routines in ring.c.


=== Added File ZODB3/Persistence/ring.c ===
/*****************************************************************************

  Copyright (c) 2003 Zope Corporation and Contributors.
  All Rights Reserved.

  This software is subject to the provisions of the Zope Public License,
  Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  FOR A PARTICULAR PURPOSE

 ****************************************************************************/

/* Support routines for the doubly-linked list of cached objects. 

The cache stores a doubly-linked list of persistent objects, with
space for the pointers allocated in the objects themselves.  The cache
stores the distinguished head of the list, which is not a valid
persistent object.

The next pointers traverse the ring in order starting with the least
recently used object.  The prev pointers traverse the ring in order
starting with the most recently used object.

*/

#include "Python.h"
#include "ring.h"

void 
ring_add(CPersistentRing *ring, CPersistentRing *elt)
{
    assert(!elt->next);
    elt->next = ring;
    elt->prev = ring->prev;
    ring->prev->next = elt;
    ring->prev = elt;
}

void 
ring_del(CPersistentRing *elt)
{
    elt->next->prev = elt->prev;
    elt->prev->next = elt->next;
    elt->next = NULL;
    elt->prev = NULL;
}

void 
ring_move_to_head(CPersistentRing *ring, CPersistentRing *elt)
{
    elt->prev->next = elt->next;
    elt->next->prev = elt->prev;
    elt->next = ring;
    elt->prev = ring->prev;
    ring->prev->next = elt;
    ring->prev = elt;
}


=== Added File ZODB3/Persistence/ring.h ===
/*****************************************************************************

  Copyright (c) 2003 Zope Corporation and Contributors.
  All Rights Reserved.

  This software is subject to the provisions of the Zope Public License,
  Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  FOR A PARTICULAR PURPOSE

 ****************************************************************************/

/* Support routines for the doubly-linked list of cached objects. 

The cache stores a doubly-linked list of persistent objects, with
space for the pointers allocated in the objects themselves.  The cache
stores the distinguished head of the list, which is not a valid
persistent object.

The next pointers traverse the ring in order starting with the least
recently used object.  The prev pointers traverse the ring in order
starting with the most recently used object.

*/

typedef struct CPersistentRing_struct
{
    struct CPersistentRing_struct *prev;
    struct CPersistentRing_struct *next;
} CPersistentRing;

void ring_add(CPersistentRing *ring, CPersistentRing *elt);
void ring_del(CPersistentRing *elt);
void ring_move_to_head(CPersistentRing *ring, CPersistentRing *elt);


=== ZODB3/Persistence/cPersistence.c 1.72.8.23 => 1.72.8.24 ===
--- ZODB3/Persistence/cPersistence.c:1.72.8.23	Tue Jul  8 15:45:28 2003
+++ ZODB3/Persistence/cPersistence.c	Wed Jul  9 15:38:13 2003
@@ -78,13 +78,9 @@
 
         /* XXX Is it ever possibly to not have a cache? */
         if (self->cache) {
-	    CPersistentRing *home = &self->cache->ring_home;
             /* Create a node in the ring for this unghostified object. */
             self->cache->non_ghost_count++;
-            self->ring.next = home;
-            self->ring.prev = home->prev;
-	    home->prev->next = &self->ring;
-	    home->prev = &self->ring;
+	    ring_add(&self->cache->ring_home, &self->ring);
 	    Py_INCREF(self);
         }
 	/* set state to CHANGED while setstate() call is in progress
@@ -111,15 +107,8 @@
 accessed(cPersistentObject *self)
 {
     /* Do nothing unless the object is in a cache and not a ghost. */
-    if (self->cache && self->state >= 0 && self->ring.next) {
-	CPersistentRing *home = &self->cache->ring_home;
-	self->ring.prev->next = self->ring.next;
-	self->ring.next->prev = self->ring.prev;
-	self->ring.next = home;
-	self->ring.prev = home->prev;
-	home->prev->next = &self->ring;
-	home->prev = &self->ring; 
-    }
+    if (self->cache && self->state >= 0 && self->ring.next)
+	ring_move_to_head(&self->cache->ring_home, &self->ring);
 }
 
 static void
@@ -133,12 +122,8 @@
 
     /* if we're ghostifying an object, we better have some non-ghosts */
     assert(self->cache->non_ghost_count > 0);
-
     self->cache->non_ghost_count--;
-    self->ring.next->prev = self->ring.prev;
-    self->ring.prev->next = self->ring.next;
-    self->ring.prev = NULL;
-    self->ring.next = NULL;
+    ring_del(&self->ring);
 }
 
 static void
@@ -156,7 +141,13 @@
         return;
     }
 
-    unlink_from_ring(self);
+    /* If the cache is still active, we must unlink the object. */
+    if (self->ring.next) {
+	/* if we're ghostifying an object, we better have some non-ghosts */
+	assert(self->cache->non_ghost_count > 0);
+	self->cache->non_ghost_count--;
+	ring_del(&self->ring);
+    }
     self->state = cPersistent_GHOST_STATE;
     dictptr = _PyObject_GetDictPtr((PyObject *)self);
     if (dictptr && *dictptr) {


=== ZODB3/Persistence/cPersistence.h 1.25.122.5 => 1.25.122.6 ===
--- ZODB3/Persistence/cPersistence.h:1.25.122.5	Tue Jul  8 15:45:28 2003
+++ ZODB3/Persistence/cPersistence.h	Wed Jul  9 15:38:13 2003
@@ -16,13 +16,7 @@
 #define CPERSISTENCE_H
 
 #include "Python.h"
-#include <time.h>
-
-typedef struct CPersistentRing_struct
-{
-    struct CPersistentRing_struct *prev;
-    struct CPersistentRing_struct *next;
-} CPersistentRing;
+#include "ring.h"
 
 #define CACHE_HEAD \
     PyObject_HEAD \


=== ZODB3/Persistence/cPickleCache.c 1.85.8.10 => 1.85.8.11 ===
--- ZODB3/Persistence/cPickleCache.c:1.85.8.10	Tue Jul  8 15:45:28 2003
+++ ZODB3/Persistence/cPickleCache.c	Wed Jul  9 15:38:13 2003
@@ -808,10 +808,7 @@
 	/* insert this non-ghost object into the ring just 
 	   behind the home position. */
 	self->non_ghost_count++;
-	p->ring.next = &self->ring_home;
-	p->ring.prev =  self->ring_home.prev;
-	self->ring_home.prev->next = &p->ring;
-	self->ring_home.prev = &p->ring;
+	ring_add(&self->ring_home, &p->ring);
 	/* this list should have a new reference to the object */
 	Py_INCREF(v);
     }
@@ -835,10 +832,7 @@
 	p = (cPersistentObject *)v;
 	if (p->state >= 0) {
 	    self->non_ghost_count--;
-	    p->ring.next->prev = p->ring.prev;
-	    p->ring.prev->next = p->ring.next;
-	    p->ring.prev = NULL;
-	    p->ring.next = NULL;
+	    ring_del(&p->ring);
 	    /* The DelItem below will account for the reference
 	       held by the list. */
 	} else {