Chronological sort of header tree. Slow. Should use binary search.

This commit is contained in:
Robert C. Martin 2022-05-16 13:33:04 -05:00
parent 16628a91a6
commit 26377873da
2 changed files with 91 additions and 6 deletions

View File

@ -5,6 +5,68 @@
(:import (javax.swing.tree DefaultMutableTreeNode)))
(describe "header tree"
(context "finding chronological insertion point"
(it "returns zero if empty tree"
(let [root (DefaultMutableTreeNode.)
time 1
event-map {}
insertion-point (find-chronological-insertion-point root time event-map)]
(should= 0 insertion-point)))
(it "returns zero if time is earlier than all events in tree"
(let [root (DefaultMutableTreeNode.)
child-id 1
child (DefaultMutableTreeNode. child-id)
_ (.add ^DefaultMutableTreeNode root child)
event-map {child-id {:created-at 10}}
event-time 1 ;earlier than 10
insertion-point (find-chronological-insertion-point root event-time event-map)]
(should= 0 insertion-point)))
(it "returns 1 when event is later than only event in tree"
(let [root (DefaultMutableTreeNode.)
child-id 1
child (DefaultMutableTreeNode. child-id)
_ (.add ^DefaultMutableTreeNode root child)
event-map {child-id {:created-at 10}}
event-time 20 ;later than 10
insertion-point (find-chronological-insertion-point root event-time event-map)]
(should= 1 insertion-point))
)
(it "returns n when event is later than n events in tree"
(let [root (DefaultMutableTreeNode.)
child-id 1
child-1 (DefaultMutableTreeNode. child-id)
child-2 (DefaultMutableTreeNode. (+ 1 child-id))
child-3 (DefaultMutableTreeNode. (+ 2 child-id))
_ (.add ^DefaultMutableTreeNode root child-1)
_ (.add ^DefaultMutableTreeNode root child-2)
_ (.add ^DefaultMutableTreeNode root child-3)
event-map {child-id {:created-at 10}
(+ 1 child-id) {:created-at 10}
(+ 2 child-id) {:created-at 10}}
event-time 20 ;later than 10
insertion-point (find-chronological-insertion-point root event-time event-map)]
(should= 3 insertion-point)))
(it "returns chronological insertion point"
(let [root (DefaultMutableTreeNode.)
child-id 1
child-1 (DefaultMutableTreeNode. child-id)
child-2 (DefaultMutableTreeNode. (+ 1 child-id))
child-3 (DefaultMutableTreeNode. (+ 2 child-id))
_ (.add ^DefaultMutableTreeNode root child-1)
_ (.add ^DefaultMutableTreeNode root child-2)
_ (.add ^DefaultMutableTreeNode root child-3)
event-map {child-id {:created-at 10}
(+ 1 child-id) {:created-at 20}
(+ 2 child-id) {:created-at 30}}
event-time 25
insertion-point (find-chronological-insertion-point root event-time event-map)]
(should= 2 insertion-point))
)
)
(context "finding nodes"
(it "finds nothing in an empty tree"
(let [root (DefaultMutableTreeNode.)

View File

@ -70,16 +70,20 @@
event (get event-map event-id)]
(text! widget (formatters/format-header nicknames event)))))
(declare add-references)
(declare add-references
find-chronological-insertion-point)
(defn add-event [ui-context event]
(let [frame (:frame @ui-context)
event-state @(:event-agent @ui-context)
event-map (:text-event-map event-state)
event-id (:id event)
event-time (:created-at event)
tree (select frame [:#header-tree])
model (config tree :model)
root (.getRoot model)
child-count (.getChildCount root)
insertion-point (find-chronological-insertion-point root event-time event-map)
child (DefaultMutableTreeNode. event-id)]
(.insertNodeInto model child root child-count)
(.insertNodeInto model child root insertion-point)
(.makeVisible tree (TreePath. (.getPath child)))
(swap! ui-context update-in [:node-map event-id] conj child)
(add-references ui-context event)
@ -104,24 +108,43 @@
(swap! ui-context update-in [:node-map id] conj child)
(recur (rest nodes))))))))
(defn find-header-node [root id]
(defn find-chronological-insertion-point [root time event-map]
(loop [insertion-point 0
children (enumeration-seq (.children root))]
(cond
(empty? children)
insertion-point
(>
(->> (first children) .getUserObject (get event-map) :created-at)
time)
insertion-point
:else
(recur (inc insertion-point) (rest children)))))
(defn search-for-node [root matcher]
(loop [children (enumeration-seq (.children root))]
(let [child (first children)]
(cond
(empty? children)
nil
(= id (.getUserObject child))
(matcher (.getUserObject child))
child
:else
(let [found-child (find-header-node child id)]
(let [found-child (search-for-node child matcher)]
(if (some? found-child)
found-child
(recur (rest children)))
))
)))
(defn find-header-node [root id]
(search-for-node root #(= id %)))
(defn id-click [ui-context id]
(let [frame (:frame @ui-context)
tree (select frame [:#header-tree])