@@ -12400,3 +12400,372 @@ reduces them without incurring seq initialization"
1240012400 (identical? " window" *global*) (set! goog/global js/window)
1240112401 (identical? " self" *global*) (set! goog/global js/self)
1240212402 (identical? " global" *global*) (set! goog/global js/global)))
12403+
12404+ ; ; -----------------------------------------------------------------------------
12405+ ; ; Original 2011 Copy-on-Write Types
12406+
12407+ ; ;; Vector
12408+
12409+ (deftype Vector [meta array]
12410+ IWithMeta
12411+ (-with-meta [coll meta] (Vector. meta array))
12412+
12413+ IMeta
12414+ (-meta [coll] meta)
12415+
12416+ IStack
12417+ (-peek [coll]
12418+ (let [count (.-length array)]
12419+ (when (> count 0 )
12420+ (aget array (dec count)))))
12421+ (-pop [coll]
12422+ (if (> (.-length array) 0 )
12423+ (let [new-array (aclone array)]
12424+ (. new-array (pop ))
12425+ (Vector. meta new-array))
12426+ (throw (js/Error. " Can't pop empty vector" ))))
12427+
12428+ ICollection
12429+ (-conj [coll o]
12430+ (let [new-array (aclone array)]
12431+ (.push new-array o)
12432+ (Vector. meta new-array)))
12433+
12434+ IEmptyableCollection
12435+ (-empty [coll] (with-meta (. Vector -EMPTY) meta))
12436+
12437+ ISequential
12438+ IEquiv
12439+ (-equiv [coll other] (equiv-sequential coll other))
12440+
12441+ IHash
12442+ (-hash [coll] (hash-coll coll))
12443+
12444+ ISeqable
12445+ (-seq [coll]
12446+ (when (> (.-length array) 0 )
12447+ (let [vector-seq
12448+ (fn vector-seq [i]
12449+ (lazy-seq
12450+ (when (< i (.-length array))
12451+ (cons (aget array i) (vector-seq (inc i))))))]
12452+ (vector-seq 0 ))))
12453+
12454+ ICounted
12455+ (-count [coll] (.-length array))
12456+
12457+ IIndexed
12458+ (-nth [coll n]
12459+ (if (and (<= 0 n) (< n (.-length array)))
12460+ (aget array n)
12461+ #_(throw (js/Error. (str " No item " n " in vector of length " (.-length array))))))
12462+ (-nth [coll n not-found]
12463+ (if (and (<= 0 n) (< n (.-length array)))
12464+ (aget array n)
12465+ not-found))
12466+
12467+ ILookup
12468+ (-lookup [coll k] (-nth coll k nil ))
12469+ (-lookup [coll k not-found] (-nth coll k not-found))
12470+
12471+ IAssociative
12472+ (-assoc [coll k v]
12473+ (let [new-array (aclone array)]
12474+ (aset new-array k v)
12475+ (Vector. meta new-array)))
12476+
12477+ IVector
12478+ (-assoc-n [coll n val] (-assoc coll n val))
12479+
12480+ IReduce
12481+ (-reduce [v f]
12482+ (ci-reduce array f))
12483+ (-reduce [v f start]
12484+ (ci-reduce array f start))
12485+
12486+ IFn
12487+ (-invoke [coll k]
12488+ (-lookup coll k))
12489+ (-invoke [coll k not-found]
12490+ (-lookup coll k not-found))
12491+
12492+ IPrintWithWriter
12493+ (-pr-writer [coll writer opts] (pr-sequential-writer writer pr-writer " [" " " " ]" opts coll)))
12494+
12495+ (set! (. Vector -EMPTY) (Vector. nil (array )))
12496+
12497+ (set! (. Vector -fromArray) (fn [xs] (Vector. nil xs)))
12498+
12499+ ; The keys field is an array of all keys of this map, in no particular
12500+ ; order. Any string, keyword, or symbol key is used as a property name
12501+ ; to store the value in strobj. If a key is assoc'ed when that same
12502+ ; key already exists in strobj, the old value is overwritten. If a
12503+ ; non-string key is assoc'ed, return a HashMap object instead.
12504+
12505+ (defn- obj-map-contains-key?
12506+ ([k strobj]
12507+ (obj-map-contains-key? k strobj true false ))
12508+ ([k strobj true -val false -val]
12509+ (if (and (goog/isString k) (.hasOwnProperty strobj k))
12510+ true -val
12511+ false -val)))
12512+
12513+ (defn- obj-map-compare-keys [a b]
12514+ (let [a (hash a)
12515+ b (hash b)]
12516+ (cond
12517+ (< a b) -1
12518+ (> a b) 1
12519+ :else 0 )))
12520+
12521+ (deftype ObjMap [meta keys strobj]
12522+ IWithMeta
12523+ (-with-meta [coll meta] (ObjMap. meta keys strobj))
12524+
12525+ IMeta
12526+ (-meta [coll] meta)
12527+
12528+ ICollection
12529+ (-conj [coll entry]
12530+ (if (vector? entry)
12531+ (-assoc coll (-nth entry 0 ) (-nth entry 1 ))
12532+ (reduce -conj
12533+ coll
12534+ entry)))
12535+
12536+ IEmptyableCollection
12537+ (-empty [coll] (with-meta (. ObjMap -EMPTY) meta))
12538+
12539+ IEquiv
12540+ (-equiv [coll other] (equiv-map coll other))
12541+
12542+ IHash
12543+ (-hash [coll] (hash-coll coll))
12544+
12545+ ISeqable
12546+ (-seq [coll]
12547+ (when (pos? (.-length keys))
12548+ (map #(vector % (aget strobj %))
12549+ (.sort keys obj-map-compare-keys))))
12550+
12551+ ICounted
12552+ (-count [coll] (.-length keys))
12553+
12554+ ILookup
12555+ (-lookup [coll k] (-lookup coll k nil ))
12556+ (-lookup [coll k not-found]
12557+ (obj-map-contains-key? k strobj (aget strobj k) not-found))
12558+
12559+ IAssociative
12560+ (-assoc [coll k v]
12561+ (if (goog/isString k)
12562+ (let [new-strobj (goog.object/clone strobj)
12563+ overwrite? (.hasOwnProperty new-strobj k)]
12564+ (aset new-strobj k v)
12565+ (if overwrite?
12566+ (ObjMap. meta keys new-strobj) ; overwrite
12567+ (let [new-keys (aclone keys)] ; append
12568+ (.push new-keys k)
12569+ (ObjMap. meta new-keys new-strobj))))
12570+ ; non-string key. game over.
12571+ (with-meta (into (hash-map k v) (seq coll)) meta)))
12572+ (-contains-key? [coll k]
12573+ (obj-map-contains-key? k strobj))
12574+
12575+ IMap
12576+ (-dissoc [coll k]
12577+ (if (and (goog/isString k) (.hasOwnProperty strobj k))
12578+ (let [new-keys (aclone keys)
12579+ new-strobj (goog.object/clone strobj)]
12580+ (.splice new-keys (scan-array 1 k new-keys) 1 )
12581+ (js-delete new-strobj k)
12582+ (ObjMap. meta new-keys new-strobj))
12583+ coll)) ; key not found, return coll unchanged
12584+
12585+ IFn
12586+ (-invoke [coll k]
12587+ (-lookup coll k))
12588+ (-invoke [coll k not-found]
12589+ (-lookup coll k not-found))
12590+
12591+ IPrintWithWriter
12592+ (-pr-writer [coll writer opts]
12593+ (print-map coll pr-writer writer opts)))
12594+
12595+ (set! (. ObjMap -EMPTY) (ObjMap. nil (array ) (js-obj )))
12596+
12597+ (set! (. ObjMap -fromObject) (fn [ks obj] (ObjMap. nil ks obj)))
12598+
12599+ (defn obj-map
12600+ " keyval => key val
12601+ Returns a new object map with supplied mappings."
12602+ [& keyvals]
12603+ (let [ks (array )
12604+ obj (js-obj )]
12605+ (loop [kvs (seq keyvals)]
12606+ (if kvs
12607+ (do (.push ks (first kvs))
12608+ (gobject/set obj (first kvs) (second kvs))
12609+ (recur (nnext kvs)))
12610+ (.fromObject ObjMap ks obj)))))
12611+
12612+ ; The keys field is an array of all keys of this map, in no particular
12613+ ; order. Each key is hashed and the result used as a property name of
12614+ ; hashobj. Each values in hashobj is actually a bucket in order to handle hash
12615+ ; collisions. A bucket is an array of alternating keys (not their hashes) and
12616+ ; vals.
12617+ (deftype HashMap [meta count hashobj]
12618+ IWithMeta
12619+ (-with-meta [coll meta] (HashMap. meta count hashobj))
12620+
12621+ IMeta
12622+ (-meta [coll] meta)
12623+
12624+ ICollection
12625+ (-conj [coll entry]
12626+ (if (vector? entry)
12627+ (-assoc coll (-nth entry 0 ) (-nth entry 1 ))
12628+ (reduce -conj
12629+ coll
12630+ entry)))
12631+
12632+ IEmptyableCollection
12633+ (-empty [coll] (with-meta (. HashMap -EMPTY) meta))
12634+
12635+ IEquiv
12636+ (-equiv [coll other] (equiv-map coll other))
12637+
12638+ IHash
12639+ (-hash [coll] (hash-coll coll))
12640+
12641+ ISeqable
12642+ (-seq [coll]
12643+ (when (pos? count)
12644+ (let [hashes (.sort (js-keys hashobj))]
12645+ (mapcat #(map vec (partition 2 (aget hashobj %)))
12646+ hashes))))
12647+
12648+ ICounted
12649+ (-count [coll] count)
12650+
12651+ ILookup
12652+ (-lookup [coll k] (-lookup coll k nil ))
12653+ (-lookup [coll k not-found]
12654+ (let [bucket (aget hashobj (hash k))
12655+ i (when bucket (scan-array 2 k bucket))]
12656+ (if i
12657+ (aget bucket (inc i))
12658+ not-found)))
12659+
12660+ IAssociative
12661+ (-assoc [coll k v]
12662+ (let [h (hash k)
12663+ bucket (aget hashobj h)]
12664+ (if bucket
12665+ (let [new-bucket (aclone bucket)
12666+ new-hashobj (goog.object/clone hashobj)]
12667+ (aset new-hashobj h new-bucket)
12668+ (if-let [i (scan-array 2 k new-bucket)]
12669+ (do ; found key, replace
12670+ (aset new-bucket (inc i) v)
12671+ (HashMap. meta count new-hashobj))
12672+ (do ; did not find key, append
12673+ (.push new-bucket k v)
12674+ (HashMap. meta (inc count) new-hashobj))))
12675+ (let [new-hashobj (goog.object/clone hashobj)] ; did not find bucket
12676+ (aset new-hashobj h (array k v))
12677+ (HashMap. meta (inc count) new-hashobj)))))
12678+ (-contains-key? [coll k]
12679+ (let [bucket (aget hashobj (hash k))
12680+ i (when bucket (scan-array 2 k bucket))]
12681+ (if i
12682+ true
12683+ false )))
12684+
12685+ IMap
12686+ (-dissoc [coll k]
12687+ (let [h (hash k)
12688+ bucket (aget hashobj h)
12689+ i (when bucket (scan-array 2 k bucket))]
12690+ (if (not i)
12691+ coll ; key not found, return coll unchanged
12692+ (let [new-hashobj (goog.object/clone hashobj)]
12693+ (if (> 3 (.-length bucket))
12694+ (js-delete new-hashobj h)
12695+ (let [new-bucket (aclone bucket)]
12696+ (.splice new-bucket i 2 )
12697+ (aset new-hashobj h new-bucket)))
12698+ (HashMap. meta (dec count) new-hashobj)))))
12699+
12700+ IFn
12701+ (-invoke [coll k]
12702+ (-lookup coll k))
12703+ (-invoke [coll k not-found]
12704+ (-lookup coll k not-found))
12705+
12706+ IPrintWithWriter
12707+ (-pr-writer [coll writer opts]
12708+ (print-map coll pr-writer writer opts)))
12709+
12710+ (set! (. HashMap -EMPTY) (HashMap. nil 0 (js-obj )))
12711+
12712+ (set! (. HashMap -fromArrays) (fn [ks vs]
12713+ (let [len (.-length ks)]
12714+ (loop [i 0 , out (. HashMap -EMPTY)]
12715+ (if (< i len)
12716+ (recur (inc i) (assoc out (aget ks i) (aget vs i)))
12717+ out)))))
12718+
12719+ (deftype Set [meta hash-map]
12720+ IWithMeta
12721+ (-with-meta [coll meta] (Set. meta hash-map))
12722+
12723+ IMeta
12724+ (-meta [coll] meta)
12725+
12726+ ICollection
12727+ (-conj [coll o]
12728+ (Set. meta (assoc hash-map o nil )))
12729+
12730+ IEmptyableCollection
12731+ (-empty [coll] (with-meta (. Set -EMPTY) meta))
12732+
12733+ IEquiv
12734+ (-equiv [coll other]
12735+ (and
12736+ (set? other)
12737+ (= (count coll) (count other))
12738+ (every? #(contains? coll %)
12739+ other)))
12740+
12741+ IHash
12742+ (-hash [coll] (hash-coll coll))
12743+
12744+ ISeqable
12745+ (-seq [coll] (keys hash-map))
12746+
12747+ ICounted
12748+ (-count [coll] (count (seq coll)))
12749+
12750+ ILookup
12751+ (-lookup [coll v]
12752+ (-lookup coll v nil ))
12753+ (-lookup [coll v not-found]
12754+ (if (-contains-key? hash-map v)
12755+ v
12756+ not-found))
12757+
12758+ ISet
12759+ (-disjoin [coll v]
12760+ (Set. meta (dissoc hash-map v)))
12761+
12762+ IFn
12763+ (-invoke [coll k]
12764+ (-lookup coll k))
12765+ (-invoke [coll k not-found]
12766+ (-lookup coll k not-found))
12767+
12768+ IPrintWithWriter
12769+ (-pr-writer [coll writer opts] (pr-sequential-writer writer pr-writer " #{" " " " }" opts coll)))
12770+
12771+ (set! (. Set -EMPTY) (Set. nil (hash-map )))
0 commit comments