[rucksack-cvs] CVS rucksack
charmon
charmon at common-lisp.net
Tue Jan 16 08:47:36 UTC 2007
Update of /project/rucksack/cvsroot/rucksack
In directory clnet:/tmp/cvs-serv24119
Modified Files:
p-btrees.lisp rucksack.asd
Log Message:
rucksack 0.1.3
* use binary search instead of linear search in find-subnode and
find-binding-in-node
--- /project/rucksack/cvsroot/rucksack/p-btrees.lisp 2007/01/16 08:42:24 1.11
+++ /project/rucksack/cvsroot/rucksack/p-btrees.lisp 2007/01/16 08:47:36 1.12
@@ -1,4 +1,4 @@
-;; $Id: p-btrees.lisp,v 1.11 2007/01/16 08:42:24 charmon Exp $
+;; $Id: p-btrees.lisp,v 1.12 2007/01/16 08:47:36 charmon Exp $
(in-package :rucksack)
@@ -497,28 +497,45 @@
"Returns the subnode that contains more information for the given key."
;; Find the first binding with a key >= the given key and return
;; the corresponding subnode.
- ;; EFFICIENCY: We should probably use binary search for this.
- (loop with btree-key< = (btree-key< btree)
- with last-index = (1- (btree-node-index-count node))
- for i to last-index
- for binding = (node-binding node i)
- when (or (= i last-index)
- (funcall btree-key< key (binding-key binding))
- (not (funcall btree-key< (binding-key binding) key)))
- do (return-from find-subnode (binding-value binding)))
- (error "This shouldn't happen."))
+ (let ((btree-key< (btree-key< btree))
+ (last (1- (btree-node-index-count node))))
+ (labels ((binary-search (start end)
+ (let* ((mid (+ start (ash (- end start) -1))))
+ (cond ((= start mid)
+ (let ((start-binding (node-binding node start)))
+ (if (funcall btree-key< (binding-key start-binding) key)
+ (binding-value (node-binding node end))
+ (binding-value start-binding))))
+ (t
+ (let ((mid-binding (node-binding node mid)))
+ (if (funcall btree-key< (binding-key mid-binding) key)
+ (binary-search mid end)
+ (binary-search start mid))))))))
+ (if (funcall btree-key< (binding-key (node-binding node (1- last))) key)
+ (binding-value (node-binding node last))
+ (binary-search 0 last)))))
(defun find-binding-in-node (key node btree)
- (let ((index-count (btree-node-index-count node)))
- (and (plusp index-count)
- (loop with array = (btree-node-index node)
- with btree-key< = (btree-key< btree)
- for i from 0 below index-count
- for candidate = (p-aref array i)
- for candidate-key = (binding-key candidate)
- while (funcall btree-key< candidate-key key)
- finally (when (funcall (btree-key= btree) key candidate-key)
- (return candidate))))))
+ (let ((btree-key< (btree-key< btree))
+ (array (btree-node-index node))
+ (index-count (btree-node-index-count node)))
+ (labels ((binary-search (start end)
+ (let* ((mid (+ start (ash (- end start) -1))))
+ (cond ((= start mid)
+ (let ((start-binding (p-aref array start)))
+ (if (funcall btree-key< (binding-key start-binding) key)
+ (when (< end index-count)
+ (p-aref array end))
+ start-binding)))
+ (t (let ((mid-binding (p-aref array mid)))
+ (if (funcall btree-key< (binding-key mid-binding) key)
+ (binary-search mid end)
+ (binary-search start mid))))))))
+ (when (plusp index-count)
+ (let ((candidate (binary-search 0 index-count)))
+ (when (and candidate
+ (funcall (btree-key= btree) (binding-key candidate) key))
+ candidate))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Insert
--- /project/rucksack/cvsroot/rucksack/rucksack.asd 2007/01/16 08:42:24 1.4
+++ /project/rucksack/cvsroot/rucksack/rucksack.asd 2007/01/16 08:47:36 1.5
@@ -1,9 +1,9 @@
-;;; $Id: rucksack.asd,v 1.4 2007/01/16 08:42:24 charmon Exp $
+;;; $Id: rucksack.asd,v 1.5 2007/01/16 08:47:36 charmon Exp $
(in-package :cl-user)
(asdf:defsystem :rucksack
- :version "0.1.2"
+ :version "0.1.3"
:serial t
:components ((:file "queue")
(:file "package")
More information about the rucksack-cvs
mailing list