Created
March 15, 2012 07:37
-
-
Save trevorc/2042755 to your computer and use it in GitHub Desktop.
Persistent Ring Buffer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns com.caira.util.ringbuffer | |
(:import (clojure.lang Counted IPersistentCollection IPersistentVector | |
Indexed RT SeqIterator Seqable Util) | |
(java.util Collection List))) | |
(defn ^:private iterables-equiv? [^Iterable i1 ^Iterable i2] | |
(let [it1 (.iterator i1) | |
it2 (.iterator i2)] | |
(loop [] | |
(or (not (.hasNext it1)) | |
(when (clojure.lang.Util/equiv (.next it1) (.next it2)) | |
(recur)) | |
false)))) | |
(deftype PersistentRingBuffer [^int offset ^int capacity | |
^IPersistentVector v] | |
Collection | |
List | |
(contains [_ o] (.contains v o)) | |
(containsAll [_ c] (.containsAll v c)) | |
(get [this index] (.nth this index)) | |
(isEmpty [_] (empty? v)) | |
(iterator [this] (SeqIterator. (.seq this))) | |
(size [_] (.count v)) | |
(toArray [this] (RT/seqToArray (.seq this))) | |
Seqable | |
(seq [_] | |
(seq (concat (drop offset v) (take offset v)))) | |
Counted | |
IPersistentCollection | |
(count [this] (count v)) | |
(cons [this o] | |
(PersistentRingBuffer. | |
(mod (inc offset) capacity) | |
capacity | |
(if (= offset (.count this)) | |
(conj v o) | |
(assoc v offset o)))) | |
(empty [_] (PersistentRingBuffer. 0 capacity [])) | |
(equiv [this o] | |
(and (instance? List o) | |
(= (.count this) (.count o)) | |
(iterables-equiv? this o))) | |
Indexed | |
(nth [_ ^int i] | |
(when (>= i capacity) | |
(throw (IndexOutOfBoundsException.))) | |
(nth v (mod (+ i offset) capacity))) | |
(nth [this ^int i ^Object not-found] | |
(if (and (>= i 0) | |
(< i (.count this))) | |
(.nth this) | |
not-found))) | |
(defn ring-buffer [size] | |
(PersistentRingBuffer. 0 size [])) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment