Created
June 4, 2010 09:41
-
-
Save ejackson/425214 to your computer and use it in GitHub Desktop.
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 | |
#^{:doc "New definitions for a timeseries type"} | |
esjtools.ts | |
(:use clojure.test) | |
(:import (clojure.lang PersistentTreeSet))) | |
;;---------------------------------------------------------------------------- | |
(defprotocol Trim | |
"Trim a timeseries. There are performance advantages to having older+newer | |
rather than just trim in most implementations." | |
(trim-older [ts snip]) | |
(trim-newer [ts snip])) | |
;;---------------------------------------------------------------------------- | |
(deftype Timeseries [dataset] | |
Object | |
(equals [this o] | |
(or (identical? this o) | |
(and (.isInstance Timeseries o) | |
(= dataset (.dataset ^Timeseries o))))) | |
(hashCode [this] | |
(hash dataset)) | |
(toString [this] | |
(str dataset)) | |
;;-------------- | |
clojure.lang.IPersistentCollection | |
(cons [this a] | |
(Timeseries. (conj dataset a))) | |
(empty [this] | |
(Timeseries. (-> dataset empty))) | |
;; How does this differ from equals | |
(equiv [this o] | |
(.equals this o)) | |
(seq [this] | |
(seq dataset)) | |
;;-------------- | |
clojure.lang.IPersistentStack | |
(peek [this] | |
(-> dataset rseq first)) | |
(pop [this] | |
(Timeseries. (disj dataset (peek this)))) | |
;;-------------- | |
clojure.lang.Sorted | |
(comparator [this] | |
(.comparator dataset)) | |
(entryKey [this entry] | |
(.entryKey dataset entry)) | |
(seq [this ascending] | |
(.seq dataset ascending)) | |
(seqFrom [this key ascending] | |
(.seqFrom dataset key ascending)) | |
;;-------------- | |
Trim | |
(trim-older [this snip] | |
(Timeseries. (reduce disj dataset (subseq this < snip)))) | |
(trim-newer [this snip] | |
(Timeseries. (reduce disj dataset (rsubseq this > snip))))) | |
;;--------------------------------------------------------------------------- | |
;; Extra API | |
(defn ts [xs] | |
(Timeseries. (apply sorted-set xs))) | |
;;--------------------------------------------------------------------- | |
;; Tests below | |
(deftest interface-test | |
(let [a (ts [1 2 3]) | |
b (ts [1 2 3]) | |
c (ts [1 2]) | |
d (ts [1]) | |
e (ts []) | |
f (ts [2 3]) | |
g (ts [3])] | |
(testing "Testing conj..." | |
(are [y] (= a y) | |
(conj c 3) | |
(conj e 1 2 3))) | |
(testing "Testing peek..." | |
(are [x y] (= x y) | |
3 (peek a) | |
2 (peek c) | |
nil (peek e))) | |
(testing "Testing subseq..." | |
(are [x y z] (= x (subseq a y z)) | |
[1 2 3] > -2 | |
[1 2 3] > 0 | |
[2 3] > 1 | |
[1 2 3] >= 1 | |
nil > 3 ;; Technically this should be [] | |
nil > 4 | |
[1 2 3] < 4 | |
[1 2 3] <= 3 | |
[1 2] < 3 | |
[] < 0)) | |
(testing "Testing rsubseq..." | |
(are [x y z] (= x (rsubseq a y z)) | |
[3 2 1] > -2 | |
[3 2 1] > 0 | |
[3 2] > 1 | |
[3 2 1] >= 1 | |
[] > 3 | |
[] > 4 | |
[3 2 1] < 4 | |
[3 2 1] <= 3 | |
[2 1] < 3 | |
nil < 0)) ;; Technically this should be [] | |
;; trim | |
(testing "Testing trim..." | |
(are [x y] (= (Timeseries. (apply sorted-set x)) (trim-older a y)) | |
[1 2 3] 0 | |
[1 2 3] 1 | |
[2 3] 2 | |
[3] 3 | |
[] 4) | |
(are [x y] (= (Timeseries. (apply sorted-set x)) (trim-newer a y)) | |
[] 0 | |
[1] 1 | |
[1 2] 2 | |
[1 2 3] 3 | |
[1 2 3] 4)))) | |
(deftest internal-tests | |
(let [a (ts [1 2 3]) | |
b (ts [1 2]) | |
c (ts [1 2 3]) | |
d (ts [1]) | |
e (ts [])] | |
(testing "Testing Object Interface..." | |
(are [x y] (= x y) | |
a a | |
a c) | |
(are [x y] (not (.equals x y)) | |
a b | |
b a) | |
;; hashCode | |
(are [x y] (= (.hashCode x) (.hashCode y)) | |
a a | |
a c) | |
;; toString | |
(is (= (.toString a) (.toString c)))) | |
(testing "clojure.lang.IPersistentCollection..." | |
;; Check the basic functionality | |
(are [x y] (.equals x y) | |
a (.cons b 3) | |
e (.empty a) | |
(seq [1 2 3]) (seq a)) | |
;; Type check these functions | |
(are [x] (= (type e) (type x)) | |
(.cons b 3) | |
(.empty a))) | |
(testing "clojure.lang.IPersistentStack..." | |
;; Check the basic functionality | |
(are [x y] (= x y) | |
3 (.peek a) | |
b (.pop a) | |
d (-> a .pop .pop) | |
;; Empties and nils | |
nil (.peek e) | |
e (.pop e)) | |
;; Type check these functions | |
(are [x] (= (type e) (type x)) | |
(.pop a))) | |
(testing "Sorted..." | |
(are [x y] (= x y) | |
(.seq a true) (seq a) | |
(.seq a true) (seq [1 2 3]) | |
(.seq a false) (seq [3 2 1]) | |
(.seqFrom a 2 true) (seq [2 3]) | |
(.seqFrom a 2 false) (seq [2 1]))))) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment