[Add support for exclusive start/end to get-instances-limit clinton@unknownlamer.org**20080205212852] { hunk ./src/database.lisp 9 -(defun make-index-mapper (fn limit &optional (skip 0) result-fn) - (let ((curr 0) - (limit (or limit -1)) ; nil -> no limit - (results (list))) - (lambda (&rest args) - (cond ((= curr limit) - (error 'results-limit-reached - :count curr :result (nreverse results))) - ((< curr skip) (decf skip) nil) - (t (incf curr) - (let ((result (apply fn args))) - (car - (if result-fn - (funcall result-fn result) - (push result results))))))))) - hunk ./src/database.lisp 10 - &key limit skip from-end)) + &key limit skip from-end exclusive) + (:documentation "Fetch items as in + elephant:get-instances-by-range. class, slot-name, start, end, + and :from-end all behave as per the documentation for that + method. In addition extra keyword parameters are supported. + + LIMIT integer - limit total results to LIMIT + SKIP integer - skip the first SKIP results + EXCLUSIVE (or :lower :upper t) - make either start, end, or both + exclusive limits")) hunk ./src/database.lisp 22 - &key limit from-end (skip 0)) + &key limit from-end (skip 0) exclusive) hunk ./src/database.lisp 24 - :limit limit :from-end from-end :skip skip)) + :limit limit :from-end from-end + :skip skip :exclusive exclusive)) hunk ./src/database.lisp 28 - &key limit from-end (skip 0)) - (let ((results (list))) - (labels ((result-pusher (result) (push result results))) + &key limit from-end (skip 0) exclusive) + (let ((results (list)) + (lower-exclusive (or (eq exclusive :lower) + (eq exclusive t))) + (upper-exclusive (or (eq exclusive :upper) + (eq exclusive t)))) + (labels + ((make-index-mapper (fun &optional result-fun) + (let ((curr 0) + (skip skip) + (skip-total skip) + (limit (or limit -1)) ; nil -> no limit + (results (list))) + (labels ((store-result (result) + (incf curr) + (if result-fun + (funcall result-fun result) + (push result results))) + (store-or-skip (result) + (cond ((> skip 0) + (decf skip) nil) + (t (store-result result))))) + (lambda (&rest args) + (cond + ((= curr limit) + (error 'results-limit-reached + :count curr :result (nreverse results))) + ((and (= curr 0) (= skip skip-total)) + (if-bind lower-limit + (or (and (not from-end) lower-exclusive start) + (and from-end upper-exclusive end)) + (let ((result (apply fun args))) + (if (not (equalp (slot-value result slot-name) + lower-limit)) + (store-or-skip result))) + (store-or-skip (apply fun args)))) + ((> skip 0) (decf skip) nil) + (t + (let ((result (apply fun args))) + (cond ((or (and from-end lower-exclusive + (equalp (slot-value result slot-name) + start)) + (and (not from-end) upper-exclusive + (equalp (slot-value result slot-name) + end))) + nil) + (t + (car + (store-result result))))))))))) + (result-pusher (result) (push result results))) hunk ./src/database.lisp 81 - (map-inverted-index (make-index-mapper #'elephant::identity2 - limit skip #'result-pusher) + (map-inverted-index (make-index-mapper + #'elephant::identity2 + #'result-pusher) hunk ./src/packages.lisp 42 - (:import-from :arnesi :it :when-bind) + (:import-from :arnesi :it :when-bind :if-bind) }