<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/3.3.2">
</HEAD>
<BODY>
Dear Waldo,<BR>
     Thanks for you excellent message.  This problem reaches<BR>
the border of my knowledge, but hopefully this answer will <BR>
be somewhat helpful.<BR>
<BR>
<BR>
> Robert,<BR>
> <BR>
> I've been trying to understand the inners of indexed-btree. I have to  <BR>
> admit, this exercise has helped me greatly in my quest for learning  <BR>
> Lisp.<BR>
<BR>
I also taught (and is teaching) me a great deal.<BR>
> <BR>
> So far, I have been able to narrow down the problem to the transient  <BR>
> slot INDICES-CACHE of the BDB-INDEXED-BTREE class.<BR>
> <BR>
Good.<BR>
<BR>
> Even though this slot has the same :initform as the non-transient  <BR>
> version (e.g. make-hash-table), after you make an instance of indexed- <BR>
> btree, you can query (indices *instance*) and it returns the hash  <BR>
> table object. However, when you (indices-cache *instance*) you get the:<BR>
> <BR>
> Array index 4 out of bounds for #<SLOT-VECTOR  #x89BFD86> .<BR>
>     [Condition of type SIMPLE-ERROR]<BR>
<BR>
This must be some kind of direct OpenMCL error.  I don't understand it;<BR>
but at least we can use it to debug this problem.<BR>
<BR>
> <BR>
> What I can't figure out yet is that in collections.lisp, you have:<BR>
> <BR>
> (defmethod shared-initialize :after ((instance indexed-btree) slot-names<BR>
>                                      &rest rest)<BR>
>    (declare (ignore slot-names rest))<BR>
>    (setf (indices-cache instance) (indices instance)))<BR>
> <BR>
> which, to my understanding, should set the value of the transient  <BR>
> slot to point to the same hash-table that the INDICES slot points to.  <BR>
> However, this doesn't seem to do anything. Even if you inspect  <BR>
> (indices instance) before the setf, you get the hash-table, but for  <BR>
> some reason, whatever (indices-cache instance) points to is not  <BR>
> accepting the change.<BR>
<BR>
OK, I think you have found the heart of the problem.  <BR>
<BR>
> <BR>
> I tried tracing it back into classes.lisp, into the:<BR>
> <BR>
> (defmethod shared-initialize :around ((instance persistent-object)  <BR>
> slot-names &rest initargs &key &allow-other-keys)<BR>
>    "Initializes the persistent slots via initargs or forms.<BR>
> This seems to be necessary because it is typical for<BR>
> implementations to optimize setting the slots via initforms<BR>
> and initargs in such a way that slot-value-using-class et al<BR>
> aren't used.  Calls the next method for the transient slots."<BR>
> <BR>
> In this method, it seems to initialize the persistent and non- <BR>
> persistent slots. At the end of the method, (indices instance) is  <BR>
> properly pointing to a hash table. However, the (indices-cache  <BR>
> instance) in that method is still returning the same error. Now, at  <BR>
> the end of the defmethod, you have:<BR>
> <BR>
>           ;; let the implementation initialize the transient slots<BR>
>           (apply #'call-next-method instance transient-slot-inits  <BR>
> initargs))))))<BR>
<BR>
I didn't write this routine (It's possible by that my extraction <BR>
of the class bdb-indexed-btree is breaking it.<BR>
<BR>
> <BR>
> which is where I'm a bit at a loss. I would assume it's trying to  <BR>
> call the next-method during the initialization process. However,  <BR>
> transient-slot-inits is internally defined (flet) within this  <BR>
> defmethod and it doesn't seem to be doing anything. Also, after  <BR>
<BR>
I think "transient-slot-inits" is not a function but a list of <BR>
the slot-names that are transient that will need to be initialized.<BR>
However, you are correct that "initialize-from-initarg" is defined<BR>
by an flet here, but it does do something --- it tries to <BR>
set certain slots.  Whether it is correct or not, I don't know.<BR>
<BR>
> inspecting all the values of the parameters passed to this defmethod,  <BR>
> there is no reference to the INDICES-CACHE slot. If you inspect SLOT- <BR>
> NAMES in this method, it only has (INDICES). Could this be the reason?<BR>
<BR>
I can think of two explanations for this:  Possibly it is bad to <BR>
name the accessor for the slot named "indices-cache" the same as the <BR>
slot itself (but I dobut it).  More likely at the time you are <BR>
examinining it you are in the contect of indexed-btree or bdb-btree<BR>
and NOT the class bdb-indexed-btree.  (I'm not too sure of this...<BR>
it may be implementation dependent, and I'm not a MOP/CLOS expert.)<BR>
<BR>
<BR>
> <BR>
> I hope this may trigger something that could allow you or others to  <BR>
> solve the problem or at least help me further in diagnosing it.<BR>
<BR>
I think you have basically identified the approach I would use<BR>
to debugging this problem:  we know invoking indices-cache at<BR>
various times gives the above error, and we can't allow that.<BR>
<BR>
So although it is quite complicated, we can potentially sprinkle<BR>
"print" statements into things like shared-initialize till we <BR>
identified the precise point where indices-cache is legitimate<BR>
and then becomes illegitimate.  I think you have already started<BR>
this process---I suggest you just continue it.<BR>
<BR>
I also suggest you organize your code into a specific piece<BR>
of test code, something like this:<BR>
(asdf:operate 'asdf:load-op :elephant)<BR>
(asdf:operate 'asdf:load-op :ele-bdb)<BR>
(asdf:operate 'asdf:load-op :elephant-tests)<BR>
(in-package "ELEPHANT-TESTS")<BR>
(open-store *testdb-path*)<BR>
(setq indexed (build-indexed-btree *store-controller*))<BR>
(elephant::indices-cache indexed)<BR>
<BR>
For example, this code works for me under SBCL; if it fails<BR>
under OpenMCL on the last line, then what we need to <BR>
do is to push something like (format t "IC = ~A~%" (indices-cache X))<BR>
into the shared-initialize and other routines until we understand <BR>
it more deeply.<BR>
<BR>
By producing a reproducible piece of text like this, we might <BR>
not solve the problem:  Possibly there is a bug in OpenMCL, or <BR>
more likely I have misunderstood CLOS and MOP in some way that<BR>
won't have a one-liner fix.  But if we can get it down to  clear,<BR>
reproducible piece of code, I suspect Andrew Blumberg would be<BR>
able to solve it from that point, or we could even ask for <BR>
help from some OpenMCL forum.<BR>
<BR>
Clearly, SBCL and OpenMCL are behaving differently; if we can<BR>
track down this difference very clearly, we have best hope of <BR>
solving it.<BR>
<BR>
Ross Overbeek once told me:<BR>
<BR>
Momements of confusion are to be cherished, because they<BR>
precede moments of enlightment.<BR>
<BR>
I apologize for not understanding this more deeply; like you,<BR>
I am still learning.<BR>
<BR>
> <BR>
> Anyway, I will continue hacking as much as I can.<BR>
> (asdf:operate 'asdf:load-op :elephant)<BR>
<BR>
> Thanks,<BR>
> Waldo<BR>
> <BR>
> On Jan 11, 2006, at 7:39 AM, Robert L. Read wrote:<BR>
> <BR>
> > OK, thank you.<BR>
> ><BR>
> > If we can get Elephant into a state that you don't have to be a  <BR>
> > LISP hacker to use it,<BR>
> > we will be greatly expanding its usefulness.<BR>
> ><BR>
> > I will try to work with Waldo Rubinstein to solve this problem for  <BR>
> > openmcl.<BR>
> ><BR>
<BR>
</BODY>
</HTML>