[elephant-devel] Missing method in elephant.

Alain Picard Dr.Alain.Picard at gmail.com
Tue Jan 4 05:20:20 UTC 2011



I think I discovered a (rather serious!) bug in elephant.
Calling MAP-BTREE with both the :FROM-END and :END
arguments on a BDB store controller leads to this condition:

There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION CURSOR-NEXT-NODUP (2)>
when called with arguments
  (#<DB-BDB::BDB-CURSOR {1006E31451}>).
   [Condition of type SIMPLE-ERROR]


This can be replicated quite simply with the included example test code.

FWIW, changing the definition of MAP-BTREE-FROM-END from 
(defun map-btree-from-end (fn btree start end collect)
  (with-map-wrapper (fn btree collect cur)
    (iterate-map-btree
     :start (if end
		(with-cursor-values (cursor-set-range cur end)
		  (cond ((and exists? (lisp-compare-equal skey end))
			 (cursor-next-nodup cur)
			 (cursor-prev cur))
			(t (cursor-prev cur))))
		(cursor-last cur))
     :continue (or (null start) (lisp-compare>= key start))
     :step (cursor-prev cur))))

to

(defun map-btree-from-end (fn btree start end collect)
  (with-map-wrapper (fn btree collect cur)
    (iterate-map-btree
     :start (if end
		(with-cursor-values (cursor-set-range cur end)
		  (cond ((and exists? (lisp-compare-equal skey end))
			 (cursor-next cur)
			 (cursor-prev cur))
			(t (cursor-prev cur))))
		(cursor-last cur))
     :continue (or (null start) (lisp-compare>= key start))
     :step (cursor-prev cur))))


"fixes" the problem, in my simple test case, but I don't understand
that function deeply enough to be convinced that this is a correct
fix in all circumstances.  If it's only ever called on btrees, which
can contain no duplicates, it's presumably OK, but if it can be called
on indexed trees, then it would not be OK, and we would need a
definition of CURSOR-NEXT-NODUP on regular cursors.

                                --alain


================================================================
;;;;   -*- Mode: lisp; Package: elephant; Syntax: Common-lisp -*-
;;
;; Copyright (C) 2011 TechNo Wait.
;; All rights reserved.
;;
;; Author:  Alain Picard
;;
;;;; Code:

(in-package :elephant)


(defun *test-tree* ()
  (or (get-from-root  :test-tree)
      (add-to-root :test-tree (make-btree))))

(defun ap/prepare-1 ()
  (dotimes (i 10)
    (setf (get-value i (*test-tree*)) (format nil "~:R" i))))

(defun ap-print2 (a b)
  (print (list a b)))

(defun ap/test-1 ()
  (map-btree 'ap-print2 (*test-tree*))
  (print "ap/test-1 OK"))

(defun ap/test-2 ()
  (map-btree 'ap-print2 (*test-tree*) :from-end t)
  (print "ap/test-2 OK"))

(defun ap/test-3 ()
  (map-btree 'ap-print2 (*test-tree*) :from-end t :end 7)
  (print "ap/test-3 OK"))

(defun ap/run-tests ()
  (ap/test-1)
  (ap/test-2)
  (ap/test-3))

#+foo
(eval-when (:load-toplevel :execute)
  (ap/prepare-1)
  (ap/run-tests))



;;; BUG2.LISP ends here

================================================================

-- 
Please read about why Top Posting
is evil at: http://en.wikipedia.org/wiki/Top-posting
and http://www.dickalba.demon.co.uk/usenet/guide/faq_topp.html
Please read about why HTML in email is evil at: http://www.birdhouse.org/etc/evilmail.html





More information about the elephant-devel mailing list