datascript icon indicating copy to clipboard operation
datascript copied to clipboard

Add API for getting single Datom from btset

Open rauhs opened this issue 8 years ago • 1 comments

As discussed on Slack.

Adding something like -slice-one to the btset which is more efficient than -slice would allow more efficient (first (datoms ...)) which is commonly used in entities and transacting.

rauhs avatar Jun 07 '17 11:06 rauhs

This seems to work:

(defn slice-one
  "Like slice but returns a single Datom."
  ([btset key] (slice-one btset key (.-comparator btset)))
  ([btset key cmp]
   (loop [node (.-root btset)
          path empty-path
          level (.-shift btset)]
     (let [keys-l (node-len node)]
       (if (== 0 level)
         (let [keys (.-keys ^Leaf node)
               idx (binary-search-l cmp keys (dec keys-l) key)]
           (when (and (not (== keys-l idx))
                      ;; Check if we actually found it:
                      (zero? (cmp key (aget keys idx))))
             (aget keys idx)))
         (let [keys (.-keys ^Node node)
               idx (binary-search-l cmp keys (- keys-l 2) key)]
           (recur (aget (.-pointers node) idx)
                  (path-set path level idx)
                  (- level level-shift))))))))

Avoid the rseek and any more traversal. This can now be used in entity and in the db transacting code. It'd probably also be good to add -datom to IIndexAccess

rauhs avatar Jun 07 '17 18:06 rauhs