Changeset 1088
- Timestamp:
- 01/05/05 12:25:25 (4 years ago)
- Files:
-
- trunk/bknr/src/bknr-indices.asd (modified) (1 diff)
- trunk/bknr/src/indices/indices.lisp (modified) (10 diffs)
- trunk/bknr/src/indices/package.lisp (modified) (1 diff)
- trunk/bknr/src/indices/protocol.lisp (added)
- trunk/bknr/src/indices/skip-list-cursor.lisp (added)
- trunk/bknr/src/skip-list/package.lisp (modified) (1 diff)
- trunk/bknr/src/skip-list/skip-list.lisp (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/bknr/src/bknr-indices.asd
r855 r1088 22 22 :long-description "" 23 23 24 :depends-on (:cl-interpol :bknr-utils : skip-list)24 :depends-on (:cl-interpol :bknr-utils :bknr-skip-list) 25 25 26 26 :components ((:module "indices" 27 27 :components 28 28 ((:file "package") 29 (:file "indices" :depends-on ("package")) 29 (:file "protocol" :depends-on ("package")) 30 (:file "skip-list-cursor" :depends-on ("package" "protocol")) 31 (:file "indices" :depends-on ("package" "protocol")) 30 32 (:file "index-metaclass" 31 33 :depends-on ("package" "indices")))))) trunk/bknr/src/indices/indices.lisp
r989 r1088 4 4 5 5 (in-package :bknr.indices) 6 7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8 ;;; CLOS Protocol for index objects9 10 ;;; A CLOS index is a CLOS class that complies to the following11 ;;; protocol:12 13 (defgeneric index-add (index object)14 (:documentation "Add OBJECT to the INDEX. Throws an ERROR if a15 problem happened while inserting OBJECT."))16 17 (defgeneric index-get (index key)18 (:documentation "Get the object (or the objects) stored under the index-key KEY."))19 20 (defgeneric index-remove (index object)21 (:documentation "Remove OBJECT from the INDEX."))22 23 (defgeneric index-keys (index)24 (:documentation "Returns all the KEYs of the INDEX."))25 26 (defgeneric index-values (index)27 (:documentation "Returns all the objects (or object lists) stored in28 INDEX."))29 30 (defgeneric index-mapvalues (index fun)31 (:documentation "Apply FUN to every object in the INDEX."))32 33 (defgeneric index-reinitialize (new-index old-index)34 (:documentation "Called when the definition of an index is changed."))35 36 (defgeneric index-clear (index)37 (:documentation "Remove all indexed objects from the index."))38 39 (defun index-create (class-name &rest initargs)40 "Instantiate the index object with class CLASS-NAME with INITARGS."41 (apply #'make-instance class-name initargs))42 43 ;;; Adding to an index can throw the following errors:44 45 (define-condition index-existing-error (error)46 ((index :initarg :index :reader condition-index)47 (key :initarg :key :reader condition-key)48 (value :initarg :value :reader condition-value)))49 50 (defmethod print-object ((obj index-existing-error) stream)51 (print-unreadable-object (obj stream :type t)52 (format stream "INDEX: ~A KEY: ~S VALUE: ~S"53 (condition-index obj) (condition-key obj) (condition-value obj))))54 6 55 7 ;;;;;;;;;;;;;;;;;;;; … … 363 315 (slot-name :initarg :slot-name 364 316 :accessor skip-list-index-slot-name) 365 (order :initarg :order366 :accessor skip-list-index-order)367 317 (index-nil :initarg :index-nil :initform nil 368 318 :accessor skip-list-index-index-nil))) 369 319 370 (defmethod initialize-instance :after ((index skip-list-index) &key (type 'string)371 orderslots index-nil &allow-other-keys)320 (defmethod initialize-instance :after ((index skip-list-index) &key 321 slots index-nil &allow-other-keys) 372 322 (unless (<= (length slots) 1) 373 323 (error "Can not create slot-index with more than one slot.")) 374 324 (with-slots (skip-list slot-name) index 375 (let ((order (or order 376 (case type 377 (string #'string-order) 378 (number #'number-order) 379 (integer #'integer-order) 380 (t (error "Unknown skip list index type ~A." type)))))) 381 (setf skip-list (make-skip-list order) 382 slot-name (first slots) 383 (slot-value index 'index-nil) index-nil 384 (slot-value index 'order) order)))) 385 386 (defun string-order (s1 s2) 387 (declare (simple-string s1 s2) (optimize (speed 3) (safety 0))) 388 (let ((l1 (length s1)) 389 (l2 (length s2))) 390 (declare (fixnum l1 l2)) 391 (dotimes (i (min l1 l2) (if (= l1 l2) :equal (< l1 l2))) 392 (declare (fixnum i)) 393 (let ((c1 (schar s1 i)) 394 (c2 (schar s2 i))) 395 (when (char/= c1 c2) 396 (return (char< c1 c2))))))) 397 398 (defun number-order (s1 s2) 399 (declare (number s1 s2) (optimize (speed 3) (safety 0))) 400 (cond ((< s1 s2) T) 401 ((= s1 s2) :EQUAL) 402 (t NIL))) 403 404 (defun integer-order (s1 s2) 405 (declare (integer s1 s2) (optimize (speed 3) (safety 0))) 406 (cond ((< s1 s2) T) 407 ((= s1 s2) :EQUAL) 408 (t NIL))) 325 (setf skip-list (make-instance 'skip-list) 326 slot-name (first slots) 327 (slot-value index 'index-nil) index-nil))) 409 328 410 329 (defmethod print-object ((object skip-list-index) stream) … … 437 356 (let ((slot-name (skip-list-index-slot-name index))) 438 357 (if (slot-boundp object slot-name) 439 (skip-list- remove (slot-value object slot-name)358 (skip-list-delete (slot-value object slot-name) 440 359 (skip-list-index-skip-list index)) 441 360 (warn "Ignoring request to remove object ~a with unbound slot ~A." … … 444 363 (defmethod index-keys ((index skip-list-index)) 445 364 (let ((keys)) 446 ( do-skip-list (key val (skip-list-index-skip-list index))447 (declare (ignore val))448 (push key keys))365 (map-skip-list #'(lambda (key val) (declare (ignore val)) 366 (push key keys)) 367 (skip-list-index-skip-list index)) 449 368 (nreverse keys))) 450 369 451 370 (defmethod index-values ((index skip-list-index)) 452 371 (let ((vals)) 453 ( do-skip-list (key val (skip-list-index-skip-list index))454 (declare (ignore key))455 (push val vals))372 (map-skip-list #'(lambda (key val) (declare (ignore key)) 373 (push val vals)) 374 (skip-list-index-skip-list index)) 456 375 (nreverse vals))) 457 376 … … 462 381 463 382 (defmethod index-clear ((index skip-list-index)) 464 (with-slots (skip-list order) index465 (setf skip-list (make- skip-list order))))383 (with-slots (skip-list) index 384 (setf skip-list (make-instance 'skip-list)))) 466 385 467 386 (defmethod index-reinitialize ((new-index skip-list-index) … … 473 392 (let ((new-list (skip-list-index-skip-list new-index)) 474 393 (old-list (skip-list-index-skip-list old-index))) 475 (if (eql (skip-list-index-order new-index) 476 (skip-list-index-order old-index)) 477 (setf (skip-list-index-skip-list new-index) 478 old-list) 479 (do-skip-list (key val old-list) 480 (setf (skip-list-get key new-list) val))) 394 (setf (skip-list-index-skip-list new-index) old-list) 481 395 new-index)) 482 396 … … 489 403 (slot-name :initarg :slot-name 490 404 :accessor class-skip-index-slot-name) 491 (order :initarg :order492 :accessor class-skip-index-order)493 405 (hash-table :accessor class-skip-index-hash-table))) 494 406 495 407 (defmethod initialize-instance :after ((index class-skip-index) &key (type 'string) 496 408 (test #'eql) 497 orderslots index-superclasses &allow-other-keys)409 slots index-superclasses &allow-other-keys) 498 410 (unless (<= (length slots) 1) 499 411 (error "Can not create slot-index with more than one slot.")) 500 412 (with-slots (hash-table slot-name) index 501 (let ((order (or order 502 (case type 503 (string #'string-order) 504 (number #'number-order) 505 (integer #'integer-order) 506 (t (error "Unknown skip list index type ~A." type)))))) 507 (setf hash-table (make-hash-table :test test) 508 slot-name (first slots) 509 (slot-value index 'index-superclasses) index-superclasses 510 (slot-value index 'order) order)))) 413 (setf hash-table (make-hash-table :test test) 414 slot-name (first slots) 415 (slot-value index 'index-superclasses) index-superclasses))) 511 416 512 417 (defmethod index-add ((index class-skip-index) object) … … 521 426 (let ((skip-list 522 427 (setf (gethash key hash-table) 523 (make- skip-list (class-skip-index-order index)))))428 (make-instance 'skip-list)))) 524 429 (setf (skip-list-get id-key skip-list) object))))))) 525 430 … … 549 454 (when skip-list 550 455 (let ((res)) 551 ( do-skip-list (key val skip-list)552 (declare (ignore key))553 (push val res))456 (map-skip-list #'(lambda (key val) (declare (ignore key)) 457 (push val res)) 458 skip-list) 554 459 (nreverse res))))) 555 460 556 (defun copy-skip-list (skip-list order) 557 (let ((new-skip-list (make-skip-list order))) 558 (do-skip-list (key value skip-list) 559 (setf (skip-list-get key new-skip-list) value)) 461 (defun copy-skip-list (skip-list) 462 (let ((new-skip-list (make-instance 'skip-list))) 463 (map-skip-list #'(lambda (key val) 464 (setf (skip-list-get new-skip-list key) val)) 465 skip-list) 560 466 new-skip-list)) 561 467 … … 563 469 (old-index class-skip-index)) 564 470 (let* ((new-hash (class-skip-index-hash-table new-index)) 565 (old-hash (class-skip-index-hash-table old-index)) 566 (new-order (class-skip-index-order new-index)) 567 (old-order (class-skip-index-order old-index)) 568 (reinit-skip-lists (not (eql new-order old-order)))) 471 (old-hash (class-skip-index-hash-table old-index))) 569 472 (if (eql (hash-table-test old-hash) 570 473 (hash-table-test new-hash)) 571 (let ((new-hash (setf (class-skip-index-hash-table new-index) old-hash))) 572 (when reinit-skip-lists 573 (maphash #'(lambda (key value) 574 (setf (gethash key new-hash) 575 (copy-skip-list value new-order))) 576 new-hash))) 474 (setf (class-skip-index-hash-table new-index) old-hash) 577 475 (maphash #'(lambda (key value) 578 (setf (gethash key new-hash) 579 (if reinit-skip-lists 580 (copy-skip-list value new-order) 581 value))) 476 (setf (gethash key new-hash) value)) 582 477 old-hash)) 583 478 new-index)) trunk/bknr/src/indices/package.lisp
r903 r1088 8 8 :cxml 9 9 :bknr.utils 10 : skip-list10 :bknr.skip-list 11 11 #+cmu 12 12 :ext trunk/bknr/src/skip-list/package.lisp
r1077 r1088 3 3 (defpackage :bknr.skip-list 4 4 (:use :cl) 5 (:export :skip-list)) 6 7 5 (:export 6 :skip-list 7 :skip-list-length 8 :skip-list-insert 9 :skip-list-get 10 :skip-list-delete 11 :skip-list-remove 12 :skip-list-search)) trunk/bknr/src/skip-list/skip-list.lisp
r1086 r1088 1 1 (in-package :bknr.skip-list) 2 3 (defgeneric cursor-next (cursor))4 (defgeneric cursor-previous (cursor))5 (defgeneric cursor-search (cursor key))6 2 7 3 ;;; TODO: … … 40 36 (declare (type fixnum level)))) 41 37 42 ;;; node: key, value, forward38 ;;; A node is a SIMPLE-VECTOR containing KEY, VALUE and the forward pointers 43 39 44 40 (defmacro node-key (node) … … 65 61 66 62 (defclass skip-list () 67 ((header :init arg :header :initform (make-header)63 ((header :initform (make-header) 68 64 :reader skip-list-header :type simple-vector) 65 #+nil 66 (finger :initform (make-header) 67 :reader skip-list-finger :type simple-vector) 69 68 (length :initform 0 :accessor skip-list-length :type fixnum) 70 69 (level :initform 0 :accessor skip-list-level :type fixnum)) … … 174 173 sl)) 175 174 176 (defmethod skip-list-search ((sl skip-list) key &optional not-found) 177 "Search for the node with KEY in the skip-list, and returns its value." 175 ;;; compatibility to old API 176 177 (defmethod skip-list-get (key (sl skip-list)) 178 (skip-list-search sl key)) 179 180 (defmethod (setf skip-list-get) (new-value key (sl skip-list)) 181 (skip-list-insert sl key new-value)) 182 183 (defmethod skip-list-remove (key (sl skip-list)) 184 (skip-list-delete sl key)) 185 186 (defmethod skip-list-search-node ((sl skip-list) key) 187 "Search for the node with KEY in the skip-list." 178 188 (declare (type integer key) 179 189 (optimize (speed 3))) … … 183 193 (let ((result (node-forward node))) 184 194 (if (and result (= (node-key result) key)) 185 (node-value result)186 n ot-found)))195 result 196 nil))) 187 197 (declare (type fixnum level) 188 198 (type simple-vector node)))) 199 200 (defmethod skip-list-after-node ((sl skip-list) key) 201 "Search for the node with key biffer or equal to KEY in the skip-list (for range queries)." 202 (declare (type integer key) 203 (optimize (speed 3))) 204 (do ((level (1- (skip-list-level sl)) (1- level)) 205 (node (skip-list-header sl) (follow-node node key level))) 206 ((< level 0) 207 (let ((result (node-forward node))) 208 (if (and result (>= (node-key result) key)) 209 result 210 nil))) 211 (declare (type fixnum level) 212 (type simple-vector node)))) 213 214 (defmethod skip-list-search ((sl skip-list) key &optional not-found) 215 (let ((result (skip-list-search-node sl key))) 216 (if result 217 (node-value result) 218 not-found))) 219 220 (defun node-before (node key &optional (level 0)) 221 (let ((next (node-forward node level))) 222 (and next (< (node-key next) key)))) 223 224 ;; broken, and not necessarily faster 225 #+nil 226 (defmethod skip-list-search ((sl skip-list) key &optional not-found) 227 (let ((finger (skip-list-finger sl)) 228 node 229 lvl) 230 231 (if (node-before finger key 0) 232 233 (do ((level 1 (1+ level))) 234 ((or (>= level (skip-list-level sl)) 235 (not (node-before finger key level))) 236 (setf node (node-forward finger (1- level)) 237 lvl (1- level)))) 238 239 (do ((level 1 (1+ level))) 240 ((or (>= level (skip-list-level sl)) 241 (node-before finger key level)) 242 243 (if (>= level (skip-list-level sl)) 244 (setf node (skip-list-header sl) 245 lvl (1- (skip-list-level sl))) 246 (setf node (node-forward finger level) 247 lvl level))) 248 #+nil(format t "level: ~A~%" level))) 249 250 #+nil(format t "node: ~A, level ~A~%" node lvl) 251 252 (do ((level lvl (1- level))) 253 ((or (null node) 254 (< level 0)) 255 (when node (setf node (node-forward node 0)))) 256 257 (setf node (follow-node node key level)) 258 (unless (eql node (skip-list-header sl)) 259 #+nil(format t "storing in finger~%") 260 (setf (node-forward finger level) node))) 261 262 (if (and node (= (node-key node) key)) 263 (node-value node) 264 not-found))) 189 265 190 266 (defmethod skip-list-to-list ((sl skip-list))
