All Downloads are FREE. Search and download functionalities are using the official Maven repository.

clojure.core.rrb_vector.nodes.cljs Maven / Gradle / Ivy

(ns clojure.core.rrb-vector.nodes
  (:refer-clojure :exclude [clone]))

;;; node ops

(def empty-node cljs.core.PersistentVector.EMPTY_NODE)

(defn clone [shift node]
  (VectorNode. (.-edit node) (aclone (.-arr node))))

(defn regular? [node]
  (not (== (alength (.-arr node)) 33)))

;;; ranges

(defn ranges [node]
  (aget (.-arr node) 32))

(defn last-range [node]
  (let [rngs (ranges node)
        i    (dec (aget rngs 32))]
    (aget rngs i)))

(defn regular-ranges [shift cnt]
  (let [step (bit-shift-left 1 shift)
        rngs (make-array 33)]
    (loop [i 0 r step]
      (if (< r cnt)
        (do (aset rngs i r)
            (recur (inc i) (+ r step)))
        (do (aset rngs i cnt)
            (aset rngs 32 (inc i))
            rngs)))))

;;; root overflow

(defn overflow? [root shift cnt]
  (if (regular? root)
    (> (bit-shift-right cnt 5)
       (bit-shift-left 1 shift))
    (let [rngs (ranges root)
          slc  (aget rngs 32)]
      (and (== slc 32)
           (or (== shift 5)
               (recur (aget (.-arr root) (dec slc))
                      (- shift 5)
                      (+ (- (aget rngs 31) (aget rngs 30)) 32)))))))

;;; find nil / 0

(defn index-of-0 [arr]
  (loop [l 0 h 31]
    (if (>= l (dec h))
      (if (zero? (int (aget arr l)))
        l
        (if (zero? (int (aget arr h)))
          h
          32))
      (let [mid (+ l (bit-shift-right (- h l) 1))]
        (if (zero? (int (aget arr mid)))
          (recur l mid)
          (recur (inc mid) h))))))

(defn index-of-nil ^long [arr]
  (loop [l 0 h 31]
    (if (>= l (dec h))
      (if (nil? (aget arr l))
        l
        (if (nil? (aget arr h))
          h
          32))
      (let [mid (+ l (bit-shift-right (- h l) 1))]
        (if (nil? (aget arr mid))
          (recur l mid)
          (recur (inc mid) h))))))

;;; children

(defn first-child [node]
  (aget (.-arr node) 0))

(defn last-child [node]
  (let [arr (.-arr node)]
    (if (regular? node)
      (aget arr (dec (index-of-nil arr)))
      (aget arr (dec (aget (ranges node) 32))))))

(defn remove-leftmost-child [shift parent]
  (let [arr (.-arr parent)]
    (if (nil? (aget arr 1))
      nil
      (let [r?      (regular? parent)
            new-arr (make-array (if r? 32 33))]
        (array-copy arr 1 new-arr 0 31)
        (if-not r?
          (let [rngs     (ranges parent)
                rng0     (aget rngs 0)
                new-rngs (make-array 33)
                lim      (aget rngs 32)]
            (array-copy rngs 1 new-rngs 0 (dec lim))
            (loop [i 0]
              (when (< i lim)
                (aset new-rngs i (- (aget new-rngs i) rng0))
                (recur (inc i))))
            (aset new-rngs 32 (dec (aget rngs 32)))
            (aset new-rngs (dec (aget rngs 32)) 0)
            (aset new-arr 32 new-rngs)))
        (->VectorNode (.-edit parent) new-arr)))))

(defn replace-leftmost-child [shift parent pcnt child d]
  (if (regular? parent)
    (let [step (bit-shift-left 1 shift)
          rng0 (- step d)
          ncnt (- pcnt d)
          li   (bit-and (bit-shift-right shift (dec pcnt)) 0x1f)
          arr      (.-arr parent)
          new-arr  (make-array 33)
          new-rngs (make-array 33)]
      (aset new-arr 0 child)
      (array-copy arr 1 new-arr 1 li)
      (aset new-arr 32 new-rngs)
      (aset new-rngs 0 rng0)
      (aset new-rngs li ncnt)
      (aset new-rngs 32 (inc li))
      (loop [i 1]
        (when (<= i li)
          (aset new-rngs i (+ (aget new-rngs (dec i)) step))
          (recur (inc i))))
      (->VectorNode nil new-arr))
    (let [new-arr  (aclone (.-arr parent))
          rngs     (ranges parent)
          new-rngs (make-array 33)
          li       (dec (aget rngs 32))]
      (aset new-rngs 32 (aget rngs 32))
      (aset new-arr 32 new-rngs)
      (aset new-arr 0 child)
      (loop [i 0]
        (when (<= i li)
          (aset new-rngs i (- (aget rngs i) d))
          (recur (inc i))))
      (->VectorNode nil new-arr))))

(defn replace-rightmost-child [shift parent child d]
  (if (regular? parent)
    (let [arr (.-arr parent)
          i   (dec (index-of-nil arr))]
      (if (regular? child)
        (let [new-arr (aclone arr)]
          (aset new-arr i child)
          (->VectorNode nil new-arr))
        (let [arr     (.-arr parent)
              new-arr (make-array 33)
              step    (bit-shift-left 1 shift)
              rngs    (make-array 33)]
          (aset rngs 32 (inc i))
          (aset new-arr 32 rngs)
          (array-copy arr 0 new-arr 0 i)
          (aset new-arr i child)
          (loop [j 0 r step]
            (when (<= j i)
              (aset rngs j r)
              (recur (inc j) (+ r step))))
          (aset rngs i (last-range child))
          (->VectorNode nil arr))))
    (let [rngs     (ranges parent)
          new-rngs (aclone rngs)
          i        (dec (aget rngs 32))
          new-arr  (aclone (.-arr parent))]
      (aset new-arr i child)
      (aset new-arr 32 new-rngs)
      (aset new-rngs i (+ (aget rngs i) d))
      (->VectorNode nil new-arr))))

;;; fold-tail

(defn new-path* [shift node]
  (let [reg? (== 32 (alength (.-arr node)))
        len  (if reg? 32 33)
        arr  (make-array len)
        rngs (if-not reg?
               (doto (make-array 33)
                 (aset 0 (alength (.-arr node)))
                 (aset 32 1)))
        ret  (->VectorNode nil arr)]
    (loop [arr arr shift shift]
      (if (== shift 5)
        (do (if-not reg?
              (aset arr 32 rngs))
            (aset arr 0 node))
        (let [a (make-array len)
              e (->VectorNode nil a)]
          (aset arr 0 e)
          (if-not reg?
            (aset arr 32 rngs))
          (recur a (- shift 5)))))
    ret))

(defn fold-tail [node shift cnt tail]
  (let [tlen     (alength tail)
        reg?     (and (regular? node) (== tlen 32))
        arr      (.-arr node)
        li       (index-of-nil arr)
        new-arr  (make-array (if reg? 32 33))
        rngs     (if-not (regular? node) (ranges node))
        cret     (if (== shift 5)
                   (->VectorNode nil tail)
                   (fold-tail (aget arr (dec li))
                              (- shift 5)
                              (if (regular? node)
                                (mod cnt (bit-shift-left 1 shift))
                                (let [li (dec (aget rngs 32))]
                                  (if (pos? li)
                                    (- (aget rngs li) (aget rngs (dec li)))
                                    (aget rngs 0))))
                              tail))
        new-rngs (if-not reg?
                   (if rngs
                     (aclone rngs)
                     (regular-ranges shift cnt)))]
    (when-not (and (or (nil? cret) (== shift 5)) (== li 32))
      (array-copy arr 0 new-arr 0 li)
      (when-not reg?
        (if (or (nil? cret) (== shift 5))
          (do (aset new-rngs li
                    (+ (if (pos? li)
                         (aget new-rngs (dec li))
                         (int 0))
                       tlen))
              (aset new-rngs 32 (inc li)))
          (do (when (pos? li)
                (aset new-rngs (dec li)
                      (+ (aget new-rngs (dec li)) tlen)))
              (aset new-rngs 32 li))))
      (if-not reg?
        (aset new-arr 32 new-rngs))
      (if (nil? cret)
        (aset new-arr li (new-path* (- shift 5) (->VectorNode nil tail)))
        (aset new-arr (if (== shift 5) li (dec li)) cret))
      (->VectorNode nil new-arr))))




© 2015 - 2025 Weber Informatics LLC | Privacy Policy