[rucksack-devel] indexing issue?
Cyrus Harmon
ch-rucksack at bobobeach.com
Fri Dec 1 00:14:09 UTC 2006
Following up on my previous email, the following works as expected:
(defun test-persistent-class-cycle ()
(rucksack:with-rucksack (rucksack *test-rucksack*)
(rucksack:with-transaction ()
(let ((p (make-instance 'a-persistent-class :name "ape")))
(setf (info p) p)))))
(defun test-persistent-class-cycle-lookup ()
(rucksack:with-rucksack (rucksack *test-rucksack*)
(rucksack:with-transaction ()
(rucksack:rucksack-map-slot
rucksack 'a-persistent-class 'name
(lambda (x)
(print (list (info (info x)) (name x) x)))
:equal "ape"))))
but when the cycle is in a non-persistent class reachable from the
persistent class, bad things happen (i.e. it hangs).
Cyrus
On Nov 30, 2006, at 3:49 PM, Cyrus Harmon wrote:
>
> On Nov 30, 2006, at 12:26 PM, Arthur Lemmens wrote:
>
>> Cyrus Harmon wrote:
>>> Oh?0 is using the index the only way to find it?
>> ...
>> This is not a relational database, it's persistent Lisp objects ;-)
>
> Indeed. Still trying to get my head around that concept fully.
>
> So does this mean that when I have an object of an indexed class I
> don't need to explicitly call add-rucksack-root?
>
>> The easiest way is probably to use SLOT-MAKUNBOUND. This should
>> sooner or later call RUCKSACK-MAYBE-INDEX-CHANGED-SLOT, which
>> will call INDEX-DELETE to remove the association between the
>> old slot value and the object instance from the index.
>
> Hmm... I'm confused, but I'll keep digging.
>
>>> Finally, one further question... what does rucksack do about cycles?
>>
>> Nothing special, really. I'm not sure that I understand your
>> question.
>
> Well, for starters there are cyclic lists and it looks like
> rucksacks answer to that is:
>
> Serializing circular lists isn't implemented yet.
> [Condition of type SIMPLE-ERROR]
>
> Restarts:
> 0: [ABORT] Abort #<RUCKSACK:STANDARD-TRANSACTION #337391780600000
> with 8 dirty objects>
> 1: [RETRY] Retry #<RUCKSACK:STANDARD-TRANSACTION #337391780600000
> with 8 dirty objects>
> 2: [ABORT-REQUEST] Abort handling SLIME request.
> 3: [TERMINATE-THREAD] Terminate this thread (#<THREAD "new-repl-
> thread" {36147FF9}>)
>
> Backtrace:
> 0: ((SB-PCL::FAST-METHOD RUCKSACK::SERIALIZE (CONS T))
> #<unavailable argument> #<unavailable argument> #1=(1 . #1#)
> #<RUCKSACK::SERIALIZATION-BUFFER {17625251}>)
> 1: ((SB-PCL::FAST-METHOD RUCKSACK::SAVE-OBJECT (T #1="#<...>" .
> #1#)) #<unused argument> #<unused argument> #<CYCLE-TEST #58 in
> #<STANDARD-CACHE of size 10000, heap #P"/Users/sly/projects/
> cyrusharmon.org/research/discs/rucksack/heap" and 45 objects in
> memory.>> 58 #<RUCKSACK:STANDARD-CACHE of size 10000, heap #P"/
> Users/sly/projects/cyrusharmon.org/research/discs/rucksack/heap"
> and 45 objects in memory.> 337391780600000 NIL :SCHEMA NIL)
> 2: ((SB-PCL::FAST-METHOD RUCKSACK::SAVE-DIRTY-OBJECT (T
> #1="#<...>" . #1#)) #<unused argument> #<unused argument> #<CYCLE-
> TEST #58 in #<STANDARD-CACHE of size 10000, heap #P"/Users/sly/
> projects/cyrusharmon.org/research/discs/rucksack/heap" and 45
> objects in memory.>> #<RUCKSACK:STANDARD-CACHE of size 10000, heap
> #P"/Users/sly/projects/cyrusharmon.org/research/discs/rucksack/
> heap" and 45 objects in memory.> #<RUCKSACK:STANDARD-TRANSACTION
> #337391780600000 with 8 dirty objects> 58 :SCHEMA NIL)
> 3: ((SB-PCL::FAST-METHOD RUCKSACK:TRANSACTION-COMMIT-1
> (RUCKSACK:STANDARD-TRANSACTION RUCKSACK:STANDARD-CACHE
> RUCKSACK:STANDARD-RUCKSACK)) #<unavailable argument> #<unavailable
> argument> #<RUCKSACK:STANDARD-TRANSACTION #337391780600000 with 8
> dirty objects> #<RUCKSACK:STANDARD-CACHE of size 10000, heap #P"/
> Users/sly/projects/cyrusharmon.org/research/discs/rucksack/heap"
> and 45 objects in memory.> #<RUCKSACK::SERIAL-TRANSACTION-RUCKSACK
> in #P"/Users/sly/projects/cyrusharmon.org/research/discs/rucksack/"
> with 3 roots {175E4AF9}>)
> 4: ((LAMBDA (SB-PCL::.PV-CELL. SB-PCL::.NEXT-METHOD-CALL. SB-
> PCL::.ARG0. SB-PCL::.ARG1. SB-PCL::.ARG2.)) #<unavailable argument>
> #<unavailable argument> #<RUCKSACK:STANDARD-TRANSACTION
> #337391780600000 with 8 dirty objects> #<RUCKSACK:STANDARD-CACHE of
> size 10000, heap #P"/Users/sly/projects/cyrusharmon.org/research/
> discs/rucksack/heap" and 45 objects in memory.> #<RUCKSACK::SERIAL-
> TRANSACTION-RUCKSACK in #P"/Users/sly/projects/cyrusharmon.org/
> research/discs/rucksack/" with 3 roots {175E4AF9}>)
> 5: (TEST-CYCLE)
> 6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (TEST-CYCLE) #<NULL-LEXENV>)
> 7: (SWANK::EVAL-REGION "(test-cycle)
>
> which is better than spinning for ever.
>
>>> Is there a way to break cycles
>>
>> What kind of cycles would you want to break, and why?
>
> Well, breaking them isn't the right answer, but somehow
> representing them in persistent storage would be nice.
>
>>> When I try to add an object that points to itself rucksack seems
>>> to spin forever.
>>
>> If it does, that's a bug. Can you show me the code that does this?
>
> Working on a test case. What I have is an object that contains a
> (non-persistent) object that points to itself. Which leads me to
> what is probably another fundamental misunderstanding on my part.
> What does rucksack do with objects of non-persistent classes?
> Here's my test:
>
>
> (defclass a-non-persistent-class ()
> ((bogosity :accessor bogosity :initarg :bogosity)))
>
> (eval-when (:compile-toplevel :load-toplevel)
> (rucksack:with-rucksack (rucksack *test-rucksack* #+nil :if-
> exists #+nil :supersede)
> (rucksack:with-transaction ()
>
> (defclass a-persistent-class ()
> ((name :accessor name :initarg :name :index :string-index)
> (info :accessor info :initarg :info))
> (:metaclass persistent-class)
> (:index t)))))
>
>
> (defun test-not-persistent-data-1 ()
> (let ((np (make-instance 'a-non-persistent-class :bogosity 412)))
> (rucksack:with-rucksack (rucksack *test-rucksack*)
> (rucksack:with-transaction ()
> (let ((p (make-instance 'a-persistent-class :name
> "moose" :info np)))
> (print (name p)))))))
>
> (defun test-not-persistent-data-lookup-1 ()
> (rucksack:with-rucksack (rucksack *test-rucksack*)
> (rucksack:with-transaction ()
> (rucksack:rucksack-map-slot
> rucksack 'a-persistent-class 'name
> (lambda (x)
> (print (list (bogosity (info x)) (name x) x)))))))
>
> (defun test-not-persistent-data-2 ()
> (let ((np (make-instance 'a-non-persistent-class :bogosity 412)))
> (setf (bogosity np) np)
> (rucksack:with-rucksack (rucksack *test-rucksack*)
> (rucksack:with-transaction ()
> (let ((p (make-instance 'a-persistent-class :name
> "moose" :info np)))
> (print (name p)))))))
>
>
>
> test-persistent-data-1 seems to work fine and the slot in a-non-
> persistent-class is even preserved, it seems. yay!
>
> but, when you go to run test-not-persistent-data-2 you get stuck on
> a loop. yes, perhaps this is a contrived situation, but it's the
> situation I find myself when trying to shoe-horn my existing
> classes into rucksack.
>
> So, in summary, there are two separate issues it seems, cyclic
> lists, which are not supported but which throw an error and
> persistent objects that contain objects that point to themselves
> which just hang.
>
> Thanks again for the insightful discussion and for rucksack in
> general! It's starting to get clearer.
>
> Cyrus
>
> _______________________________________________
> rucksack-devel mailing list
> rucksack-devel at common-lisp.net
> http://common-lisp.net/cgi-bin/mailman/listinfo/rucksack-devel
More information about the rucksack-devel
mailing list