Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit - draft of ring buffer
- Loading branch information
0 parents
commit f2dfad9
Showing
6 changed files
with
114 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/target | ||
/lib | ||
/classes | ||
/checkouts | ||
pom.xml | ||
*.jar | ||
*.class | ||
.lein-deps-sum | ||
.lein-failures | ||
.lein-plugins |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# ring-buffer | ||
|
||
A persistent collection with semantics roughly equivalent to a ring buffer: acts like a queue, but | ||
has a predetermined maximum capacity; items added after that capacity is exceeded implicitly eject | ||
items from the front of the queue to make room. | ||
|
||
Implements all the relevant Clojure interfaces, but none of the java interop interfaces; pull | ||
requests welcome. | ||
|
||
Possible optimization: keep a reference to unused items until some new item overwrites it. This is | ||
easier and faster, but if you have a queue with very large objects (or a very large, mostly-empty | ||
queue), you may see memory leaks. The performance gain is probably not worth it, but I suppose | ||
|
||
## Usage | ||
|
||
```clojure | ||
ring-buffer.core> (into (ring-buffer 3) '(a b)) | ||
(a b) | ||
ring-buffer.core> (into (ring-buffer 3) '(a b c d e)) | ||
(c d e) | ||
ring-buffer.core> (pop (into (ring-buffer 3) '(a b c d e))) | ||
(d e) | ||
ring-buffer.core> (peek (into (ring-buffer 3) '(a b c d e))) | ||
c | ||
``` | ||
|
||
## License | ||
|
||
Copyright © 2012 Alan Malloy | ||
|
||
Distributed under the Eclipse Public License, the same as Clojure. |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Introduction to ring-buffer | ||
|
||
TODO: write [great documentation](http://jacobian.org/writing/great-documentation/what-to-write/) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
(defproject ring-buffer "0.1.0-SNAPSHOT" | ||
:description "Persistent bounded-size queue implementation in Clojure" | ||
:url "http://github.com/amalloy/ring-buffer" | ||
:license {:name "Eclipse Public License" | ||
:url "http://www.eclipse.org/legal/epl-v10.html"} | ||
:dependencies [[org.clojure/clojure "1.4.0"]]) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
(ns ring-buffer.core | ||
(:import (clojure.lang Counted Sequential IPersistentCollection IPersistentStack Reversible IObj) | ||
(java.io Writer))) | ||
|
||
(deftype RingBuffer [^int start ^int len buf meta] | ||
Counted | ||
(count [this] len) | ||
|
||
Sequential ;; tagging interface | ||
|
||
IObj | ||
(withMeta [this m] | ||
(RingBuffer. start len buf m)) | ||
(meta [this] meta) | ||
|
||
Object | ||
(toString [this] | ||
(pr-str (lazy-seq (seq this)))) | ||
|
||
IPersistentStack | ||
(peek [this] | ||
(nth buf (mod start (count buf)))) | ||
(pop [this] | ||
(if (zero? len) | ||
(throw (IllegalStateException. "Can't pop empty queue")) | ||
(RingBuffer. (mod (inc start) (count buf)) (dec len) (assoc buf start nil) meta))) | ||
(empty [this] | ||
(RingBuffer. 0 0 (vec (repeat (count buf) nil)) meta)) | ||
(equiv [this other] | ||
(and (sequential? other) | ||
(or (not (counted? other)) | ||
(= (count this) (count other))) | ||
(= (seq this) (seq other)))) | ||
|
||
IPersistentCollection | ||
(cons [this x] | ||
(if (= len (count buf)) | ||
(RingBuffer. (mod (inc start) len) len (assoc buf start x) meta) | ||
(RingBuffer. start (inc len) (assoc buf (mod (+ start len) (count buf)) x) meta))) | ||
(seq [this] | ||
(seq (for [i (range len)] | ||
(nth buf (mod (+ start i) (count buf))))))) | ||
|
||
(defmethod print-method RingBuffer [b ^Writer w] | ||
(.write w "(") | ||
(loop [b (seq b)] | ||
(when-let [[x & xs] b] | ||
(print-method x w) | ||
(when xs | ||
(.write w " ") | ||
(recur xs)))) | ||
(.write w ")")) | ||
|
||
(defn ring-buffer | ||
"Create an empty ring buffer with the specified [capacity]." | ||
[capacity] | ||
(RingBuffer. 0 0 (vec (repeat capacity nil)) nil)) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
(ns ring-buffer.core-test | ||
(:use clojure.test | ||
ring-buffer.core)) | ||
|
||
(deftest a-test | ||
(testing "FIXME, I fail." | ||
(is (= 0 1)))) |