enhance: replace atom blocks-ast-cache by lrucache

This commit is contained in:
rcmerci
2025-04-03 22:14:27 +08:00
parent 1c24fff543
commit d05a8ac07f
5 changed files with 45 additions and 38 deletions

View File

@@ -2,6 +2,9 @@
"Utils about cache"
(:require [cljs.cache :as cache]))
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
(def *profile (volatile! {}))
(defn cache-fn
"Return a cached version of `f`.
cache-key&f-args-fn: return [<cache-key> <args-list-to-f>]"
@@ -9,5 +12,8 @@
(fn [& args]
(let [[cache-k f-args] (apply cache-key&f-args-fn args)
through-value-fn #(apply f f-args)
;; hit? (cache/has? @*cache cache-k)
;; _ (vswap! *profile update-in [[*cache (.-limit ^js @*cache)] (if hit? :hit :miss)] inc)
;; _ (prn (if hit? :hit :mis) cache-k)
cache (vreset! *cache (cache/through through-value-fn @*cache cache-k))]
(cache/lookup cache cache-k))))

View File

@@ -1,7 +1,9 @@
(ns frontend.format.block
"Block code needed by app but not graph-parser"
(:require [cljs-time.format :as tf]
[cljs.cache :as cache]
[clojure.string :as string]
[frontend.common.cache :as common.cache]
[frontend.config :as config]
[frontend.date :as date]
[frontend.db :as db]
@@ -94,6 +96,29 @@ and handles unexpected failure."
block (dissoc block :block.temp/ast-body :block/level)]
(if uuid (assoc block :block/uuid uuid) block))))
(defonce *blocks-ast-cache (volatile! (cache/lru-cache-factory {} :threshold 5000)))
(defn- parse-title-and-body-helper
[format content]
(let [parse-config (mldoc/get-default-config format)
ast (->> (format/to-edn content format parse-config)
(map first))
title (when (gp-block/heading-block? (first ast))
(:title (second (first ast))))
body (vec (if title (rest ast) ast))
body (drop-while gp-property/properties-ast? body)]
(cond->
(if (seq body) {:block.temp/ast-body body} {})
title
(assoc :block.temp/ast-title title))))
(def ^:private cached-parse-title-and-body-helper
(common.cache/cache-fn
*blocks-ast-cache
(fn [format content]
[[format content] [format content]])
parse-title-and-body-helper))
(defn parse-title-and-body
([block]
(when (map? block)
@@ -102,25 +127,11 @@ and handles unexpected failure."
(get block :block/format :markdown)
(:block/pre-block? block)
(:block/title block)))))
([block-uuid 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)))]
(if-let [result (state/get-block-ast block-uuid content)]
result
(let [parse-config (mldoc/get-default-config format)
ast (->> (format/to-edn content format parse-config)
(map first))
title (when (gp-block/heading-block? (first ast))
(:title (second (first ast))))
body (vec (if title (rest ast) ast))
body (drop-while gp-property/properties-ast? body)
result (cond->
(if (seq body) {:block.temp/ast-body body} {})
title
(assoc :block.temp/ast-title title))]
(state/add-block-ast-cache! block-uuid content result)
result))))))
(cached-parse-title-and-body-helper format content)))))
(defn break-line-paragraph?
[[typ break-lines]]

View File

@@ -85,8 +85,17 @@
:custom-key-fn (fn [args result] {:a args :r result}))
(register-fn! 'cljs.core/reset!
:custom-key-fn (fn [args result]
(when (and (coll? result) (> (count result) 10000))
(prn :atom-size (count result) (take 10 result)))
(when (and (coll? result) (> (count result) 5000))
(prn :atom-size (count result) (take 3 result))
(js/console.trace))
nil))
(register-fn! 'cljs.core/vreset!
:custom-key-fn (fn [args result]
(when (and (coll? result) (> (count result) 5000))
(prn :volatile-size (count result) (take 3 result))
(js/console.trace))
nil))
)

View File

@@ -146,7 +146,7 @@
bp (->breakpoint (when (some? rect) (.-width rect)))]
[ref bp])))
(defonce *key->atom-cache (volatile! (cache/lru-cache-factory {} :threshold 1000)))
(defonce *key->atom-cache (volatile! (cache/lru-cache-factory {} :threshold 3000)))
(defn- gen-cached-derived-atom
[ref key' f]

View File

@@ -347,25 +347,6 @@
:db/async-queries (atom {})
:db/latest-transacted-entity-uuids (atom {})})))
;; Block ast state
;; ===============
;; block uuid -> {content(String) -> ast}
(def blocks-ast-cache (atom {}))
(defn add-block-ast-cache!
[block-uuid content ast]
(when (and block-uuid content ast)
(let [new-value (assoc-in @blocks-ast-cache [block-uuid content] ast)
new-value (if (> (count new-value) 10000)
(into {} (take 5000 new-value))
new-value)]
(reset! blocks-ast-cache new-value))))
(defn get-block-ast
[block-uuid content]
(when (and block-uuid content)
(get-in @blocks-ast-cache [block-uuid content])))
;; User configuration getters under :config (and sometimes :me)
;; ========================================
;; TODO: Refactor default config values to be data driven. Currently they are all