From 631fa684484e37c038f37057fec10ef95958cb7a Mon Sep 17 00:00:00 2001 From: Daniel Compton Date: Sun, 28 Jan 2018 10:46:02 +1300 Subject: [PATCH] Incrementally parse traces Rather than re-parsing them every time we get a new set of traces. This is much more efficient and lets us do more useful things in the future. --- src/day8/re_frame/trace/events.cljs | 41 ++++++------- src/day8/re_frame/trace/metamorphic.cljc | 75 ++++++++++++------------ 2 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/day8/re_frame/trace/events.cljs b/src/day8/re_frame/trace/events.cljs index d1bb403..ecc740a 100644 --- a/src/day8/re_frame/trace/events.cljs +++ b/src/day8/re_frame/trace/events.cljs @@ -485,34 +485,35 @@ (rf/reg-event-db :epochs/receive-new-traces (fn [db [_ new-traces]] - (if-let [new-traces (->> (filter log-trace? new-traces) - (sort-by :id))] + (if-let [filtered-traces (->> (filter log-trace? new-traces) + (sort-by :id))] (let [number-of-epochs-to-retain (get-in db [:settings :number-of-epochs]) events-to-ignore (->> (get-in db [:settings :ignored-events]) vals (map :event-id) set) previous-traces (get-in db [:traces :all-traces] []) - all-traces (reduce conj previous-traces new-traces) - matches (:matches (metam/parse-traces all-traces)) - matches (remove (fn [match] + parse-state (get-in db [:epochs :parse-state] metam/initial-parse-state) + all-traces (reduce conj previous-traces filtered-traces) + parse-state (metam/parse-traces parse-state filtered-traces) + new-matches (:partitions parse-state) + previous-matches (get-in db [:epochs :matches] []) + parse-state (assoc parse-state :partitions []) ;; Remove matches we know about + new-matches (remove (fn [match] (let [event (get-in (metam/matched-event match) [:tags :event])] - (contains? events-to-ignore (first event)))) matches) - retained-epochs (take-last number-of-epochs-to-retain matches) - first-id-to-retain (:id (ffirst retained-epochs)) + (contains? events-to-ignore (first event)))) new-matches) + all-matches (reduce conj previous-matches new-matches) + retained-matches (into [] (take-last number-of-epochs-to-retain all-matches)) + first-id-to-retain (:id (ffirst retained-matches)) retained-traces (into [] (drop-while #(< (:id %) first-id-to-retain)) all-traces)] - (rf/dispatch [:epochs/update-epochs {:matches retained-epochs}]) - (assoc-in db [:traces :all-traces] retained-traces)) + (-> db + (assoc-in [:traces :all-traces] retained-traces) + (update :epochs (fn [epochs] + (assoc epochs + :matches retained-matches + :matches-by-id (into {} (map (juxt first-match-id identity)) retained-matches) + :match-ids (mapv first-match-id retained-matches) + :parse-state parse-state))))) ;; Else db))) -(rf/reg-event-db - :epochs/update-epochs - [(rf/path [:epochs])] - (fn [epochs [_ rt]] - (let [matches (:matches rt)] - (assoc epochs - :matches matches - :matches-by-id (into {} (map (juxt first-match-id identity)) matches) - :match-ids (mapv first-match-id matches))))) - (rf/reg-event-fx :epochs/previous-epoch [(rf/path [:epochs])] diff --git a/src/day8/re_frame/trace/metamorphic.cljc b/src/day8/re_frame/trace/metamorphic.cljc index 3c0722d..e34a5ab 100644 --- a/src/day8/re_frame/trace/metamorphic.cljc +++ b/src/day8/re_frame/trace/metamorphic.cljc @@ -185,50 +185,51 @@ (defn quiescent? [event] (= :reagent/quiescent (:op-type event))) -(defn parse-traces [traces] - (let [partitions (reduce - (fn [state event] - (let [current-match (:current-match state) - previous-event (:previous-event state) - no-match? (nil? current-match)] - (-> (cond +(def initial-parse-state + {:current-match nil + :previous-event nil + :partitions []}) - ;; No current match yet, check if this is the start of an epoch - no-match? - (if (start-of-epoch? event) - (assoc state :current-match [event]) - state) +(defn parse-traces [parse-state traces] + (reduce + (fn [state event] + (let [current-match (:current-match state) + previous-event (:previous-event state) + no-match? (nil? current-match)] + (-> (cond - ;; We are in an epoch match, and reagent has gone to a quiescent state - (quiescent? event) - (-> state - (update :partitions conj (conj current-match event)) - (assoc :current-match nil)) + ;; No current match yet, check if this is the start of an epoch + no-match? + (if (start-of-epoch? event) + (assoc state :current-match [event]) + state) - ;; We are in an epoch match, and we have started a new epoch - ;; The previously seen event was the last event of the old epoch, - ;; and we need to start a new one from this event. - (start-of-epoch-and-prev-end? event state) - (-> state - (update :partitions conj (conj current-match previous-event)) - (assoc :current-match [event])) + ;; We are in an epoch match, and reagent has gone to a quiescent state + (quiescent? event) + (-> state + (update :partitions conj (conj current-match event)) + (assoc :current-match nil)) - (event-run? event) - (update state :current-match conj event) + ;; We are in an epoch match, and we have started a new epoch + ;; The previously seen event was the last event of the old epoch, + ;; and we need to start a new one from this event. + (start-of-epoch-and-prev-end? event state) + (-> state + (update :partitions conj (conj current-match previous-event)) + (assoc :current-match [event])) + + (event-run? event) + (update state :current-match conj event) - :else - state - ;; Add a timeout/warning if a match goes on for more than a second? + :else + state + ;; Add a timeout/warning if a match goes on for more than a second? - ) - (assoc :previous-event event)))) - {:current-match nil - :previous-event nil - :partitions []} - traces) - matches (:partitions partitions)] - {:matches matches})) + ) + (assoc :previous-event event)))) + parse-state + traces)) (defn matched-event [match] (->> match