Skip to content

Commit

Permalink
perf: cache d/entity result for immutable entities
Browse files Browse the repository at this point in the history
  • Loading branch information
RCmerci committed Dec 27, 2024
1 parent 41f878c commit d36f1c3
Show file tree
Hide file tree
Showing 18 changed files with 181 additions and 81 deletions.
4 changes: 2 additions & 2 deletions .carve/ignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ frontend.ui/_emoji-init-data
frontend.worker.rtc.op-mem-layer/_sync-loop-canceler
;; Used by shadow.cljs
frontend.worker.db-worker/init
;; WIP fn, remove when it's ready
frontend.worker.rtc.asset-sync/<loop-for-assets-sync
;; Future use?
frontend.worker.rtc.hash/hash-blocks
;; Repl fn
frontend.rum/use-atom-in
;; missionary utils
frontend.common.missionary-util/<!
;; Not sure why carve said it's unused...
frontend.flows/current-repo-flow
14 changes: 7 additions & 7 deletions deps/db/src/logseq/db.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@
For shared file graph only fns, use logseq.graph-parser.db"
(:require [clojure.set :as set]
[clojure.string :as string]
[clojure.walk :as walk]
[datascript.core :as d]
[datascript.impl.entity :as de]
[logseq.common.config :as common-config]
[logseq.common.util :as common-util]
[logseq.common.util.namespace :as ns-util]
[logseq.common.util.page-ref :as page-ref]
[logseq.common.uuid :as common-uuid]
[logseq.db.frontend.class :as db-class]
[logseq.db.frontend.delete-blocks :as delete-blocks] ;; Load entity extensions
[logseq.db.frontend.entity-plus]
[logseq.db.frontend.entity-plus :as entity-plus]
[logseq.db.frontend.entity-util :as entity-util]
[logseq.db.frontend.property :as db-property]
[logseq.db.frontend.rules :as rules]
[logseq.db.sqlite.common-db :as sqlite-common-db]
[logseq.db.sqlite.util :as sqlite-util]
[logseq.db.frontend.property :as db-property]
[logseq.common.util.namespace :as ns-util]
[logseq.common.util.page-ref :as page-ref]
[clojure.walk :as walk])
[logseq.db.sqlite.util :as sqlite-util])
(:refer-clojure :exclude [object?]))

(defonce *transact-fn (atom nil))
Expand Down Expand Up @@ -192,7 +192,7 @@

(def get-first-page-by-name sqlite-common-db/get-first-page-by-name)

(def db-based-graph? entity-util/db-based-graph?)
(def db-based-graph? entity-plus/db-based-graph?)

(defn page-exists?
"Returns truthy value if page exists.
Expand Down
5 changes: 3 additions & 2 deletions deps/db/src/logseq/db/frontend/content.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
[logseq.common.util.page-ref :as page-ref]
[datascript.core :as d]
[logseq.common.util :as common-util]
[logseq.db.frontend.entity-util :as entity-util]))
[logseq.db.frontend.entity-util :as entity-util]
[logseq.db.frontend.entity-plus :as entity-plus]))

;; [[uuid]]
(def id-ref-pattern
Expand Down Expand Up @@ -121,7 +122,7 @@
(defn update-block-content
"Replace `[[internal-id]]` with `[[page name]]`"
[db item eid]
(if (entity-util/db-based-graph? db)
(if (entity-plus/db-based-graph? db)
(if-let [content (:block/title item)]
(let [refs (:block/refs (d/entity db eid))]
(assoc item :block/title (id-ref->title-ref content refs false)))
Expand Down
5 changes: 3 additions & 2 deletions deps/db/src/logseq/db/frontend/delete_blocks.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
[logseq.common.util.page-ref :as page-ref]
[datascript.core :as d]
[clojure.string :as string]
[logseq.db.frontend.entity-util :as entity-util]))
[logseq.db.frontend.entity-util :as entity-util]
[logseq.db.frontend.entity-plus :as entity-plus]))

(defn- replace-ref-with-deleted-block-title
[block ref-raw-title]
Expand Down Expand Up @@ -57,7 +58,7 @@
(when (seq retracted-block-ids)
(let [retracted-blocks (map #(d/entity db %) retracted-block-ids)
retracted-tx (build-retracted-tx retracted-blocks)
macros-tx (when-not (entity-util/db-based-graph? db)
macros-tx (when-not (entity-plus/db-based-graph? db)
(mapcat (fn [b]
;; Only delete if last reference
(keep #(when (<= (count (:block/_macros (d/entity db (:db/id %))))
Expand Down
87 changes: 73 additions & 14 deletions deps/db/src/logseq/db/frontend/entity_plus.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,80 @@
;; Disable clj linters since we don't support clj
#?(:clj {:clj-kondo/config {:linters {:unresolved-namespace {:level :off}
:unresolved-symbol {:level :off}}}})
(:require [cljs.core]
#?(:org.babashka/nbb [datascript.db])
(:require #?(:org.babashka/nbb [datascript.db])
[cljs.core]
[datascript.core :as d]
[datascript.impl.entity :as entity :refer [Entity]]
[logseq.db.frontend.content :as db-content]
[logseq.db.frontend.property :as db-property]
[logseq.db.frontend.entity-util :as entity-util]
[frontend.common.missionary-util :as c.m]
[frontend.flows :as flows]
[logseq.common.util.date-time :as date-time-util]
[datascript.core :as d]))

(def db-based-graph? entity-util/db-based-graph?)

(def lookup-entity @#'entity/lookup-entity)
[logseq.db.frontend.entity-util :as entity-util]
[logseq.db.frontend.property :as db-property]
[missionary.core :as m]))

(def immutable-db-idents
"These db-ident entities are immutable,
it means `(db/entity :block/title)` always return same result"
#{:block/created-at :block/updated-at
:block/uuid :block/title :block/tags :block/name :block/format
:block/schema :block/path-refs :block/refs :block/tx-id :block/type
:block/page :block/parent :block/order :block/journal-day :block/closed-value-property
:block/link :block/marker :block/warning :block/collapsed? :block/deadline :block/scheduled :block/level
:block/pre-block? :block/heading-level

:block/_refs :logseq.property/_query

:block.temp/search? :block.temp/ast-title :block.temp/ast-body
:block.temp/fully-loaded? :block.temp/top? :block.temp/bottom?

:db/cardinality :db/ident :db/index :db/valueType

:logseq.kv/db-type

:logseq.property.node/display-type :logseq.property/icon
:logseq.property.asset/type :logseq.property.asset/checksum
:logseq.property/created-from-property

:logseq.class/Query :logseq.class/Journal :logseq.class/Cards :logseq.class/Task})

(def ^:private lookup-entity @#'entity/lookup-entity)

(def ^:private *seen-immutable-entities (volatile! {}))

(defn reset-immutable-entities-cache!
[]
(vreset! *seen-immutable-entities {}))

(c.m/run-background-task
::reset-immutable-entities-cache!
(m/reduce
(fn [_ repo]
(when (some? repo)
(prn :reset-immutable-entities-cache!)
(reset-immutable-entities-cache!)))
flows/current-repo-flow))

(defn entity-memoized
[db eid]
(if (and (qualified-keyword? eid)
(contains? immutable-db-idents eid))
(if-let [e (find @*seen-immutable-entities eid)]
(val e)
(let [r (d/entity db eid)]
(vswap! *seen-immutable-entities assoc eid r)
r))
(d/entity db eid)))

(defn db-based-graph?
"Whether the current graph is db-only"
[db]
(when db
(= "db" (:kv/value (entity-memoized db :logseq.kv/db-type)))))

(defn- get-journal-title
[db e]
(date-time-util/int->journal-title (:block/journal-day e)
(:logseq.property.journal/title-format (d/entity db :logseq.class/Journal))))
(:logseq.property.journal/title-format (entity-memoized db :logseq.class/Journal))))

(defn- get-block-title
[^Entity e k default-value]
Expand All @@ -36,7 +93,7 @@
(let [result (lookup-entity e k default-value)
refs (:block/refs e)
result' (if (and (string? result) refs)
(db-content/id-ref->title-ref result refs search?)
((resolve 'logseq.db.frontend.content/id-ref->title-ref) result refs search?)
result)]
(or result' default-value)))))))

Expand All @@ -51,7 +108,7 @@
result
;; property default value
(when (qualified-keyword? k)
(when-let [property (d/entity db k)]
(when-let [property (entity-memoized db k)]
(let [schema (lookup-entity property :block/schema nil)]
(if (= :checkbox (:type schema))
(lookup-entity property :logseq.property/scalar-default-value nil)
Expand Down Expand Up @@ -107,7 +164,9 @@
[^js this]
(let [v @(.-cache this)
v' (if (:block/title v)
(assoc v :block/title (db-content/id-ref->title-ref (:block/title v) (:block/refs this) (:block.temp/search? this)))
(assoc v :block/title
((resolve 'logseq.db.frontend.content/id-ref->title-ref)
(:block/title v) (:block/refs this) (:block.temp/search? this)))
v)]
(concat (seq v')
(seq (.-kv this)))))
Expand Down
11 changes: 2 additions & 9 deletions deps/db/src/logseq/db/frontend/entity_util.cljs
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
(ns logseq.db.frontend.entity-util
"Lower level entity util fns used across db namespaces"
(:require [datascript.core :as d]
[clojure.string :as string]
(:require [clojure.string :as string]
[datascript.impl.entity :as de])
(:refer-clojure :exclude [object?]))

(defn db-based-graph?
"Whether the current graph is db-only"
[db]
(when db
(= "db" (:kv/value (d/entity db :logseq.kv/db-type)))))

(defn- has-tag?
[entity tag-ident]
(let [tags (:block/tags entity)]
Expand Down Expand Up @@ -92,4 +85,4 @@
:logseq.class/Journal :journal
:logseq.class/Whiteboard :whiteboard
:logseq.class/Page :page}]
(set (map #(ident->type (:db/ident %)) (:block/tags entity)))))
(set (map #(ident->type (:db/ident %)) (:block/tags entity)))))
19 changes: 10 additions & 9 deletions deps/db/src/logseq/db/sqlite/common_db.cljs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
(ns logseq.db.sqlite.common-db
"Common sqlite db fns for browser and node"
(:require [datascript.core :as d]
["path" :as node-path]
(:require ["path" :as node-path]
[clojure.set :as set]
[clojure.string :as string]
[logseq.db.sqlite.util :as sqlite-util]
[logseq.common.util.date-time :as date-time-util]
[logseq.common.util :as common-util]
[datascript.core :as d]
[logseq.common.config :as common-config]
[logseq.common.util :as common-util]
[logseq.common.util.date-time :as date-time-util]
[logseq.db.frontend.entity-plus :as entity-plus]
[logseq.db.frontend.entity-util :as entity-util]
[clojure.set :as set]
[logseq.db.frontend.order :as db-order]))
[logseq.db.frontend.order :as db-order]
[logseq.db.sqlite.util :as sqlite-util]))

(defn- get-pages-by-name
[db page-name]
Expand Down Expand Up @@ -81,7 +82,7 @@

(defn- property-with-values
[db block]
(when (entity-util/db-based-graph? db)
(when (entity-plus/db-based-graph? db)
(let [block (d/entity db (:db/id block))]
(->> (:block/properties block)
vals
Expand Down Expand Up @@ -242,7 +243,7 @@
"Returns current database schema and initial data.
NOTE: This fn is called by DB and file graphs"
[db]
(let [db-graph? (entity-util/db-based-graph? db)
(let [db-graph? (entity-plus/db-based-graph? db)
_ (when db-graph?
(reset! db-order/*max-key (db-order/get-max-order db)))
schema (:schema db)
Expand Down
8 changes: 5 additions & 3 deletions deps/db/src/logseq/db/test/helper.cljs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
(ns ^:node-only logseq.db.test.helper
"Main ns for providing test fns for DB graphs"
(:require [datascript.core :as d]
[logseq.db.frontend.entity-plus :as entity-plus]
[logseq.db.frontend.schema :as db-schema]
[logseq.db.sqlite.build :as sqlite-build]
[logseq.db.sqlite.create-graph :as sqlite-create-graph]
[logseq.db.frontend.schema :as db-schema]))
[logseq.db.sqlite.create-graph :as sqlite-create-graph]))

(defn find-block-by-content
"Find first block by exact block string or by fuzzier regex"
Expand Down Expand Up @@ -43,11 +44,12 @@
[]
(let [conn (d/create-conn db-schema/schema-for-db-based-graph)
_ (d/transact! conn (sqlite-create-graph/build-db-initial-data "{}"))]
(entity-plus/reset-immutable-entities-cache!)
conn))

(defn create-conn-with-blocks
"Create a conn with create-db-conn and then create blocks using sqlite-build"
[opts]
(let [conn (create-conn)
_ (sqlite-build/create-blocks conn opts)]
conn))
conn))
2 changes: 1 addition & 1 deletion deps/outliner/src/logseq/outliner/property.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@

(defn- property-with-position?
[db property-id block position]
(let [property (d/entity db property-id)
(let [property (entity-plus/entity-memoized db property-id)
schema (:block/schema property)]
(and
(= (:position schema) position)
Expand Down
11 changes: 6 additions & 5 deletions deps/outliner/test/logseq/outliner/validate_test.cljs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
(ns logseq.outliner.validate-test
(:require [cljs.test :refer [deftest is are testing]]
(:require [cljs.test :refer [are deftest is testing]]
[datascript.core :as d]
[logseq.outliner.validate :as outliner-validate]
[logseq.db.test.helper :as db-test]))
[logseq.db.frontend.entity-plus :as entity-plus]
[logseq.db.test.helper :as db-test]
[logseq.outliner.validate :as outliner-validate]))

(deftest validate-block-title-unique-for-properties
(let [conn (db-test/create-conn-with-blocks
Expand Down Expand Up @@ -99,8 +100,8 @@
(is (thrown-with-msg?
js/Error
#"Can't change.*built-in"
(outliner-validate/validate-parent-property (d/entity @conn :logseq.class/Task)
[(d/entity @conn :logseq.class/Cards)]))))))
(outliner-validate/validate-parent-property (entity-plus/entity-memoized @conn :logseq.class/Task)
[(entity-plus/entity-memoized @conn :logseq.class/Cards)]))))))

(deftest validate-tags-property
(let [conn (db-test/create-conn-with-blocks
Expand Down
14 changes: 7 additions & 7 deletions deps/publishing/src/logseq/publishing/db.cljs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
(ns logseq.publishing.db
"Provides db fns and associated util fns for publishing"
(:require [datascript.core :as d]
[logseq.db.frontend.rules :as rules]
[clojure.set :as set]
(:require [clojure.set :as set]
[clojure.string :as string]
[logseq.db.frontend.entity-util :as entity-util]
[logseq.db.frontend.malli-schema :as db-malli-schema]))
[datascript.core :as d]
[logseq.db.frontend.entity-plus :as entity-plus]
[logseq.db.frontend.malli-schema :as db-malli-schema]
[logseq.db.frontend.rules :as rules]))

(defn ^:api get-area-block-asset-url
"Returns asset url for an area block used by pdf assets. This lives in this ns
because it is used by this dep and needs to be independent from the frontend app"
[db block page]
(let [db-based? (entity-util/db-based-graph? db)]
(let [db-based? (entity-plus/db-based-graph? db)]
(when-some [uuid' (:block/uuid block)]
(if db-based?
(when-let [image (:logseq.property.pdf/hl-image block)]
Expand Down Expand Up @@ -105,7 +105,7 @@

(defn- hl-type-area-fn
[db]
(if (entity-util/db-based-graph? db)
(if (entity-plus/db-based-graph? db)
(fn [datom]
(and (= :logseq.property.pdf/hl-type (:a datom))
(= (keyword (:v datom)) :area)))
Expand Down
Loading

0 comments on commit d36f1c3

Please sign in to comment.