From 566ba1696505323cd4416a2e70719603eaed1715 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Mon, 13 Dec 2021 12:26:51 +0800 Subject: [PATCH] enhance: add blocks ast cache --- deps.edn | 3 +- src/main/frontend/components/block.cljs | 10 ++++-- src/main/frontend/components/query_table.cljs | 6 +++- src/main/frontend/format/block.cljs | 31 +++++++++++-------- src/main/frontend/handler/editor.cljs | 2 +- src/main/frontend/modules/file/core.cljs | 4 +-- src/main/frontend/state.cljs | 30 ++++++++++++++++-- 7 files changed, 63 insertions(+), 23 deletions(-) diff --git a/deps.edn b/deps.edn index a0b2220fb..75b633eb6 100755 --- a/deps.edn +++ b/deps.edn @@ -37,7 +37,8 @@ camel-snake-kebab/camel-snake-kebab {:mvn/version "0.4.2"} instaparse/instaparse {:mvn/version "1.4.10"} nubank/workspaces {:mvn/version "1.1.1"} - frankiesardo/linked {:mvn/version "1.3.0"}} + frankiesardo/linked {:mvn/version "1.3.0"} + org.clojars.mmb90/cljs-cache {:mvn/version "0.1.4"}} :aliases {:cljs {:extra-paths ["src/dev-cljs/" "src/test/" "src/electron/"] :extra-deps {org.clojure/clojurescript {:mvn/version "1.10.879"} diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 78a03c69f..ab09f2376 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -1812,7 +1812,7 @@ (rum/defc block-content < rum/reactive [config {:block/keys [uuid content children properties scheduled deadline format pre-block?] :as block} edit-input-id block-id slide?] (let [{:block/keys [title body] :as block} (if (:block/title block) block - (merge block (block/parse-title-and-body format pre-block? content))) + (merge block (block/parse-title-and-body uuid format pre-block? content))) collapsed? (get properties :collapsed) block-ref? (:block-ref? config) block-ref-with-title? (and block-ref? (seq title)) @@ -1997,7 +1997,11 @@ parents-props (doall (for [{:block/keys [uuid name content] :as block} parents] (when-not name ; not page - (let [{:block/keys [title body]} (block/parse-title-and-body (:block/format block) (:block/pre-block? block) content)] + (let [{:block/keys [title body]} (block/parse-title-and-body + uuid + (:block/format block) + (:block/pre-block? block) + content)] [block (if (seq title) (->elem :span (map-inline config title)) @@ -2157,7 +2161,7 @@ (not= (select-keys (first (:rum/args old-state)) config-compare-keys) (select-keys (first (:rum/args new-state)) config-compare-keys)))))} [state config {:block/keys [uuid repo children pre-block? top? properties refs heading-level level type format content] :as block}] - (let [block (merge block (block/parse-title-and-body format pre-block? content)) + (let [block (merge block (block/parse-title-and-body uuid format pre-block? content)) body (:block/body block) blocks-container-id (:blocks-container-id config) config (update config :block merge block) diff --git a/src/main/frontend/components/query_table.cljs b/src/main/frontend/components/query_table.cljs index 7bb36e925..0b6453dd7 100644 --- a/src/main/frontend/components/query_table.cljs +++ b/src/main/frontend/components/query_table.cljs @@ -128,7 +128,11 @@ :block ; block title (let [content (:block/content item) - {:block/keys [title]} (block/parse-title-and-body (:block/format item) (:block/pre-block? item) content)] + {:block/keys [title]} (block/parse-title-and-body + (:block/uuid item) + (:block/format item) + (:block/pre-block? item) + content)] (if (seq title) [:element (->elem :div (map-inline config title))] [:string content])) diff --git a/src/main/frontend/format/block.cljs b/src/main/frontend/format/block.cljs index edc55819e..862bf8972 100644 --- a/src/main/frontend/format/block.cljs +++ b/src/main/frontend/format/block.cljs @@ -731,24 +731,29 @@ ([block] (when (map? block) (merge block - (parse-title-and-body (:block/format block) + (parse-title-and-body (:block/uuid block) + (:block/format block) (:block/pre-block? block) (:block/content block))))) - ([format pre-block? content] + ([block-uuid format pre-block? content] (when-not (string/blank? content) (let [content (if pre-block? content (str (config/get-block-pattern format) " " (string/triml content))) - content (property/remove-properties format content) - ast (->> (format/to-edn content format (mldoc/default-config format)) - (map first)) - title (when (heading-block? (first ast)) - (:title (second (first ast)))) - body (vec (if title (rest ast) ast)) - body (drop-while properties-block? body)] - (cond-> - {:block/body body} - title - (assoc :block/title title)))))) + content (property/remove-properties format content)] + (if-let [result (state/get-block-ast block-uuid content)] + result + (let [ast (->> (format/to-edn content format (mldoc/default-config format)) + (map first)) + title (when (heading-block? (first ast)) + (:title (second (first ast)))) + body (vec (if title (rest ast) ast)) + body (drop-while properties-block? body) + result (cond-> + (if (seq body) {:block/body body} {}) + title + (assoc :block/title title))] + (state/add-block-ast-cache! block-uuid content result) + result)))))) (defn macro-subs [macro-content arguments] diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index d48ee6b9d..2c19282b5 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -350,7 +350,7 @@ [{:block/keys [content format left page uuid level pre-block?] :as block}] (let [block (or (and (:db/id block) (db/pull (:db/id block))) block) block (merge block - (block/parse-title-and-body format pre-block? (:block/content block))) + (block/parse-title-and-body uuid format pre-block? (:block/content block))) properties (:block/properties block) real-content (:block/content block) content (if (and (seq properties) real-content (not= real-content content)) diff --git a/src/main/frontend/modules/file/core.cljs b/src/main/frontend/modules/file/core.cljs index f04cb751a..6344aa25b 100644 --- a/src/main/frontend/modules/file/core.cljs +++ b/src/main/frontend/modules/file/core.cljs @@ -24,8 +24,8 @@ (ffirst body)))) (defn transform-content - [{:block/keys [format pre-block? unordered content heading-level left page scheduled deadline parent] :as block} level {:keys [heading-to-list?]}] - (let [{:block/keys [title body]} (block/parse-title-and-body format pre-block? content) + [{:block/keys [uuid format pre-block? unordered content heading-level left page scheduled deadline parent] :as block} level {:keys [heading-to-list?]}] + (let [{:block/keys [title body]} (block/parse-title-and-body uuid format pre-block? content) content (or content "") heading-with-title? (seq title) allowed-block-as-title? (allowed-block-as-title? title body) diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index 96900cca9..dc98f74b6 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -16,7 +16,8 @@ [promesa.core :as p] [rum.core :as rum] [frontend.mobile.util :as mobile] - [frontend.mobile.util :as mobile-util])) + [frontend.mobile.util :as mobile-util] + [cljs.cache :as cache])) (defonce state (let [document-mode? (or (storage/get :document/mode?) false) @@ -188,6 +189,31 @@ :srs/cards-due-count nil}))) +;; block uuid -> {content(String) -> ast} +(def blocks-ast-cache (atom (cache/lru-cache-factory {} :threshold 5000))) +(defn add-block-ast-cache! + [block-uuid content ast] + (when (and block-uuid content ast) + (let [k block-uuid + add-cache! (fn [] + (reset! blocks-ast-cache (cache/evict @blocks-ast-cache block-uuid)) + (reset! blocks-ast-cache (cache/miss @blocks-ast-cache k {content ast})))] + (if (cache/has? @blocks-ast-cache k) + (let [m (cache/lookup @blocks-ast-cache k)] + (if (and (map? m) (get m content)) + (reset! blocks-ast-cache (cache/hit @blocks-ast-cache k)) + (add-cache!))) + (add-cache!))))) + +(defn get-block-ast + [block-uuid content] + (when (and block-uuid content) + (let [k block-uuid] + (when (cache/has? @blocks-ast-cache k) + (let [m (cache/lookup @blocks-ast-cache k)] + (when-let [result (and (map? m) (get m content))] + (reset! blocks-ast-cache (cache/hit @blocks-ast-cache k)) + result)))))) (defn sub [ks] @@ -1587,4 +1613,4 @@ (defn get-visual-viewport-state [] - (:ui/visual-viewport-state @state)) \ No newline at end of file + (:ui/visual-viewport-state @state))