Skip to content

Instantly share code, notes, and snippets.

@dakrone
Created February 25, 2011 02:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dakrone/843310 to your computer and use it in GitHub Desktop.
Save dakrone/843310 to your computer and use it in GitHub Desktop.
Collapse page results into a lazy-seq that only fetches when needed
(ns lazywindow.core)
;; Lazily fetch page results as needed
;; How many results in a page
(def page-size 5)
(defn get-page*
"Retrieve a vector of results for a page"
[page-num]
(println :fetching-page page-num)
(flush)
(Thread/sleep 500)
;; this is used to simulate actually getting a page of results
(cond
(= page-num 0) [:a :b :c :d :f]
(= page-num 1) [:g :h :i :j :k]
(= page-num 2) [:l :m :n :o :p]
(= page-num 3) [:q :r :s :t :u]))
(def get-page (memoize get-page*))
(defn get-result
"Given a result index, return that result"
[index]
(let [page (int (Math/floor (/ index page-size)))
offset (mod index page-size)]
(get (get-page page) offset :unknown)))
(defn results
"Return a lazy-seq of all results"
([] (results 0))
([n] (lazy-seq (cons (get-result n) (results (inc n))))))
;; Examples, notice that the pages aren't fetched until needed
;; (doall (take 12 (map (fn [x] (println :got x) x) (results))))
;; lazywindow.core> (doall (take 12 (map (fn [x] (println :got x) x) (results))))
;; :fetching-page 0
;; :got :a
;; :got :b
;; :got :c
;; :got :d
;; :got :f
;; :fetching-page 1
;; :got :g
;; :got :h
;; :got :i
;; :got :j
;; :got :k
;; :fetching-page 2
;; :got :l
;; :got :m
;; (:a :b :c :d :f :g :h :i :j :k :l :m)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment