[rucksack-devel] indexing issue?

Cyrus Harmon ch-rucksack at bobobeach.com
Thu Nov 30 23:49:33 UTC 2006


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




More information about the rucksack-devel mailing list