[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