[rucksack-cvs] CVS rucksack

alemmens alemmens at common-lisp.net
Sun Sep 3 14:40:51 UTC 2006


Update of /project/rucksack/cvsroot/rucksack
In directory clnet:/tmp/cvs-serv23707

Modified Files:
	do.txt done.txt notes.txt objects.lisp test-index-1a.lisp 
Log Message:

Handle updates of in-memory persistent objects by writing a method for
LispÅ› UPDATE-INSTANCE-FOR-REDEFINED-CLASS that marks the object as dirty
and calls Rucksack's UPDATE-PERSISTENT-INSTANCE-FOR-REDEFINED-CLASS.



--- /project/rucksack/cvsroot/rucksack/do.txt	2006/09/01 13:57:07	1.3
+++ /project/rucksack/cvsroot/rucksack/do.txt	2006/09/03 14:40:50	1.4
@@ -1,28 +1,9 @@
 DO: 
 
-- What about in-memory persistent instances when the class definition
-  changes?  We should make sure that those are updated too.  Some possible
-  strategies:
-  to be three strategies:
-  1. Rely on Lisp's normal UPDATE-INSTANCE-FOR-REDEFINED-CLASS mechanism.
-     Then the programmer must write methods for both UPDATE-INSTANCE-...
-     and UPDATE-PERSISTENT-INSTANCE-... .  That seems error prone.
-  2. Remove all instances of the redefined class from the cache.
-     Then the objects will be loaded from disk again, and U-P-I-F-R-C will
-     be called automatically.  This has the disadvantage that all values
-     of transient slots will be gone; then again, I'm not sure if transient
-     slots make much sense anyway for persistent objects.
-     CLHS says: 
-       "Updating such an instance occurs at an implementation-dependent time,
-       but no later than the next time a slot of that instance is read or
-       written."
-     Maybe we can also hook into SLOT-VALUE-USING-CLASS and (SETF S-V-U-C)
-     to automatically reload the object.  Or maybe write an after method on
-     Lisp's UPDATE-INSTANCE-FOR-REDEFINED-CLASS that calls UPDATE-PERSISTENT-...
-  3. Forbid it and signal some kind of error.
+- Make Rucksack crash proof.  (Use a copying GC?)
 
-- There's still a btree bug that's uncovered by the stress test.
-  Fix it.
+- There's still a btree bug that's detected (very rarely) by the
+  stress test.  Fix it.
 
 - Check that btrees actually signal an error for duplicate keys.
   Handle those errors correctly for slot indexes.
@@ -45,7 +26,7 @@
   continue, UPDATE-PERSISTENT-INSTANCE-... will be called when necessary.
 
 - Think about non-persistent slots.  Should we initialize them during
-  LOAD-OBJECT?
+  LOAD-OBJECT?  Do we need them at all?
 
 - I'm not sure that :INCLUDE-SUBCLASSES NIL makes sense for
   RUCKSACK-MAP-SLOT.  Think about this.
--- /project/rucksack/cvsroot/rucksack/done.txt	2006/09/01 13:57:07	1.3
+++ /project/rucksack/cvsroot/rucksack/done.txt	2006/09/03 14:40:51	1.4
@@ -1,3 +1,11 @@
+* 2006-09-03
+
+- Handle updates of in-memory persistent objects by writing a method
+  for Lisp's UPDATE-INSTANCE-FOR-REDEFINED-CLASS that marks the object
+  as dirty and calls Rucksack's
+  UPDATE-PERSISTENT-INSTANCE-FOR-REDEFINED-CLASS.
+
+
 * 2006-09-01
 
 - Get rid of the Lispworks-specific PROCESS-A-SLOT-OPTION stuff and handle
--- /project/rucksack/cvsroot/rucksack/notes.txt	2006/09/01 13:57:07	1.2
+++ /project/rucksack/cvsroot/rucksack/notes.txt	2006/09/03 14:40:51	1.3
@@ -1,4 +1,4 @@
-;; $Id: notes.txt,v 1.2 2006/09/01 13:57:07 alemmens Exp $
+;; $Id: notes.txt,v 1.3 2006/09/03 14:40:51 alemmens Exp $
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Some random notes
@@ -39,6 +39,7 @@
 
 
 * Handling initargs in LOAD-OBJECT and UPDATE-PERSISTENT-INSTANCE-...
+  [2006-09-01]
 
 Actually, initargs are only relevant for slots that have been added by
 a class redefinition, so they're only relevant for
@@ -57,3 +58,36 @@
   to update an instance whose class has been redefined, no initialization
   arguments are provided."
 
+
+* Updating in-memory persistent instances when the class definition changes
+  [2006-09-02]
+
+We should make sure that those are updated too.  Some possible strategies:
+
+1. Don't do anything special but rely on Lisp's normal
+   UPDATE-INSTANCE-FOR-REDEFINED-CLASS mechanism.  Then the programmer
+   must write methods for both UPDATE-INSTANCE-...  and
+   UPDATE-PERSISTENT-INSTANCE-... .  That seems error prone.
+
+2. Remove all instances of the redefined class from the cache.  Then
+   the objects will be loaded from disk again, and U-P-I-F-R-C will be
+   called automatically.  This has the disadvantage that all values of
+   transient slots will be gone; then again, I'm not sure if transient
+   slots make much sense anyway for persistent objects.  CLHS says:
+   "Updating such an instance occurs at an implementation-dependent
+   time, but no later than the next time a slot of that instance is
+   read or written."  Maybe we can also hook into
+   SLOT-VALUE-USING-CLASS and (SETF S-V-U-C) to automatically reload
+   the object.  Or maybe write an after method on Lisp's
+   UPDATE-INSTANCE-FOR-REDEFINED-CLASS that calls
+   UPDATE-PERSISTENT-...
+
+3. Forbid it and signal some kind of error.
+
+4. Write default method for Lisp's UPDATE-INSTANCE-FOR-REDEFINED-CLASS
+   that marks the object as dirty and calls Rucksack's
+   UPDATE-PERSISTENT-INSTANCE-FOR-REDEFINED-CLASS.
+
+Strategy 4 looks like a simple and reasonably clean solution to me.
+I'll implement that.
+
--- /project/rucksack/cvsroot/rucksack/objects.lisp	2006/09/01 13:57:07	1.15
+++ /project/rucksack/cvsroot/rucksack/objects.lisp	2006/09/03 14:40:51	1.16
@@ -1,4 +1,4 @@
-;; $Id: objects.lisp,v 1.15 2006/09/01 13:57:07 alemmens Exp $
+;; $Id: objects.lisp,v 1.16 2006/09/03 14:40:51 alemmens Exp $
 
 (in-package :rucksack)
 
@@ -403,13 +403,14 @@
 
 
 
-(defmethod shared-initialize :before ((object persistent-object) slots
-				      &key rucksack
-                                      ;; The DONT-INDEX argument is used
-                                      ;; when creating the indexes themselves
-                                      ;; (to prevent infinite recursion).
-                                      (dont-index nil)
-                                      &allow-other-keys)
+(defmethod initialize-instance :before ((object persistent-object)
+                                        &rest args
+                                        &key rucksack
+                                        ;; The DONT-INDEX argument is used
+                                        ;; when creating the indexes themselves
+                                        ;; (to prevent infinite recursion).
+                                        (dont-index nil)
+                                        &allow-other-keys)
   ;; This happens when persistent-objects are created in memory, not when
   ;; they're loaded from the cache (loading uses ALLOCATE-INSTANCE instead).
   (let ((rucksack (or rucksack (rucksack object))))
@@ -422,10 +423,10 @@
     (unless dont-index
       (rucksack-maybe-index-new-object rucksack (class-of object) object))))
 
-(defmethod shared-initialize :after ((object persistent-object) slots
-				      &key rucksack
-                                      (dont-index nil)
-                                      &allow-other-keys)
+(defmethod initialize-instance :after ((object persistent-object)
+                                       &rest args
+                                       &key rucksack (dont-index nil)
+                                       &allow-other-keys)
   ;; Update slot indexes for persistent slots that are bound now.
   (unless dont-index
     (let ((class (class-of object)))
@@ -433,7 +434,7 @@
         (let ((slot-name (slot-definition-name slot)))
           (when (and (slot-boundp object slot-name)
                      (slot-persistence slot))
-            (rucksack-maybe-index-changed-slot rucksack
+            (rucksack-maybe-index-changed-slot (or rucksack (rucksack object))
                                                class object slot
                                                nil (slot-value object slot-name)
                                                nil t)))))))
@@ -772,10 +773,11 @@
 
 (defgeneric update-persistent-instance-for-redefined-class
     (instance added-slots discarded-slots property-list &key)
-  (:method ((instance persistent-object) added-slots discarded-slots property-list
+  (:method ((instance persistent-object) added-slots discarded-slots plist
             &key)
    ;; Default method: ignore the discarded slots and initialize added slots
-   ;; according to their initfunctions.
+   ;; according to their initforms.  We do this 'by hand' and not by calling
+   ;; SHARED-INITIALIZE because slot indexes may need to be updated too.
    (let ((slots (class-slots (class-of instance))))
      (loop for slot-name in added-slots
            for slot = (find slot-name slots :key #'slot-definition-name)
@@ -789,3 +791,15 @@
            ;; arguments are provided." 
            do (setf (slot-value instance slot-name) (funcall initfunction))))))
 
+
+(defmethod update-instance-for-redefined-class
+           ((object persistent-object) added-slots discarded-slots plist
+            &rest initargs &key)
+  ;; This method exists for updating in-memory persistent objects
+  ;; of which the class definition has changed.
+  (declare (ignore initargs)) ; there shouldn't be any, anyway
+  (cache-touch-object object (rucksack-cache (rucksack object)))
+  (update-persistent-instance-for-redefined-class object added-slots
+                                                  discarded-slots plist))
+
+
--- /project/rucksack/cvsroot/rucksack/test-index-1a.lisp	2006/09/01 13:57:07	1.3
+++ /project/rucksack/cvsroot/rucksack/test-index-1a.lisp	2006/09/03 14:40:51	1.4
@@ -1,4 +1,4 @@
-;; $Id: test-index-1a.lisp,v 1.3 2006/09/01 13:57:07 alemmens Exp $
+;; $Id: test-index-1a.lisp,v 1.4 2006/09/03 14:40:51 alemmens Exp $
 
 (in-package :rucksack-test)
 
@@ -94,7 +94,7 @@
 
 #|
 
-TEST-RS 3 > (create-hackers)
+RS-TEST 3 > (create-hackers)
 
 #<HACKER #:HACKER-9234 called "Martin"> 
 #<HACKER #:HACKER-9235 called "Martin"> 
@@ -129,7 +129,7 @@
 NIL
 T
 
-TEST-RS 4 > (show-hackers)
+RS-TEST 4 > (show-hackers)
 
 "Hackers indexed by object id." 
 #<HACKER #:HACKER-9234 called "Martin"> 




More information about the rucksack-cvs mailing list