So, much of the pain involved in handling UUID's correctly on the JVM relates to the fact that there is no primitive unsigned numeric type that can represent the full range of possible values of the msb and lsb. Ie., we need to always deal with the unpleasant "am I negative?" approach to reading (writing) that 64th bit. To avoid the complexity of all the edge cases, we encapsulate the basic primitives of working with unsigned numbers entirely within the abstraction of "mask" and "mask offset". Using these, we built the two fundamental bitwise operations that are used for most of the UUID calculation: ldb (load-byte) and dpb (deposit-byte).
This scrap of code from my clj-uuid.bitmop library is extremely useful for working with "unsigned" long/binary values (analogously to how one might using the common-lisp functions by the same name). And, it has been "good enough" to do pretty well so far in terms of performance. But I'm sure that there are gifted binariticians in the audience that can improve this. (Note, the namespace uses ztellman/primitive-math which changes the semantics of some arithmetic operations and some type hinting. Also some of the 'let's are there for that reason. It may be helpful to refer to the link. ;;; https://github.com/danlentz/clj-uuid/blob/master/src/clj_uuid/bitmop.clj (defn ^long expt2 [^long pow] (bit-set 0 pow)) (defn ^long mask [^long width ^long offset] (if (< (+ width offset) 64) (bit-shift-left (dec (bit-shift-left 1 width)) offset) (let [x (expt2 offset)] (bit-and-not -1 (dec ^long x))))) (declare ^long mask-offset ^long mask-width) (defn ^long mask-offset [^long m] (cond (zero? m) 0 (neg? m) (- 64 ^long (mask-width m)) :else (loop [c 0] (if (pos? (bit-and 1 (bit-shift-right m c))) c (recur (inc c)))))) (defn ^long mask-width [^long m] (if (neg? m) (let [x (mask-width (- (inc m)))] (- 64 ^long x)) (loop [m (bit-shift-right m (mask-offset m)) c 0] (if (zero? (bit-and 1 (bit-shift-right m c))) c (recur m (inc c)))))) (defn ^long ldb "Load Byte" [^long bitmask ^long num] (let [off (mask-offset bitmask)] (bit-and (>>> bitmask ^long off) (bit-shift-right num off)))) (defn ^long dpb "Deposit Byte" [^long bitmask ^long num ^long value] (bit-or (bit-and-not num bitmask) (bit-and bitmask (bit-shift-left value (mask-offset bitmask))))) -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.