From alemmens at xs4all.nl Fri Jul 14 07:41:51 2006 From: alemmens at xs4all.nl (Arthur Lemmens) Date: Fri, 14 Jul 2006 09:41:51 +0200 Subject: [rucksack-devel] Re: rucksack cvs and sbcl: compilation problems In-Reply-To: <78EAA999-0180-4979-8B46-A69D599B5048@c-plusplus.de> References: <78EAA999-0180-4979-8B46-A69D599B5048@c-plusplus.de> Message-ID: Hello R?diger, > I'm trying to use rucksack with sbcl. I tried to compile it with > > (asdf:oos 'asdf:load-op :rucksack) > > But I get the following error message. Is there something wrong with > the current cvs version (2006-07-13) or is there a way to fix the error? > > I'm using SBCL 0.9.13 on Mac OS X/PPC. > > Regards, > R?diger Sonderfeld > > There is no applicable method for the generic function > # > when called with arguments > (# # >). > [Condition of type SIMPLE-ERROR] This looks like the pathname serialization bug to me; Nikodemus Siivola wrote a small patch for SBCL to fix this problem. You should probably ask him for the patch. Regards, Arthur Lemmens From nikodemus at random-state.net Fri Jul 14 08:31:00 2006 From: nikodemus at random-state.net (Nikodemus Siivola) Date: Fri, 14 Jul 2006 11:31:00 +0300 Subject: [rucksack-devel] Re: rucksack cvs and sbcl: compilation problems In-Reply-To: (Arthur Lemmens's message of "Fri, 14 Jul 2006 09:41:51 +0200") References: <78EAA999-0180-4979-8B46-A69D599B5048@c-plusplus.de> Message-ID: <87d5c88u63.fsf@logxor.random-state.net> "Arthur Lemmens" writes: > This looks like the pathname serialization bug to me; Nikodemus Siivola > wrote a small patch for SBCL to fix this problem. You should probably > ask him for the patch. No, actually I don't have this fixed in SBCL yet. (Bug is that PATHNAME-HOST returns an opaque object, but just changing it isn't enough -- SBCL's own uses of it need to be refacored too.) Using HOST-NAMESTRING instead of PATHNAME-HOST in Rucksack works, but breaks OpenMCL... I have just #+/- in my own tree there for SBCL. Cheers, -- Nikodemus Schemer: "Buddha is small, clean, and serious." Lispnik: "Buddha is big, has hairy armpits, and laughs." From kingruedi at c-plusplus.de Fri Jul 14 12:54:02 2006 From: kingruedi at c-plusplus.de (=?ISO-8859-1?Q?R=FCdiger_Sonderfeld?=) Date: Fri, 14 Jul 2006 14:54:02 +0200 Subject: [rucksack-devel] Re: rucksack cvs and sbcl: compilation problems In-Reply-To: <87d5c88u63.fsf@logxor.random-state.net> References: <78EAA999-0180-4979-8B46-A69D599B5048@c-plusplus.de> <87d5c88u63.fsf@logxor.random-state.net> Message-ID: Am 14.07.2006 um 10:31 schrieb Nikodemus Siivola: > "Arthur Lemmens" writes: > >> This looks like the pathname serialization bug to me; Nikodemus >> Siivola >> wrote a small patch for SBCL to fix this problem. You should >> probably >> ask him for the patch. > > No, actually I don't have this fixed in SBCL yet. (Bug is that > PATHNAME-HOST returns > an opaque object, but just changing it isn't enough -- SBCL's own > uses of it need to > be refacored too.) > > Using HOST-NAMESTRING instead of PATHNAME-HOST in Rucksack works, > but breaks OpenMCL... > > I have just #+/- in my own tree there for SBCL. Is there a way to get read-access to your SBCL-rucksack tree or a current snapshot? At the moment I'm developing an application for SBCL. So I don't really care if it is broken on other lisp systems. Thank you. Regards, R?diger Sonderfeld From franks-muc at web.de Wed Jul 19 08:44:42 2006 From: franks-muc at web.de (franks-muc at web.de) Date: Wed, 19 Jul 2006 10:44:42 +0200 Subject: [rucksack-devel] Rucksack error Message-ID: <137061277@web.de> I'm trying to call (test-btree-insert) from test.lisp. The output is: T 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000 11000 12000 13000 14000 15000 16000 17000 18000 19000 20000 and then the error below. This is in Lispworks trial; ACL trial produces the same result. Am I doing something wrong ? Can I hope to resolve this ? Frank Schorr Error: Rucksack error in #. Internal error: Object-id mismatch during GC scan (required: 1664; actual: 3829). 1 (abort) Abort # 2 Retry # 3 Abort job 17 :(BIND-STANDARD-STREAMS-AND-EXECUTE # 2137885C> (FUNCALL-BACKGROUND-JOB-AUX # BACKGROUND-REGION-EVAL (#<2>" 2172EDA4> #<2>> #<2>" 0 offset 6217 2283DF0C> #<2>" 0 offset 6236 2283DF2C> T NIL NIL))) Type :b for backtrace, :c to proceed, or :? for other options TEST-RS 1 : 1 > :b Call to RUCKSACK-ERROR Call to (METHOD RUCKSACK::SCAN-OBJECT (T RUCKSACK::SERIALIZATION-BUFFER T)) Call to (METHOD RUCKSACK::MARK-ROOT (MARK-AND-SWEEP-HEAP INTEGER)) Call to (METHOD RUCKSACK::MARK-SOME-ROOTS (MARK-AND-SWEEP-HEAP T)) Call to (METHOD RUCKSACK::COLLECT-SOME-GARBAGE (MARK-AND-SWEEP-HEAP T)) Call to (METHOD RUCKSACK::SAVE-OBJECT (T T STANDARD-CACHE T T)) Call to (METHOD RUCKSACK::SAVE-DIRTY-OBJECT (T STANDARD-CACHE STANDARD-TRANSACTION T)) Call to (METHOD TRANSACTION-COMMIT-1 (STANDARD-TRANSACTION STANDARD-CACHE STANDARD-RUCKSACK)) Interpreted call to TEST-BTREE-INSERT Call to SPECIAL::%EVAL-NOHOOK Call to IV:PROCESS-TOP-LEVEL Call to EDITOR::EDITOR-EVAL Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION 3 (HARLEQUIN-COMMON-LISP:SUBFUNCTION 1 EDITOR::REGION-LISP-EVAL)) Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION 1 EDITOR::REGION-LISP-EVAL) Call to EDITOR::WITH-COMPILATION-ENVIRONMENT-AT-POINT-FN Call to EDITOR::REGION-LISP-EVAL Call to EDITOR::BACKGROUND-REGION-EVAL Call to CAPI::FUNCALL-BACKGROUND-JOB-AUX Call to CAPI::BIND-STANDARD-STREAMS-AND-EXECUTE Call to MP::BACKGROUND-EXECUTE-LOOP Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION MP::PROCESS-SG-FUNCTION MP::INITIALIZE-PROCESS-STACK) TEST-RS 2 : 1 > __________________________________________________________________________ Erweitern Sie FreeMail zu einem noch leistungsst?rkeren E-Mail-Postfach! Mehr Infos unter http://freemail.web.de/home/landingpad/?mc=021131 From edi at agharta.de Thu Jul 20 00:15:38 2006 From: edi at agharta.de (Edi Weitz) Date: Thu, 20 Jul 2006 02:15:38 +0200 Subject: [rucksack-devel] Rucksack error In-Reply-To: <137061277@web.de> (franks-muc@web.de's message of "Wed, 19 Jul 2006 10:44:42 +0200") References: <137061277@web.de> Message-ID: On Wed, 19 Jul 2006 10:44:42 +0200, franks-muc at web.de wrote: > I'm trying to call (test-btree-insert) from test.lisp. > The output is: > T 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000 11000 12000 13000 14000 15000 16000 17000 18000 19000 20000 > and then the error below. > This is in Lispworks trial; ACL trial produces the same result. > > Am I doing something wrong ? > Can I hope to resolve this ? After some testing today I'm pretty sure there's a race condition in the garbage collector. I think I have a solution but it's too late for the details now. I'll send a patch tomorrow. (The short version is that the collector should never deallocate objects which are in the current transaction.) Generally, Rucksack is not ready for production-use yet, in case you've expected that. Cheers, Edi. From edi at agharta.de Thu Jul 20 09:37:47 2006 From: edi at agharta.de (Edi Weitz) Date: Thu, 20 Jul 2006 11:37:47 +0200 Subject: [rucksack-devel] More patches Message-ID: Here are two more small patches for Rucksack. The first one fixes all SETF functions which had a wrong return value. The second one fixes a syntax error in WITH-TRANSACTION and makes sure the first return value is what the body returns as is usual with WITH- macros. Note that these patches are relative to what I've sent in June, so they might not work with what's in CVS as nothing has been commited there since May. Just in case I've temporarily set up ViewCVS to give those who are interested access to my "private" version of Rucksack: http://miles.agharta.de/cgi-bin/viewcvs/viewcvs.cgi/rucksack/ No, I'm not volunteering to maintain Rucksack... :) In case you're wondering: Arthur is on vacation, so you probably shouldn't expect too much activity in c-l.net's CVS until mid-August. Cheers, Edi. -------------- next part -------------- A non-text attachment was scrubbed... Name: rucksack1.diff Type: text/x-patch Size: 2905 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: rucksack2.diff Type: text/x-patch Size: 1345 bytes Desc: not available URL: From edi at agharta.de Thu Jul 20 10:01:07 2006 From: edi at agharta.de (Edi Weitz) Date: Thu, 20 Jul 2006 12:01:07 +0200 Subject: [rucksack-devel] Rucksack error In-Reply-To: (Edi Weitz's message of "Thu, 20 Jul 2006 02:15:38 +0200") References: <137061277@web.de> Message-ID: On Thu, 20 Jul 2006 02:15:38 +0200, Edi Weitz wrote: > After some testing today I'm pretty sure there's a race condition in > the garbage collector. OK, here's my analysis of what I think is happening: Suppose you're writing a big aggregate object (like a btree) to the heap. A, B, and C are parts of this object where A is a Rucksack root. A points to B and B points to C, i.e. the garbage collector in its marking phase reaches C through B. Now suppose that A and C have been created pretty early while B has been created much later, i.e. it's far behind in the dirty queue of the transaction. This is not unusual, especially for btrees. When the transaction is committed, A and C get written to disk. HANDLE-WRITTEN-OBJECT adds C to the roots of the heap (A is there anyway) if necessary so it will be marked live. However, this only applies to the /current/ garbage collection. It is not impossible (and this is what happens in the TEST-BTREE-INSERT case) that another GC will be started while B is still not written to disk. This time C will simply be marked dead in the :MARKING-OBJECT-TABLE phase and it won't be marked live in the :SCANNING phase because (B still not being there) it can't be reached from the root A. This will eventually result in C being deallocated and overwritten by other objects in the same transaction commit. That's it... :( Now, what to do about this? The only idea I could come up with is the following: In the :MARKING-OBJECT-TABLE phase never mark objects dead that belong to the current transaction. This assumes that a) we're always within a transaction and b) transactions can't be nested, but I think this is what Rucksack currently does anyway. Still, it looks like a kludge to me as now the garbage collector has to be aware of transactions. There goes the modular design. Any better ideas? Even worse, the idea above won't work with Rucksack in its current form because if you close and then re-open a rucksack, transactions will again be numbered beginning from 1. This makes me wonder why transaction IDs are stored at all because they seem pretty useless. Am I missing something? (I should probably re-read the mailing list archives from May, maybe this was already discussed.) Anyway, I'll try to come up with a solution as outlined above but I'll first change the way transactions are identified. Stay tuned... Cheers, Edi. From edi at agharta.de Thu Jul 20 11:10:32 2006 From: edi at agharta.de (Edi Weitz) Date: Thu, 20 Jul 2006 13:10:32 +0200 Subject: [rucksack-devel] Rucksack error In-Reply-To: (Edi Weitz's message of "Thu, 20 Jul 2006 12:01:07 +0200") References: <137061277@web.de> Message-ID: On Thu, 20 Jul 2006 12:01:07 +0200, Edi Weitz wrote: > but I'll first change the way transactions are identified. Stay > tuned... Attached is a patch for unique transaction IDs. -------------- next part -------------- A non-text attachment was scrubbed... Name: rucksack3.diff Type: text/x-patch Size: 2580 bytes Desc: not available URL: From edi at agharta.de Thu Jul 20 12:18:29 2006 From: edi at agharta.de (Edi Weitz) Date: Thu, 20 Jul 2006 14:18:29 +0200 Subject: [rucksack-devel] Rucksack error In-Reply-To: (Edi Weitz's message of "Thu, 20 Jul 2006 13:10:32 +0200") References: <137061277@web.de> Message-ID: On Thu, 20 Jul 2006 13:10:32 +0200, Edi Weitz wrote: > Attached is a patch for unique transaction IDs. And here's a fix for it... :) Sorry, my first idea was a bit too simplistic. -------------- next part -------------- A non-text attachment was scrubbed... Name: rucksack4.diff Type: text/x-patch Size: 1684 bytes Desc: not available URL: From edi at agharta.de Thu Jul 20 12:48:16 2006 From: edi at agharta.de (Edi Weitz) Date: Thu, 20 Jul 2006 14:48:16 +0200 Subject: [rucksack-devel] Rucksack error In-Reply-To: (Edi Weitz's message of "Thu, 20 Jul 2006 12:01:07 +0200") References: <137061277@web.de> Message-ID: On Thu, 20 Jul 2006 12:01:07 +0200, Edi Weitz wrote: > Anyway, I'll try to come up with a solution as outlined above See attachment. You have to apply the two transaction ID patches first. -------------- next part -------------- A non-text attachment was scrubbed... Name: rucksack5.diff Type: text/x-patch Size: 2338 bytes Desc: not available URL: From edi at agharta.de Thu Jul 20 16:47:03 2006 From: edi at agharta.de (Edi Weitz) Date: Thu, 20 Jul 2006 18:47:03 +0200 Subject: [rucksack-devel] SCAN-CONTENTS Message-ID: This patch adds the missing SCAN-CONTENTS methods (for efficiency). -------------- next part -------------- A non-text attachment was scrubbed... Name: rucksack6.diff Type: text/x-patch Size: 10021 bytes Desc: not available URL: From edi at agharta.de Thu Jul 20 19:08:43 2006 From: edi at agharta.de (Edi Weitz) Date: Thu, 20 Jul 2006 21:08:43 +0200 Subject: [rucksack-devel] Mutating the argument list Message-ID: Here's a small patch for WITH-TRANSACTION which replaces the REMF part. The cited Usenet article in the comment should explain the reason for this change. -------------- next part -------------- A non-text attachment was scrubbed... Name: rucksack7.diff Type: text/x-patch Size: 2054 bytes Desc: not available URL: From edi at agharta.de Thu Jul 20 19:16:49 2006 From: edi at agharta.de (Edi Weitz) Date: Thu, 20 Jul 2006 21:16:49 +0200 Subject: [rucksack-devel] SCAN-CONTENTS In-Reply-To: (Edi Weitz's message of "Thu, 20 Jul 2006 18:47:03 +0200") References: Message-ID: On Thu, 20 Jul 2006 18:47:03 +0200, Edi Weitz wrote: > This patch adds the missing SCAN-CONTENTS methods (for efficiency). Forgot one - see attachment. -------------- next part -------------- A non-text attachment was scrubbed... Name: rucksack8.diff Type: text/x-patch Size: 584 bytes Desc: not available URL: From edi at agharta.de Thu Jul 20 20:49:51 2006 From: edi at agharta.de (Edi Weitz) Date: Thu, 20 Jul 2006 22:49:51 +0200 Subject: [rucksack-devel] Restarts for BTREE-SEARCH Message-ID: Subject says it all. -------------- next part -------------- A non-text attachment was scrubbed... Name: rucksack9.diff Type: text/x-patch Size: 1763 bytes Desc: not available URL: From edi at agharta.de Thu Jul 20 21:32:15 2006 From: edi at agharta.de (Edi Weitz) Date: Thu, 20 Jul 2006 23:32:15 +0200 Subject: [rucksack-devel] Error reporting for btree errors Message-ID: Yes, I'm on a roll today... :) -------------- next part -------------- A non-text attachment was scrubbed... Name: rucksack10.diff Type: text/x-patch Size: 1176 bytes Desc: not available URL: From edi at agharta.de Sun Jul 23 20:00:09 2006 From: edi at agharta.de (Edi Weitz) Date: Sun, 23 Jul 2006 22:00:09 +0200 Subject: [rucksack-devel] GC problems (Was: Rucksack error) In-Reply-To: (Edi Weitz's message of "Thu, 20 Jul 2006 12:01:07 +0200") References: <137061277@web.de> Message-ID: On Thu, 20 Jul 2006 12:01:07 +0200, Edi Weitz wrote: > The only idea I could come up with is the following: In the > :MARKING-OBJECT-TABLE phase never mark objects dead that belong to > the current transaction. This assumes that a) we're always within a > transaction and b) transactions can't be nested, but I think this is > what Rucksack currently does anyway. And c) it ignores the fact that there could be other threads having other transactions opened at the same time. (Or is that forbidden? I hope not.) So, it won't be enough to just check *TRANSACTION*, rather the rucksack object would have to keep track of /all/ open transactions. (And two different threads couldn't open the same on-disk rucksack at the same time, instead you'd have to open it first, then "fork." Or, as an alternative, the IDs of all open transactions have to be on disk as well. Another source of potential race conditions, I'd say.) Hmm... Anyway, I currently think there are more substantial problems with the garbage collector. I'm trying to build a simple test case which demonstrates them. More later. Cheers, Edi. From edi at agharta.de Mon Jul 24 08:32:07 2006 From: edi at agharta.de (Edi Weitz) Date: Mon, 24 Jul 2006 10:32:07 +0200 Subject: [rucksack-devel] GC problems In-Reply-To: (Edi Weitz's message of "Sun, 23 Jul 2006 22:00:09 +0200") References: <137061277@web.de> Message-ID: On Sun, 23 Jul 2006 22:00:09 +0200, Edi Weitz wrote: > Anyway, I currently think there are more substantial problems with > the garbage collector. I'm trying to build a simple test case which > demonstrates them. More later. OK, here is one: (in-package :test-rs) (defun check-gc (n) (with-rucksack (rucksack *test-suite* :if-exists :supersede) (with-transaction () ;; after this, INNER can be reached directly from the root (let* ((inner (p-cons "Waldorf" "Statler")) (root (p-cons 42 inner))) (add-rucksack-root root rucksack))) (with-transaction () (let* ((root (first (rucksack-roots rucksack))) (inner (p-cdr root)) (array (p-make-array n))) ;; after this, INNER can't be reached from the root anymore (setf (p-cdr root) 43) ;; now let the GC do some work (dotimes (i n) (let ((string (format nil "~R" i))) (setf (p-aref array i) (p-cons string string)))) ;; hook INNER back to the root again before we finish the ;; transaction (setf (p-car root) array (p-cdr root) (p-cons 'bar (p-cons 'foo inner))))) ; [***] (with-transaction () (let* ((root (first (rucksack-roots rucksack))) (inner (p-cdr (p-cdr (p-cdr root))))) ;; we expect the list ("Waldorf" "Statler") here (list (p-car inner) (p-cdr inner)))))) If I try to execute CHECK-GC with a high enough value for N (on my machine, 10,000 will suffice), I reproducibly get an "Object-id mismatch" error from Rucksack. What happens is similar to what I described on July 20, but not the same: In the second transaction, the GC has to do a lot of work if N is large enough, one pass won't suffice. But then on the first pass already, INNER can't be reached from the one and only root anymore because it can only be reached through the P-CONS objects created in the [***] line, and these are at the end of the dirty queue and haven't been written to disc when the GC scans the heap for the first time. So, the GC marks INNER dead and frees its space. INNER's block will then be re-allocated for some other object from the dirty queue. Bang... The important difference between the July 20 case and this one is that INNER was not written in the current transaction - it's an "old" object. Still, the GC is wrong when it frees its space. I /think/ there were discussion about similar cases on this mailing list two months ago or so, but IIRC they were about more "esoteric" scenarios where you hold references to persistent objects while you're not within a transaction or somesuch. IMHO, the example above is a completely legitimate usage of Rucksack, though. Cheers, Edi. From edi at agharta.de Mon Jul 24 09:22:16 2006 From: edi at agharta.de (Edi Weitz) Date: Mon, 24 Jul 2006 11:22:16 +0200 Subject: [rucksack-devel] Btrees Message-ID: The attached patch cleans up (at least I hope so) the btree code a bit and adds the missing delete function and some more tests. In particular, I convinced myself that KEY= is really not needed although I said the opposite at the ECLM. Also, the old version of BTREE-NODE-INSERT sometimes split too early because it eagerly split downwards. The new version splits upwards and only if needed. -------------- next part -------------- A non-text attachment was scrubbed... Name: rucksack.diff Type: text/x-patch Size: 31855 bytes Desc: not available URL: From edi at agharta.de Mon Jul 24 15:40:54 2006 From: edi at agharta.de (Edi Weitz) Date: Mon, 24 Jul 2006 17:40:54 +0200 Subject: [rucksack-devel] GC problems In-Reply-To: (Edi Weitz's message of "Mon, 24 Jul 2006 10:32:07 +0200") References: <137061277@web.de> Message-ID: Yeah, I realize I'm soliloquizing... :) OK, I've thought about how to solve this a bit but I haven't succeeded yet. Here are two sketches of approaches I've tried but discarded. Maybe someone else has an idea based on them. In both cases I declare a mixin PERSISTENT-THING for PERSISTENT-DATA, PERSISTENT-OBJECT, and PROXY. The mixin provides the OBJECT-ID and RUCKSACK slots. 1. Hook into the host (Lisp) GC (in an implementation-dependent way, obviously): Whenever a PERSISTENT-THING object is created, annotate its object ID in an IDS-IN-USE structure (for example a hash table) belonging to its rucksack. During (Rucksack) GC, add the IDs in this structure to the roots. When such an object is finalized by the host (Lisp), remove its ID from IDS-IN-USE. The idea is that (live) transient references to persistent objects are also traversed during the scanning phase of the GC. 2. Similar, but portable and coupled to transactions: Whenever a PERSISTENT-THING object is created, annotate its object ID in an IDS-IN-USE structure (for example a hash table) belonging to the current transaction. During (Rucksack) GC, add the IDs in this structure to the roots. IDS-IN-USE will obviously vanish once the transaction is finished. The idea is that transient references to persistent objects which were created in the current transaction are also traversed during the scanning phase of the GC. Both "solutions" fail because objects are in a way written to disk too late - even if an ID belongs to the root set examined by Rucksack's GC, that does not necessarily imply that its descendants will be marked. At the very least, one would have to change the way the GC scanning phase works, perhaps taking the dirty queue into account somehow. In addition, the first solution fails because TRANSACTION-COMMIT is usually not called in the lexical contour that declared the transient references. I have no idea how and if this could be tackled. Again, all this gets even more complicated if we think about concurrent transactions... Some "meta-ideas" about the GC: A. We could abandon the idea of a concurrent GC and only run the GC when there's no transaction, similar to what Plob! does. B. We could abandon the idea of roots and reachability and instead explicitely delete objects, similar to what AllegroCache does. Hmmm.... From alemmens at xs4all.nl Fri Jul 28 10:58:14 2006 From: alemmens at xs4all.nl (Arthur Lemmens) Date: Fri, 28 Jul 2006 12:58:14 +0200 (CEST) Subject: [rucksack-devel] Rucksack error In-Reply-To: <137061277@web.de> References: <137061277@web.de> Message-ID: <8296.80.24.200.223.1154084294.squirrel@webmail.xs4all.nl> Frank Schorr wrote: > Error: Rucksack error in #. > Internal error: Object-id mismatch during GC scan (required: 1664; actual: > 3829). (Sorry for the late reply. I?m on vacation now and reading this in an Internet caf?.) Yes, this is probably a bug in the garbage collector that?s already on my to do list. I hope I?ll get around to fixing it when I?m back from vacation. Arthur Lemmens From edi at agharta.de Fri Jul 28 12:11:18 2006 From: edi at agharta.de (Edi Weitz) Date: Fri, 28 Jul 2006 14:11:18 +0200 Subject: [rucksack-devel] Btrees In-Reply-To: (Edi Weitz's message of "Mon, 24 Jul 2006 11:22:16 +0200") References: Message-ID: On Mon, 24 Jul 2006 11:22:16 +0200, Edi Weitz wrote: > The attached patch cleans up (at least I hope so) the btree code a > bit BTW, you'll notice that I changed your "split downwards" approach to the usual "split upwards" way which is slightly more efficient. It just occurred to me, though, that you might have done this on purpose to implement (a variant of) the Guibas/Sedgewick algorithm. But that would only make sense if you've had plans to implement some kind of locking for concurrent access, wouldn't it?