Skip to content

Commit 437d000

Browse files
Christian Weilbachdgrnbrg
Christian Weilbach
authored andcommitted
Make the system end-to-end async, add cljs support, and add a konserve backend (replikativ#30)
* Add a konserve backend implementation. * Wrap by core.async, add konserve test. * Fix stash mismatch after re-adding of print statements. * Use plain core.async + helpers, port promise, fixes. * Fix examples for cljs. * Readd temporarily for github review limitations. * Add a mixed-ops test for konserve. * Ensure empty store in the beginning. * Use channel for iterators instead of seqs. Preparing first automatic cljs test. * Add a first automatic cljs test for node. * Add property based test for cljs. This has a heavy payload of 1 MiB, working around the lacking async support in test-check: https://dev.clojure.org/jira/browse/TCHECK-128 * Fix the redis backend and benchmark. * Fix missing redis test. * Fix sorted-set benchmark. * Next attempt at fixing sorted-set. * Fix redis test. * Fiddle with multi-lang travis work-around. * Actually build cljs for the test. * Keep dancing with travis. * Integrate node tests into travis. Small cleanups. * Try a performance hack. * Missed cljs macro. * Fix string key support in messaging, one test still failing (?). * Fix string key test indices. * Unify codebase, reset gen-test volume.
1 parent 55fcd65 commit 437d000

16 files changed

+1660
-955
lines changed

.travis.yml

+6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
language: clojure
2+
dist: trusty
23
services:
34
- redis-server
5+
before_install:
6+
- sudo apt-get install nodejs
7+
install:
8+
- lein cljsbuild once
49
env:
510
matrix:
611
- TEST_CMD='lein test'
712
- TEST_CMD='lein bench output --data-structure fractal -- --data-structure b-tree -- --data-structure sorted-set'
813
- TEST_CMD='lein bench output --delete-pattern forward -- --delete-pattern reverse -- --delete-pattern shuffle -- --delete-pattern zero'
14+
- TEST_CMD='node ./test_node.js'
915
script: $TEST_CMD

env/profiling/hitchhiker/bench.clj

+62-61
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[clojure.tools.cli :refer [parse-opts]]
55
[excel-templates.build :as excel]
66
[hitchhiker.redis :as redis]
7-
[hitchhiker.tree.core :as core]
7+
[hitchhiker.tree.core :refer [<?? <? go-try] :as core]
88
[hitchhiker.tree.messaging :as msg])
99
(:import [java.io File FileWriter]))
1010

@@ -17,26 +17,26 @@
1717
(defn core-b-tree
1818
"Returns a b-tree with core insert"
1919
[b backend]
20-
{:structure (core/b-tree (core/->Config b b 0))
20+
{:structure (<?? (core/b-tree (core/->Config b b 0)))
2121
:insert core/insert
2222
:delete core/delete
23-
:flush (fn [x] (core/flush-tree x backend))})
23+
:flush (fn [x] (<?? (core/flush-tree x backend)))})
2424

2525
(defn msg-b-tree
2626
"Returns a b-tree with msg insert"
2727
[b backend]
2828
(let [sqrt-b (long (Math/sqrt b))]
29-
{:structure (core/b-tree(core/->Config sqrt-b b (- b sqrt-b)))
29+
{:structure (<?? (core/b-tree(core/->Config sqrt-b b (- b sqrt-b))))
3030
:insert msg/insert
3131
:delete msg/delete
32-
:flush (fn [x] (core/flush-tree x backend))}))
32+
:flush (fn [x] (<?? (core/flush-tree x backend)))}))
3333

3434
(defn sorted-set-repr
3535
"Returns a sorted set"
3636
[]
3737
{:structure (sorted-map)
38-
:insert assoc
39-
:delete dissoc
38+
:insert (fn [m k v] (go-try (assoc m k v)))
39+
:delete (fn [m k] (go-try (dissoc m k)))
4040
:flush (fn [set]
4141
{:tree set
4242
:stats (atom {})})})
@@ -64,60 +64,61 @@
6464
[n dataset flush-freq datastruct out delete-xform]
6565
(let [{:keys [structure delete insert flush]} datastruct
6666
dataset (take n (:data dataset))]
67-
(loop [[x & data] dataset
68-
t 0
69-
tree structure
70-
last-flush nil
71-
i 0
72-
inserting? true
73-
outputs []]
74-
(let [i' (inc i)
75-
{flushed-tree :tree
76-
stats :stats} (when (zero? (mod i' flush-freq))
77-
(flush tree))
78-
before (System/nanoTime)
79-
tree' (if inserting?
80-
(insert (or flushed-tree tree) x x)
81-
(delete (or flushed-tree tree) x))
82-
after (System/nanoTime)
83-
log-inserts (zero? (mod i' (quot n 100)))
84-
updated-outputs (atom outputs)]
85-
(when log-inserts ;; 1000 pieces
86-
(binding [*out* (:speed out)]
87-
(let [ks (sort (keys last-flush))
88-
avg-ns (float (/ t (quot n 100)))]
89-
(when (zero? i)
90-
(println (str "elements,op,insert_took_avg_ns,"
91-
(str/join "," ks))))
92-
(println (str i' "," (if inserting? "insert" "delete") "," avg-ns
93-
"," (str/join "," (map #(get last-flush %) ks))))
94-
(swap! updated-outputs conj (-> (into {} last-flush)
95-
(assoc :ins-avg-ns avg-ns
96-
(if inserting?
97-
:insert
98-
:delete) true
99-
:n i'))))))
100-
(cond
101-
(seq data)
102-
(recur data
103-
(if log-inserts
104-
0
105-
(+ t (- after before)))
106-
tree'
107-
(if stats (merge-with + last-flush @stats) last-flush)
108-
i'
109-
inserting?
110-
@updated-outputs)
111-
inserting?
112-
(recur (delete-xform dataset)
113-
0
114-
tree'
115-
nil
116-
i'
117-
false
118-
@updated-outputs)
119-
:else
120-
@updated-outputs)))))
67+
(<?? (go-try
68+
(loop [[x & data] dataset
69+
t 0
70+
tree structure
71+
last-flush nil
72+
i 0
73+
inserting? true
74+
outputs []]
75+
(let [i' (inc i)
76+
{flushed-tree :tree
77+
stats :stats} (when (zero? (mod i' flush-freq))
78+
(flush tree))
79+
before (System/nanoTime)
80+
tree' (if inserting?
81+
(<? (insert (or flushed-tree tree) x x))
82+
(<? (delete (or flushed-tree tree) x)))
83+
after (System/nanoTime)
84+
log-inserts (zero? (mod i' (quot n 100)))
85+
updated-outputs (atom outputs)]
86+
(when log-inserts ;; 1000 pieces
87+
(binding [*out* (:speed out)]
88+
(let [ks (sort (keys last-flush))
89+
avg-ns (float (/ t (quot n 100)))]
90+
(when (zero? i)
91+
(println (str "elements,op,insert_took_avg_ns,"
92+
(str/join "," ks))))
93+
(println (str i' "," (if inserting? "insert" "delete") "," avg-ns
94+
"," (str/join "," (map #(get last-flush %) ks))))
95+
(swap! updated-outputs conj (-> (into {} last-flush)
96+
(assoc :ins-avg-ns avg-ns
97+
(if inserting?
98+
:insert
99+
:delete) true
100+
:n i'))))))
101+
(cond
102+
(seq data)
103+
(recur data
104+
(if log-inserts
105+
0
106+
(+ t (- after before)))
107+
tree'
108+
(if stats (merge-with + last-flush @stats) last-flush)
109+
i'
110+
inserting?
111+
@updated-outputs)
112+
inserting?
113+
(recur (delete-xform dataset)
114+
0
115+
tree'
116+
nil
117+
i'
118+
false
119+
@updated-outputs)
120+
:else
121+
@updated-outputs)))))))
121122

122123
(def options
123124
[["-n" "--num-operations NUM_OPS" "The number of elements that will be applied to the data structure"

project.clj

+43-3
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
:url "https://github.com/dgrnbrg/hitchhiker-tree"
44
:license {:name "Eclipse Public License"
55
:url "http://www.eclipse.org/legal/epl-v10.html"}
6-
:dependencies [[org.clojure/clojure "1.7.0"]
6+
:dependencies [[org.clojure/clojure "1.8.0"]
7+
[org.clojure/clojurescript "1.8.51" :scope "provided"]
78
[org.clojure/core.memoize "0.5.8"]
89
[com.taoensso/carmine "2.12.2"]
910
[org.clojure/core.rrb-vector "0.0.11"]
10-
[org.clojure/core.cache "0.6.5"]]
11+
[org.clojure/core.cache "0.6.5"]
12+
13+
[io.replikativ/incognito "0.2.2-SNAPSHOT"]
14+
[io.replikativ/konserve "0.4.9"]]
1115
:aliases {"bench" ["with-profile" "profiling" "run" "-m" "hitchhiker.bench"]}
1216
:jvm-opts ["-server" "-Xmx3700m" "-Xms3700m"]
1317
:profiles {:test
@@ -18,4 +22,40 @@
1822
:dependencies [[criterium "0.4.4"]
1923
[org.clojure/tools.cli "0.3.3"]
2024
[org.clojure/test.check "0.9.0"]
21-
[com.infolace/excel-templates "0.3.3"]]}})
25+
[com.infolace/excel-templates "0.3.3"]]}
26+
:dev {:dependencies [[binaryage/devtools "0.8.2"]
27+
[figwheel-sidecar "0.5.8"]
28+
[com.cemerick/piggieback "0.2.1"]
29+
[org.clojure/test.check "0.9.0"]]
30+
:source-paths ["src" "dev"]
31+
:plugins [[lein-figwheel "0.5.8"]]
32+
:repl-options {; for nREPL dev you really need to limit output
33+
:init (set! *print-length* 50)
34+
:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}}
35+
:clean-targets ^{:protect false} ["resources/public/js/compiled" "target"]
36+
37+
38+
:cljsbuild {:builds
39+
[{:id "dev"
40+
:figwheel true
41+
:source-paths ["src"]
42+
:compiler {:main hitchhiker.tree.core
43+
:asset-path "js/out"
44+
:output-to "resources/public/js/core.js"
45+
:output-dir "resources/public/js/out" }}
46+
;; inspired by datascript project.clj
47+
{:id "test"
48+
:source-paths ["src" "test" "dev"]
49+
:compiler {
50+
:main hitchhiker-tree.konserve-test
51+
:output-to "target/test.js"
52+
:output-dir "target/none"
53+
:optimizations :none
54+
:source-map true
55+
:recompile-dependents false
56+
:parallel-build true
57+
}}
58+
]}
59+
60+
:plugins [[lein-figwheel "0.5.8"]
61+
[lein-cljsbuild "1.1.4" :exclusions [[org.clojure/clojure]]]])

0 commit comments

Comments
 (0)