Skip to content

Instantly share code, notes, and snippets.

@brandonbloom
Last active August 29, 2015 14:07
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save brandonbloom/441a4b5712729dec7467 to your computer and use it in GitHub Desktop.
(ns nibble-vector
(:import [clojure.core ArrayManager Vec]))
(deftype NibbleArray [^int size ^longs words])
(def ^:private ^ArrayManager am
(reify ArrayManager
(array [_ size]
(NibbleArray. size (long-array (inc (unsigned-bit-shift-right size 4)))))
(alength [_ arr]
(.size ^NibbleArray arr))
(aclone [_ arr]
(NibbleArray. (.size ^NibbleArray arr)
(aclone (.words ^NibbleArray arr))))
(aget [_ arr i]
(assert (< i (.size arr)))
(let [words (.words ^NibbleArray arr)
w (unsigned-bit-shift-right i 4)
word (aget ^longs words w)
n (bit-and i 0xF)
shift (unchecked-multiply-int n 4)
mask (bit-shift-left 0xF shift)]
(unsigned-bit-shift-right (bit-and word mask) shift)))
(aset [_ arr i val]
(assert (< i (.size arr)))
(assert (<= 0 val 15))
(let [words (.words ^NibbleArray arr)
w (unsigned-bit-shift-right i 4)
word (aget ^longs words w)
n (bit-and i 0xF)
shift (unchecked-multiply-int n 4)
mask (bit-shift-left 0xF shift)
v (bit-or (bit-and word (bit-not mask))
(bit-shift-left val shift))]
(aset ^longs words w v)))
))
(def empty-nibble-vector (Vec. am 0 5 EMPTY-NODE (.array am 0) nil))
(comment
(let [^NibbleArray arr (.array am 5)]
(.aset am arr 0 4)
(.aset am arr 1 3)
(.aset am arr 2 2)
(.aset am arr 3 1)
(.aset am arr 4 10)
(.aset am arr 4 11)
(dotimes [i (.alength am arr)]
(prn (.aget am arr i)))
)
(conj empty-nibble-vector 6) ; fails!! due to System/arraycopy
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment