This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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