[New function: get-instances-limit clinton@unknownlamer.org**20080106183329 Identical to elephant:get-instances-by-range, but only returns at most LIMIT instances. The implementation is a bit lame now: it uses a closure that tracks the limit and accumulates the results in a private list. This wastes LIMIT cons since map-index is already allocating the list. A better solution would be to add a :limit argument to the Elephant query functions. ] { hunk ./src/database.lisp 2 + +;;; Basic Query Functions + +(define-condition results-limit-reached (error) + ((count :initarg :count :reader limit-count) + (result :initarg :result :reader limit-result))) + +(defun make-index-mapper (fn limit) + (let ((curr 0) + (results '())) + (lambda (&rest args) + (cond ((= curr limit) + (error 'results-limit-reached + :count curr :result (nreverse results))) + (t (incf curr) + (car (push (apply fn args) results))))))) + +(defgeneric get-instances-limit (class slot-name start end &optional limit)) + +(defmethod get-instances-limit ((class symbol) slot-name start end &optional limit) + (get-instances-limit (find-class class) slot-name start end limit)) + +(defmethod get-instances-limit ((class persistent-metaclass) slot-name start end + &optional limit) + (if limit + (handler-case + (map-inverted-index (make-index-mapper #'elephant::identity2 limit) + class slot-name :start start :end end :collect t) + (results-limit-reached (c) (values (limit-result c) (limit-count c)))) + (get-instances-by-range class slot-name start end))) hunk ./src/packages.lisp 26 + :get-instances-limit }