From a92c493375d95996b999eed0736e28016bd94814 Mon Sep 17 00:00:00 2001 From: Zach Tellman Date: Thu, 10 Oct 2013 11:31:52 -0400 Subject: [PATCH] add fast-path encoding for long, doubles, keywords, and strings --- src/taoensso/nippy.clj | 51 +++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/src/taoensso/nippy.clj b/src/taoensso/nippy.clj index ce55eac..298cc71 100644 --- a/src/taoensso/nippy.clj +++ b/src/taoensso/nippy.clj @@ -87,14 +87,29 @@ (defmacro ^:private write-biginteger [s x] `(write-bytes ~s (.toByteArray ~x))) (defmacro ^:private write-utf8 [s x] `(write-bytes ~s (.getBytes ~x "UTF-8"))) -(defmacro ^:private freeze-to-stream - "Like `freeze-to-stream*` but with metadata support." - [s x] - `(let [x# ~x s# ~s] - (when-let [m# (meta x#)] - (write-id s# ~id-meta) - (freeze-to-stream* m# s#)) - (freeze-to-stream* x# s#))) + +(defn- freeze-to-stream + "Like `freeze-to-stream*`, but with metadata support and certain fast-paths encoded." + [^DataOutputStream s x] + (condp instance? x + Number (condp instance? x + Long (do (write-id s id-long) (.writeLong s x)) + Double (do (write-id s id-double) (.writeDouble s x)) + (freeze-to-stream* x s)) + Keyword (do + (write-id s id-keyword) + (write-utf8 s + (if-let [ns (namespace x)] + (str ns "/" (name x)) + (name x)))) + String (do + (write-id s id-string) + (write-utf8 s ^String x)) + (do + (when-let [m (meta x)] + (write-id s id-meta) + (freeze-to-stream* m s)) + (freeze-to-stream* x s)))) (defn freeze-to-stream! "Low-level API. Serializes arg (any Clojure data type) to a DataOutputStream." @@ -120,12 +135,12 @@ (doseq [i# ~'x] (freeze-to-stream ~'s i#))) (let [bas# (ByteArrayOutputStream.) s# (DataOutputStream. bas#) - cnt# (reduce - (fn [cnt# i#] - (freeze-to-stream! s# i#) - (unchecked-inc cnt#)) - 0 - ~'x) + cnt# (loop [cnt# 0, x# ~'x] + (if (empty? x#) + cnt# + (do + (freeze-to-stream! s# (first x#)) + (recur (unchecked-inc cnt#) (rest x#))))) ba# (.toByteArray bas#)] (.writeInt ~'s cnt#) (.write ~'s ba# 0 (alength ba#)))))) @@ -134,10 +149,10 @@ "Extends Freezable to key-value collection types." [type id & body] `(freezer ~type ~id - (.writeInt ~'s (* 2 (count ~'x))) - (doseq [kv# ~'x] - (freeze-to-stream ~'s (key kv#)) - (freeze-to-stream ~'s (val kv#))))) + (.writeInt ~'s (* 2 (count ~'x))) + (doseq [kv# ~'x] + (freeze-to-stream ~'s (key kv#)) + (freeze-to-stream ~'s (val kv#))))) (freezer (Class/forName "[B") id-bytes (write-bytes s ^bytes x)) (freezer nil id-nil)