-
-
Save ztellman/755574 to your computer and use it in GitHub Desktop.
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 clojfix.simple) | |
(use 'gloss.core 'gloss.io) | |
(import | |
[java.nio | |
ByteBuffer]) | |
(defcodec simple-tuple | |
"gloss codec definition" | |
(header | |
(string-integer :ascii :delimiters ["="]) | |
(memoize | |
(fn [key] | |
(compile-frame | |
[key (string :ascii :delimiters [0x01])]))) | |
(fn [[key value]] | |
key))) | |
(defn print-bb [title b] | |
"Hex dump of ByteBuffer instance" | |
(let [cnt (.limit ^ByteBuffer b)] | |
(printf "bb:%s\n" title) | |
(loop [i 0] | |
(if (== i cnt) | |
(printf "\n") | |
(do | |
(printf "%d:%02x " i (.get ^ByteBuffer b i)) | |
(recur (inc i))))))) | |
(defn ascii-int-to-bb [b n width] | |
"ASCII representation of positive integer n is stored | |
at current byte buffer position. | |
Returns number of bytes filled." | |
(let [len (int width) | |
val (int n) | |
old-pos (int (.position ^ByteBuffer b)) | |
new-pos (int (+ len old-pos))] | |
(.position ^ByteBuffer b new-pos) | |
(loop [i new-pos acc val] | |
(if (== i old-pos) | |
len | |
(do | |
(.put ^ByteBuffer b (dec i) (+ (int (rem acc 10)) 0x30)) | |
(recur (dec i) (int (quot acc 10)))))))) | |
(defn encode-tuple [t] | |
(let [ | |
tag (int (first t)) | |
val (second t) | |
tlen (int (+ 1 (Math/log10 tag))) | |
vlen (int (count val)) | |
len (+ tlen vlen 2) | |
ret (ByteBuffer/allocate len)] | |
(ascii-int-to-bb ret tag tlen) | |
(. ret put (byte 0x21)) | |
(. ret put (.getBytes ^String val)) | |
(. ret put (byte 1)) | |
(. ret rewind) | |
ret)) | |
(defn bb-get-tag [b] | |
(if (== 0 (.remaining ^ByteBuffer b)) | |
0 | |
(do | |
(loop [ ret 0 | |
nextb (int (.get ^ByteBuffer b))] | |
(if (== 0 (.remaining ^ByteBuffer b)) | |
0 | |
(do | |
(if (or (< nextb 0x30) | |
(> nextb 0x39)) | |
(if (== nextb 0x21) | |
ret | |
0) | |
(recur | |
(+ (- nextb 0x30) (* ret 10)) | |
(int (.get ^ByteBuffer b)))))))))) | |
(defn bb-get-val [b] | |
(if (== 0 (.remaining ^ByteBuffer b)) | |
nil | |
(do | |
(loop [chars [] | |
nextb (int (.get ^ByteBuffer b))] | |
(if (== nextb 0x01) | |
(apply str chars) | |
(do | |
(if (== 0 (.remaining ^ByteBuffer b)) | |
nil ; did not get SOH | |
(recur (conj chars (char nextb)) | |
(int (.get ^ByteBuffer b)))))))))) | |
(defn decode-tuple [b] | |
(let [tag (bb-get-tag b) | |
val (bb-get-val b)] | |
(if (or (== tag 0) (nil? val)) | |
nil | |
[tag val]))) | |
(defn tuple-bench [repeat] | |
(let [test-tuple [123 "The test"] | |
enc-bufs-gloss (encode simple-tuple test-tuple) | |
enc-buf (encode-tuple test-tuple) | |
dec-tuple-gloss (decode simple-tuple enc-bufs-gloss) | |
dec-tuple (decode-tuple (.duplicate ^ByteBuffer enc-buf))] | |
(printf "Doing encode/decode %d times\n" repeat) | |
(print "encode(gloss): ") | |
(time (dotimes [i repeat] (encode simple-tuple dec-tuple-gloss))) | |
(print "encode-tuple: ") | |
(time (dotimes [_ repeat] (encode-tuple dec-tuple))) | |
(print "decode(gloss): ") | |
(time (dotimes [_ repeat] (decode simple-tuple enc-bufs-gloss))) | |
(print "decode-tuple: ") | |
(time (dotimes [_ repeat] (decode-tuple (.duplicate ^ByteBuffer enc-buf)))) | |
)) | |
(defn enc-dec-test [] | |
(let [tuple [122 "abc-123"] | |
bb-gloss (encode simple-tuple tuple) | |
bb (encode-tuple tuple) | |
ee-gloss (decode simple-tuple bb-gloss) | |
ee (decode-tuple bb)] | |
(print-bb "bb" bb) | |
(println ee-gloss) | |
(println ee))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment