/
odoyle_alt.cljc
75 lines (64 loc) · 2.08 KB
/
odoyle_alt.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
(ns todos.odoyle-alt
(:require [odoyle.rules :as o #?(:clj :refer :cljs :refer-macros) [ruleset]]
[todos.core :as core]))
(def rules
(o/ruleset
{::todo
[:what
[id ::core/text text]
[id ::sub-todos sub-todos {:then not=}]
:then-finally
(->> (o/query-all o/*session* ::todo)
(reduce #(assoc %1 (:id %2) %2) {})
(o/insert o/*session* ::todos ::by-id)
o/reset!)]
::update-sub-todos
[:what
[id ::core/sub-todo-ids sub-todo-ids]
[::todos ::by-id id->todo]
:then
(->> (mapv id->todo sub-todo-ids)
(o/insert o/*session* id ::sub-todos)
o/reset!)]
::root-todo
[:what
[1 ::core/text text]
[1 ::sub-todos sub-todos]]
::update-sub-todo-ids
[:what
[id ::core/parent-id parent-id]
:then-finally
(let [todos (o/query-all o/*session* ::update-sub-todo-ids)
todos-by-parent (group-by :parent-id todos)]
(->> todos
(reduce
(fn [session {:keys [id]}]
(o/insert session id ::core/sub-todo-ids (mapv :id (todos-by-parent id))))
o/*session*)
o/reset!))]}))
(defn init [session]
(-> (reduce (fn [session todo]
(o/insert session (:db/id todo) todo))
session core/todos-alt)
(o/insert ::todos ::by-id {})
o/fire-rules))
(def initial-session
(init (reduce o/add-rule (o/->session) rules)))
(defn query [session]
(first (o/query-all session ::root-todo)))
;; benchmark
(defn tick [session counter]
(let [random-id (inc (mod counter (count core/todos)))
id->todo (-> (o/query-all session ::update-sub-todos)
first
:id->todo)
random-todo-text (:text (id->todo random-id))]
(-> session
(o/insert random-id ::core/text (str random-todo-text " " counter))
o/fire-rules)))
(defn run [iterations]
(loop [session initial-session
counter 0]
(if (= counter iterations)
session
(recur (tick session counter) (inc counter)))))