Chronological sort using java.util.Collections/binarySearch. Much faster.

This commit is contained in:
Robert C. Martin 2022-05-16 17:55:51 -05:00
parent 26377873da
commit d02682dc16
2 changed files with 56 additions and 31 deletions

View File

@ -8,9 +8,9 @@
(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)]
event {:id 99 :created-at 1}
event-map {99 event}
insertion-point (find-chronological-insertion-point root 99 event-map)]
(should= 0 insertion-point)))
(it "returns zero if time is earlier than all events in tree"
@ -18,9 +18,10 @@
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)]
event {:id 99 :created-at 1}
event-map {99 event
child-id {:created-at 10}}
insertion-point (find-chronological-insertion-point root 99 event-map)]
(should= 0 insertion-point)))
(it "returns 1 when event is later than only event in tree"
@ -28,9 +29,10 @@
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)]
event {:id 99 :created-at 20}
event-map {99 event
child-id {:created-at 10}}
insertion-point (find-chronological-insertion-point root 99 event-map)]
(should= 1 insertion-point))
)
@ -43,11 +45,12 @@
_ (.add ^DefaultMutableTreeNode root child-1)
_ (.add ^DefaultMutableTreeNode root child-2)
_ (.add ^DefaultMutableTreeNode root child-3)
event-map {child-id {:created-at 10}
event {:id 99 :created-at 20}
event-map {99 event
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)]
insertion-point (find-chronological-insertion-point root 99 event-map)]
(should= 3 insertion-point)))
(it "returns chronological insertion point"
@ -59,13 +62,32 @@
_ (.add ^DefaultMutableTreeNode root child-1)
_ (.add ^DefaultMutableTreeNode root child-2)
_ (.add ^DefaultMutableTreeNode root child-3)
event-map {child-id {:created-at 10}
event {:id 99 :created-at 25}
event-map {99 event
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)]
insertion-point (find-chronological-insertion-point root 99 event-map)]
(should= 2 insertion-point))
)
(it "returns chronological insertion point when coincident"
(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 {:id 99 :created-at 20}
event-map {99 event
child-id {:created-at 10}
(+ 1 child-id) {:created-at 20}
(+ 2 child-id) {:created-at 30}}
insertion-point (find-chronological-insertion-point root 99 event-map)]
(should= 1 insertion-point))
)
)
(context "finding nodes"
(it "finds nothing in an empty tree"

View File

@ -4,7 +4,8 @@
[more-speech.ui.config :as config]
[more-speech.nostr.util :as util])
(:use [seesaw core font tree])
(:import (javax.swing.tree DefaultMutableTreeNode DefaultTreeModel TreePath)))
(:import (javax.swing.tree DefaultMutableTreeNode DefaultTreeModel TreePath)
(java.util Collections)))
(declare render-event select-article)
@ -77,11 +78,10 @@
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)
insertion-point (find-chronological-insertion-point root event-time event-map)
insertion-point (find-chronological-insertion-point root event-id event-map)
child (DefaultMutableTreeNode. event-id)]
(.insertNodeInto model child root insertion-point)
(.makeVisible tree (TreePath. (.getPath child)))
@ -109,20 +109,23 @@
(recur (rest nodes))))))))
(defn find-chronological-insertion-point [root time event-map]
(loop [insertion-point 0
children (enumeration-seq (.children root))]
(cond
(empty? children)
insertion-point
(defn find-chronological-insertion-point [root event-id event-map]
(let [comparator (fn [node1 node2]
(let [v1 (->> node1 .getUserObject (get event-map) :created-at)
v2 (->> node2 .getUserObject (get event-map) :created-at)]
(compare v1 v2)))
children (enumeration-seq (.children root))
(>
(->> (first children) .getUserObject (get event-map) :created-at)
time)
insertion-point
:else
(recur (inc insertion-point) (rest children)))))
insertion-point (if (nil? children)
0
(Collections/binarySearch children
(DefaultMutableTreeNode. event-id)
comparator))]
(if (neg? insertion-point)
(- (inc insertion-point))
insertion-point)
)
)
(defn search-for-node [root matcher]
(loop [children (enumeration-seq (.children root))]