 
 ;; ## Long Lexicoder
 
-; TODO: use prefix length encoding, otherwise simple values like 0 double in size when escaped.
+(defn- flip-long-sign
+  "Flip the sign bit on a long value."
+  ^long
+  [^long x]
+  (bit-xor x Long/MIN_VALUE))
+
+
+(defn- get-long-byte
+  "Return the `i`th byte in a long, where 0 gives the least significant byte."
+  [l i]
+  (bit-and 0xFF (bit-shift-right l (* i 8))))
+
+
 (defrecord LongLexicoder
   []
 

      (let [bits (Double/doubleToRawLongBits
                   (if (zero? value) 0.0 (double value)))]
        (if (neg? bits)
          (bit-xor (bit-not bits) Long/MIN_VALUE)
          bits))))

  (decode*

  (encode*
    [_ value]
    ; Flip sign bit so that positive values sort after negative values.
    (let [lexed (flip-long-sign (long value))
          data (byte-array 8)]
      (dotimes [i 8]
        (->
          (get-long-byte lexed (- 7 i))
          (as-> b (if (< 127 b) (- b 256) b))
          (->> (aset-byte data i))))
      data))
