From 17901a10325e6c70d9b92ac1d86d3bc99b043299 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Sat, 15 Feb 2020 09:28:44 -0800 Subject: [PATCH] oker --- quad/quadwriter/query.rkt | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/quad/quadwriter/query.rkt b/quad/quadwriter/query.rkt index c0f6df28..82362034 100644 --- a/quad/quadwriter/query.rkt +++ b/quad/quadwriter/query.rkt @@ -39,12 +39,12 @@ ;; if lidx is bigger, search backward [(> start-arg end-arg) (values start-arg (sub1 end-arg) -1)] [else (values start-arg (add1 end-arg) 1)])) - (for/fold ([start-adjusted (- start step)]) ; remove step for reason below + (for/fold ([adjusted-start (- start step)]) ; remove step for reason below ([seen (in-range count)] - #:break (not start-adjusted)) + #:break (not adjusted-start)) ;; add step so we find next matcher ;; and won't re-find the last one immediately - (for/first ([idx (in-range (+ start-adjusted step) end step)] + (for/first ([idx (in-range (+ adjusted-start step) end step)] #:when (pred (vector-ref vec idx))) idx))) @@ -57,21 +57,28 @@ #:result (and vidx (vector-ref vec vidx))) ([query-piece (in-list (parse-query query-str))] #:break (not vidx)) - (match-define (cons pred count) query-piece) + (match-define (cons pred subscript) query-piece) + (define (find start end count) (find-inclusive vec pred start end count)) (define res-idx - (match count - [(== 'this eq?) ; start at querying quad, then search backward - (find-inclusive vec pred (vector-memq starting-q vec) 0)] - [(== 'last eq?) ; search backward from end - (find-inclusive vec pred maxidx 0)] - [(== 'prev eq?) (find-inclusive vec pred (vector-memq starting-q vec) 0 2)] - [(== 'next eq?) (find-inclusive vec pred ((if (pred starting-q) add1 values) (vector-memq starting-q vec)) maxidx)] - [count (find-inclusive vec pred vidx maxidx count)])) + (let loop ([subscript subscript]) + (match subscript + [(== 'this eq?) ; start at querying quad, then search 1 back + (find (vector-memq starting-q vec) 0 1)] + [(== 'last eq?) (loop -1)] + [(== 'prev eq?) ; search 2 back. same algo if starting-q is pred or not. + (find (vector-memq starting-q vec) 0 2)] + [(== 'next eq?) ; search 1 ahead, but if starting-q is also pred, search 2 ahead + (find (vector-memq starting-q vec) maxidx (if (pred starting-q) 2 1))] + [(? negative? count) ; search backward from end + (find maxidx vidx (abs count))] + [(? positive? count) ; seach forward + (find vidx maxidx count)] + [_ #false]))) (define next-maxidx (cond [(not res-idx) maxidx] ;; try searching for next occurence after this one, up to max. - [(find-inclusive vec pred (add1 res-idx) maxidx)] + [(find (add1 res-idx) maxidx 1)] [else maxidx])) (values res-idx next-maxidx))) @@ -112,5 +119,8 @@ (count (query doc "page[1]"))) (check-equal? (count (query doc "page[next]" (query doc "page[2]:line[1]"))) (count (query doc "page[3]"))) + + (check-equal? (count (query doc "page[next]" (query doc "page[2]:line[1]"))) + (count (query doc "page[3]"))) ) \ No newline at end of file