mirror of
https://github.com/logseq/logseq.git
synced 2026-04-24 22:25:01 +00:00
enhance: replace atom blocks-ast-cache by lrucache
This commit is contained in:
@@ -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))))
|
||||
|
||||
@@ -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]]
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
|
||||
)
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user