Better sorting technique, using sorted-set. I expect that will do insertions rather than continual sorting of a large collection. Also reversed the sense of the sort, so latest articles are on top.

This commit is contained in:
Robert C. Martin 2022-04-08 12:28:30 -05:00
parent 2addd2e5f7
commit efe273e32b
5 changed files with 63 additions and 32 deletions

View File

@ -4,7 +4,6 @@
:license {:name "Eclipse Public License" :license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"} :url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.10.3"] :dependencies [[org.clojure/clojure "1.10.3"]
;[quil "3.1.0-SNAPSHOT"]
[quil "4.0.0-SNAPSHOT"] [quil "4.0.0-SNAPSHOT"]
[org.clojure/data.json "2.4.0"] [org.clojure/data.json "2.4.0"]
[org.clojure/core.async "1.5.648"] [org.clojure/core.async "1.5.648"]

View File

@ -15,7 +15,8 @@
"sig" "dddddd"}) "sig" "dddddd"})
(with state {:application (with state {:application
{:text-event-map {} {:text-event-map {}
:chronological-text-events []} :chronological-text-events (make-chronological-text-events)
}
}) })
(it "creates the map of text events by id" (it "creates the map of text events by id"
(let [state (process-text-event @state @event) (let [state (process-text-event @state @event)
@ -24,7 +25,7 @@
event (get event-map 0xdeadbeef :not-in-map)] event (get event-map 0xdeadbeef :not-in-map)]
(should= 1 (count event-map)) (should= 1 (count event-map))
(should= 1 (count text-events)) (should= 1 (count text-events))
(should= 0xdeadbeef (first text-events)) (should= [0xdeadbeef @now] (first text-events))
(should= [0xdeadbeef] (keys event-map)) (should= [0xdeadbeef] (keys event-map))
(should= 0xdeadbeef (:id event)) (should= 0xdeadbeef (:id event))
(should= 0xf00d (:pubkey event)) (should= 0xf00d (:pubkey event))
@ -32,8 +33,7 @@
(should= "the content" (:content event)) (should= "the content" (:content event))
(should= 0xdddddd (:sig event)) (should= 0xdddddd (:sig event))
(should= [[:p "0001" "someurl"] (should= [[:p "0001" "someurl"]
[:e "0002" "anotherurl"]] (:tags event)) [:e "0002" "anotherurl"]] (:tags event))))
))
(it "adds references to tagged articles." (it "adds references to tagged articles."
(let [state (assoc-in @state (let [state (assoc-in @state
@ -45,4 +45,38 @@
(should= [0xdeadbeef] (:references article))) (should= [0xdeadbeef] (:references article)))
) )
(context "sorted set for handling events"
(it "adds one element"
(let [state (add-event @state {:id 10 :created-at 0})]
(should= #{[10 0]} (get-in state [:application :chronological-text-events]))
(should= {10 {:id 10 :created-at 0}} (get-in state [:application :text-event-map]))))
(it "adds two elements in chronological order, should be reversed"
(let [state (add-event @state {:id 10 :created-at 0})
state (add-event state {:id 20 :created-at 1})
]
(should= [[20 1] [10 0]] (seq (get-in state [:application :chronological-text-events])))
(should= {10 {:id 10 :created-at 0}
20 {:id 20 :created-at 1}} (get-in state [:application :text-event-map])))
)
(it "adds two elements in reverse chronological order, should remain."
(let [state (add-event @state {:id 10 :created-at 1})
state (add-event state {:id 20 :created-at 0})
]
(should= [[10 1] [20 0]] (seq (get-in state [:application :chronological-text-events])))
(should= {10 {:id 10 :created-at 1}
20 {:id 20 :created-at 0}} (get-in state [:application :text-event-map])))
)
(it "adds two elements with equal ids"
(let [state (add-event @state {:id 10 :created-at 1})
state (add-event state {:id 10 :created-at 0})
event-map (get-in state [:application :text-event-map])]
(should= [[10 1]] (seq (get-in state [:application :chronological-text-events])))
(should= 1 (count event-map))
)
)
)
) )

View File

@ -3,7 +3,6 @@
[clojure.data.json :as json] [clojure.data.json :as json]
[more-speech.nostr.util :refer [hex-string->num]] [more-speech.nostr.util :refer [hex-string->num]]
[more-speech.ui.widget :as w] [more-speech.ui.widget :as w]
[more-speech.ui.formatters :as f]
)) ))
(s/def ::id number?) (s/def ::id number?)
(s/def ::pubkey number?) (s/def ::pubkey number?)
@ -25,20 +24,20 @@
(defn process-event [{:keys [application] :as state} event] (defn process-event [{:keys [application] :as state} event]
(let [{:keys [_articles nicknames]} application (let [{:keys [_articles nicknames]} application
name-of (fn [pubkey] (get nicknames pubkey pubkey)) _name-of (fn [pubkey] (get nicknames pubkey pubkey))
[_name _subscription-id inner-event :as _decoded-msg] event [_name _subscription-id inner-event :as _decoded-msg] event
{:strs [_id pubkey created_at kind _tags content _sig]} inner-event] {:strs [_id _pubkey _created_at kind _tags _content _sig]} inner-event]
(condp = kind (condp = kind
0 (process-name-event state inner-event) 0 (process-name-event state inner-event)
3 (do 3 (do
;(printf "%s: %s %s %s\n" kind (f/format-time created_at) (name-of pubkey) content) ;(printf "%s: %s %s %s\n" kind (f/format-time created_at) (name-of pubkey) content)
state) state)
1 (do 1 (do
;(printf "%s: %s %s %s\n" kind (f/format-time created_at) (name-of pubkey) (subs content 0 (min 50 (count content)))) ;(printf "%s: %s %s %s\n" kind (f/format-time created_at) (name-of pubkey) (subs content 0 (min 50 (count content))))
(process-text-event state inner-event)) (process-text-event state inner-event))
4 (do 4 (do
;(printf "%s: %s %s %s\n" kind (f/format-time created_at) (name-of pubkey) content) ;(printf "%s: %s %s %s\n" kind (f/format-time created_at) (name-of pubkey) content)
state) state)
(do (prn "unknown event: " event) (do (prn "unknown event: " event)
state)))) state))))
@ -58,7 +57,7 @@
(defn process-references [state {:keys [id tags] :as _event}] (defn process-references [state {:keys [id tags] :as _event}]
(let [e-tags (filter #(= :e (first %)) tags) (let [e-tags (filter #(= :e (first %)) tags)
refs (map second e-tags) refs (map second e-tags)
refs (map hex-string->num (take 1 refs)) ;; Hack. Only the first reference is counted. refs (map hex-string->num (take 1 refs)) ;; Hack. Only the first reference is counted.
] ]
(loop [refs refs (loop [refs refs
state state] state state]
@ -84,22 +83,23 @@
:sig sig :sig sig
:tags (process-tags (get event "tags"))})) :tags (process-tags (get event "tags"))}))
(defn by-event-time [event-map id1 id2] (defn add-event [state event]
(let [event1 (get event-map id1) (let [id (:id event)
event2 (get event-map id2)] time (:created-at event)
(< (get event1 :created-at) state (assoc-in state [:application :text-event-map id] event)
(get event2 :created-at)))) state (update-in state [:application :chronological-text-events] conj [id time])]
state))
(defn process-text-event [state event] (defn process-text-event [state event]
(let [event (translate-text-event event) (let [event (translate-text-event event)
id (:id event) state (add-event state event)
state (assoc-in state [:application :text-event-map id] event) state (w/redraw-widget state [:application :header-window])]
event-map (get-in state [:application :text-event-map] {}) (process-references state event)))
events (get-in state [:application :chronological-text-events] [])
events (conj events id) (defn chronological-event-comparator [[i1 t1] [i2 t2]]
events (sort (partial by-event-time event-map) events) (if (= i1 i2)
state (assoc-in state [:application :chronological-text-events] events) 0
;state (update-in state [:application :chronological-text-events] conj id) (compare t2 t1)))
state (w/redraw-widget state [:application :header-window])
] (defn make-chronological-text-events []
(process-references state event))) (sorted-set-by chronological-event-comparator))

View File

@ -33,7 +33,7 @@
(s/def ::mouse-locked-to #(or (nil? %) (s/coll-of keyword?))) (s/def ::mouse-locked-to #(or (nil? %) (s/coll-of keyword?)))
(s/def ::keyboard-focus #(or (nil? %) (s/coll-of keyword?))) (s/def ::keyboard-focus #(or (nil? %) (s/coll-of keyword?)))
(s/def ::nicknames (s/map-of number? string?)) (s/def ::nicknames (s/map-of number? string?))
(s/def ::chronological-text-events (s/coll-of number?)) (s/def ::chronological-text-events (s/coll-of (s/tuple [number? number?]) :kind set?))
(s/def ::text-event-map (s/map-of number? ::events/event)) (s/def ::text-event-map (s/map-of number? ::events/event))
(s/def ::open-thread (s/coll-of number? :kind set?)) (s/def ::open-thread (s/coll-of number? :kind set?))
(s/def ::this-update (s/coll-of ::path :kind set?)) (s/def ::this-update (s/coll-of ::path :kind set?))
@ -96,7 +96,7 @@
:mouse-locked-to nil :mouse-locked-to nil
:keyboard-focus nil :keyboard-focus nil
:nicknames {} :nicknames {}
:chronological-text-events [] :chronological-text-events (events/make-chronological-text-events)
:text-event-map {} :text-event-map {}
:open-thread #{} :open-thread #{}
:header-window (map->text-window :header-window (map->text-window
@ -134,5 +134,3 @@
:controls (->edit-window-controls)}) :controls (->edit-window-controls)})
) )
)) ))

View File

@ -286,7 +286,7 @@
(defn get-threaded-events [application] (defn get-threaded-events [application]
(let [event-map (:text-event-map application) (let [event-map (:text-event-map application)
events (:chronological-text-events application) events (map first (:chronological-text-events application))
open-thread (:open-thread application) open-thread (:open-thread application)
threaded-events (thread-events events event-map open-thread)] threaded-events (thread-events events event-map open-thread)]
threaded-events threaded-events