Skip to content

Commit

Permalink
Removed data hashmap and fixed dissoc
Browse files Browse the repository at this point in the history
  • Loading branch information
Paula Gearon committed May 23, 2023
1 parent 883298f commit 500bad1
Showing 1 changed file with 59 additions and 32 deletions.
91 changes: 59 additions & 32 deletions src/tiara/data.clj
Original file line number Diff line number Diff line change
@@ -1,57 +1,85 @@
(ns ^{:doc "Divergent data structures"
:author "Paula Gearon"}
tiara.data
(:import [clojure.lang AFn MapEntry IPersistentMap IHashEq IObj MapEquivalence]
(:import [clojure.lang AFn APersistentMap MapEntry IPersistentMap IHashEq IObj MapEquivalence]
[java.util Map]))

;; Note: keySet is unordered. This could be implemented with an ordered set, but is only used
;; when the map is used as a Java object, and so the function is basically never used.
(def ^:const magic 7)

(definline indirect
"This get operation is used in multiple places, and can be inlined.
Possibly redundant with (indirect-nd index entry-vector k nil)"
[index entry-vector k]
`(when-let [n# (~index ~k)]
(val (nth ~entry-vector n#))))

(definline indirect-nf
"This alternative get operation is used in multiple places, and can be inlined."
[index entry-vector k not-found]
`(if-let [n# (~index ~k)]
(val (nth ~entry-vector n#))
~not-found))

(definterface Debug
(dp []))

(defn- vec-map
"Creates an object that implements the required map interfaces, implemented by wrapping
a hashmap and a vector. This does not extend the abstract class APersistentMap as this
includes lots of functionality that would be duplicated by the wrapped objects."
([] (vec-map {} [] {}))
([mp lst idx]
(proxy [AFn IPersistentMap IHashEq IObj MapEquivalence Map] []
([] (vec-map [] {}))
([lst idx]
(proxy [AFn IPersistentMap IHashEq IObj MapEquivalence Map Debug] []
(assoc [k v]
(let [new-mp (assoc mp k v)
kv (find new-mp k)]
(if (contains? mp k)
(vec-map new-mp (assoc lst (idx k) kv) idx)
(vec-map new-mp (conj lst kv) (assoc idx k (count lst))))))
(if-let [n (idx k)]
(if (= (val (nth lst n)) v)
this
(vec-map (assoc lst n (MapEntry/create k v)) idx))
(vec-map (conj lst (MapEntry/create k v)) (assoc idx k (count lst)))))
(assocEx [k v]
(if (contains? mp k)
(if (contains? idx k)
(throw (ex-info "Key already present" {:key k}))
(assoc this k v)))
(.assoc this k v)))
(dp []
(println " lst:" lst)
(println " idx:" idx))
(without [k]
(if (contains? mp k)
(vec-map (dissoc mp k) (vec (remove #(= k (first %)) lst)) (dissoc idx k))
(if-let [split (get idx k)]
(vec-map (into (subvec lst 0 split) (subvec lst (inc split)))
(reduce (fn [index n]
(let [k (key (nth lst n))]
(update index k dec)))
(dissoc idx k)
(range (inc split) (count lst))))
this))
(containsKey [k] (contains? mp k))
(entryAt [k] (find mp k))
(containsKey [k] (contains? idx k))
(entryAt [k] (when-let [n (idx k)] (nth lst n)))
(count [] (count lst))
(iterator [] (.iterator lst))
(cons [[k v :as o]] (.assoc this k v))
(cons [[k v]] (.assoc this k v))
(empty [] (vec-map))
(equiv [o] (.equiv mp o))
(equiv [o]
(if (instance? IPersistentMap o)
(and (instance? MapEquivalence o) (APersistentMap/mapEquals this o))
(APersistentMap/mapEquals this o)))
(valAt
([k] (get mp k))
([k not-found] (get mp k not-found)))
([k] (indirect idx lst k))
([k not-found] (indirect-nf idx lst k not-found)))
(seq [] (seq lst))
(hasheq [] (.hasheq mp))
(hasheq [] (+ magic (.hasheq lst)))
(invoke
([k] (get mp k))
([k not-found] (get mp k not-found)))
([k] (indirect idx lst k))
([k not-found] (indirect-nf idx lst k not-found)))
(containsValue [v] (some #(= % v) (map val lst)))
(equals [o] (.equals mp o))
(get [v] (get mp v))
(equals [o] (.equiv this o))
(get [k] (indirect idx lst k))
(isEmpty [] (empty? lst))
(size [] (count lst))
(hashCode [] (hash mp))
(keySet [] (.keySet mp))
(values [] (map second lst))
(withMeta [meta] (vec-map (with-meta mp meta) lst idx))
(meta [] (meta mp))
(hashCode [] (+ magic (hash lst)))
(keySet [] (map key lst))
(values [] (map val lst))
(withMeta [meta] (vec-map lst (with-meta idx meta)))
(meta [] (meta idx))
(clear [] (throw (UnsupportedOperationException.)))
(put [k v] (throw (UnsupportedOperationException.)))
(putAll [m] (throw (UnsupportedOperationException.)))
Expand All @@ -75,7 +103,6 @@
(if (seen? k) [seen? acc] [(conj seen? k) (conj acc (MapEntry/create k v))]))
[#{} []] (reverse (partition 2 keyvals)))))]
(vec-map
(apply hash-map (flatten kv-vec))
kv-vec
(apply hash-map (interleave (map first kv-vec) (range)))))))

0 comments on commit 500bad1

Please sign in to comment.