Tools housekeeping

This commit is contained in:
Peter Taoussanis 2016-03-16 19:22:56 +07:00
parent 892937eb34
commit 3f43542adb
6 changed files with 77 additions and 75 deletions

View file

@ -343,6 +343,7 @@
(.writeLong out (.getMostSignificantBits x)) (.writeLong out (.getMostSignificantBits x))
(.writeLong out (.getLeastSignificantBits x))) (.writeLong out (.getLeastSignificantBits x)))
;; TODO Deprecate, move to `thaw` opt?
(enc/defonce* ^:dynamic *final-freeze-fallback* nil) (enc/defonce* ^:dynamic *final-freeze-fallback* nil)
(defn freeze-fallback-as-str [out x] (defn freeze-fallback-as-str [out x]
(-freeze-to-out {:nippy/unfreezable (enc/pr-edn x) :type (type x)} out)) (-freeze-to-out {:nippy/unfreezable (enc/pr-edn x) :type (type x)} out))
@ -513,6 +514,7 @@
(def ^:private class-method-sig (into-array Class [IPersistentMap])) (def ^:private class-method-sig (into-array Class [IPersistentMap]))
;; TODO Deprecate, move to `thaw` opt?
(enc/defonce* ^:dynamic *custom-readers* "{<hash-or-byte-id> (fn [data-input])}" nil) (enc/defonce* ^:dynamic *custom-readers* "{<hash-or-byte-id> (fn [data-input])}" nil)
(defn swap-custom-readers! [f] (alter-var-root #'*custom-readers* f)) (defn swap-custom-readers! [f] (alter-var-root #'*custom-readers* f))

View file

@ -1,5 +1,4 @@
(ns taoensso.nippy.benchmarks (ns taoensso.nippy.benchmarks
{:author "Peter Taoussanis"}
(:require [clojure.data.fressian :as fressian] (:require [clojure.data.fressian :as fressian]
[taoensso.encore :as enc] [taoensso.encore :as enc]
[taoensso.nippy :as nippy :refer (freeze thaw)])) [taoensso.nippy :as nippy :refer (freeze thaw)]))

View file

@ -1,5 +1,4 @@
(ns taoensso.nippy.compression (ns taoensso.nippy.compression
{:author "Peter Taoussanis"}
(:require [taoensso.encore :as enc]) (:require [taoensso.encore :as enc])
(:import [java.io ByteArrayInputStream ByteArrayOutputStream DataInputStream (:import [java.io ByteArrayInputStream ByteArrayOutputStream DataInputStream
DataOutputStream])) DataOutputStream]))
@ -13,7 +12,7 @@
;;;; Default implementations ;;;; Default implementations
(def standard-header-ids "These'll support :auto thaw." #{:snappy :lzma2 :lz4}) (def standard-header-ids "These'll support :auto thaw" #{:snappy :lzma2 :lz4})
(deftype SnappyCompressor [] (deftype SnappyCompressor []
ICompressor ICompressor

View file

@ -1,6 +1,5 @@
(ns taoensso.nippy.encryption (ns taoensso.nippy.encryption
"Simple no-nonsense crypto with reasonable defaults." "Simple no-nonsense crypto with reasonable defaults"
{:author "Peter Taoussanis"}
(:require [taoensso.encore :as enc])) (:require [taoensso.encore :as enc]))
;;;; Interface ;;;; Interface

View file

@ -1,33 +1,42 @@
(ns taoensso.nippy.tools (ns taoensso.nippy.tools
"Utilities for third-party tools that want to add fully-user-configurable "Utils for 3rd-party tools that want to add user-configurable Nippy support.
Nippy support. Used by Carmine and Faraday." Used by Carmine, Faraday, etc."
{:author "Peter Taoussanis"}
(:require [taoensso.nippy :as nippy])) (:require [taoensso.nippy :as nippy]))
(def ^:dynamic *freeze-opts* nil)
(def ^:dynamic *thaw-opts* nil)
(defmacro with-freeze-opts [opts & body] `(binding [*freeze-opts* ~opts] ~@body))
(defmacro with-thaw-opts [opts & body] `(binding [*thaw-opts* ~opts] ~@body))
(defrecord WrappedForFreezing [value opts]) (defrecord WrappedForFreezing [value opts])
(defn wrapped-for-freezing? [x] (instance? WrappedForFreezing x)) (defn wrapped-for-freezing? [x] (instance? WrappedForFreezing x))
(defn wrap-for-freezing (defn wrap-for-freezing
"Wraps arg (any freezable data type) so that (tools/freeze <wrapped-arg>) "Ensures that given arg (any freezable data type) is wrapped so that
will serialize the arg using given options." (tools/freeze <wrapped-arg>) will serialize as
[value & [opts]] (->WrappedForFreezing value opts)) (nippy/freeze <unwrapped-arg> <opts>)."
([x ] (wrap-for-freezing x nil))
([x opts]
(if (wrapped-for-freezing? x)
(if (= (:opts x) opts)
x
(WrappedForFreezing. (:value x) opts))
(WrappedForFreezing. x opts))))
(defn freeze (defn freeze
"Like `nippy/freeze` but takes options from special argument wrapper when "Like `nippy/freeze` but merges opts from *freeze-opts*, `wrap-for-freezing`."
present." ([x ] (freeze x nil))
[x & [{:keys [default-opts]}]] ([x default-opts]
(let [default-opts (or (:default-opts default-opts) default-opts)] ; Back compat
(if (wrapped-for-freezing? x) (if (wrapped-for-freezing? x)
(nippy/freeze (:value x) (or (:opts x) default-opts)) (nippy/freeze (:value x) (merge default-opts *freeze-opts* (:opts x)))
(nippy/freeze x default-opts))) (nippy/freeze x default-opts)))))
(comment (freeze (wrap-for-freezing "wrapped")) (defn thaw
(freeze "unwrapped")) "Like `nippy/thaw` but merges opts from `*thaw-opts*`."
([ba ] (thaw ba nil))
([ba default-opts]
(let [default-opts (or (:default-opts default-opts) default-opts)] ; Back compat
(nippy/thaw ba (merge default-opts *thaw-opts*)))))
(def ^:dynamic *thaw-opts* nil) (comment (thaw (freeze (wrap-for-freezing "wrapped"))))
(defmacro with-thaw-opts
"Evaluates body using given options for any automatic deserialization in
context."
[opts & body] `(binding [*thaw-opts* ~opts] ~@body))
(defn thaw "Like `nippy/thaw` but takes options from *thaw-opts* binding."
[ba & [{:keys [default-opts]}]]
(nippy/thaw ba (merge default-opts *thaw-opts*)))

View file

@ -1,5 +1,4 @@
(ns taoensso.nippy.utils (ns taoensso.nippy.utils
{:author "Peter Taoussanis"}
(:require [clojure.string :as str] (:require [clojure.string :as str]
[taoensso.encore :as enc]) [taoensso.encore :as enc])
(:import [java.io ByteArrayInputStream ByteArrayOutputStream Serializable (:import [java.io ByteArrayInputStream ByteArrayOutputStream Serializable
@ -36,15 +35,10 @@
(def readable? (memoize-type-test (fn [x] (-> x enc/pr-edn enc/read-edn) true))) (def readable? (memoize-type-test (fn [x] (-> x enc/pr-edn enc/read-edn) true)))
(comment (comment
(serializable? "Hello world") (enc/qb 1000 (serializable? "Hello world")) ; Cacheable
(serializable? (fn [])) (enc/qb 1000 (serializable? (fn []))) ; Uncacheable
(readable? "Hello world") (enc/qb 1000 (readable? "Hello world")) ; Cacheable
(readable? (fn [])) (enc/qb 1000 (readable? (fn [])))) ; Uncacheable
(time (dotimes [_ 10000] (serializable? "Hello world"))) ; Cacheable
(time (dotimes [_ 10000] (serializable? (fn [])))) ; Uncacheable
(time (dotimes [_ 10000] (readable? "Hello world"))) ; Cacheable
(time (dotimes [_ 10000] (readable? (fn []))))) ; Uncacheable
;;;; ;;;;
@ -77,20 +71,20 @@
(comment (is-coll? (clojure.lang.PersistentVector$ChunkedSeq. [1 2 3] 0 0))) (comment (is-coll? (clojure.lang.PersistentVector$ChunkedSeq. [1 2 3] 0 0)))
(defn freezable? (defn freezable?
"Alpha - subject to change, MAY BE BUGGY! "Alpha - subject to change.
Returns truthy value iff Nippy supports de/serialization of given argument. Returns truthy iff Nippy *appears* to support freezing the given argument.
Conservative with default options.
`:allow-clojure-reader?` and `:allow-java-serializable?` options may be used `:allow-clojure-reader?` and `:allow-java-serializable?` options may be
to also enable the relevant roundtrip fallback test(s). These tests are only used to enable the relevant roundtrip fallback test(s). These tests are
**moderately reliable** since they're cached by arg type and don't test for only **moderately reliable** since they're cached by arg type and don't
pre/post serialization equality (there's no good general way of doing so)." test for pre/post serialization value equality (there's no good general
[x & [{:keys [allow-clojure-reader? allow-java-serializable?]}]] way of doing so)."
([x] (freezable? x nil))
([x {:keys [allow-clojure-reader? allow-java-serializable?]}]
(let [is? #(when (instance? % x) %)] (let [is? #(when (instance? % x) %)]
(if (is-coll? x) (if (is-coll? x)
(try (when (enc/revery? freezable? x) (type x))
(when (every? freezable? x) (type x))
(catch Exception _ false))
(or (or
(is? clojure.lang.Keyword) (is? clojure.lang.Keyword)
(is? java.lang.String) (is? java.lang.String)
@ -116,10 +110,10 @@
(when (and allow-java-serializable? (when (and allow-java-serializable?
;; Reports as true but is unreliable: ;; Reports as true but is unreliable:
(not (is? clojure.lang.Fn)) (not (is? clojure.lang.Fn))
(serializable? x)) :java-serializable))))) (serializable? x)) :java-serializable))))))
(comment (comment
(time (dotimes [_ 10000] (freezable? "hello"))) (enc/qb 10000 (freezable? "hello"))
(freezable? [:a :b]) (freezable? [:a :b])
(freezable? [:a (fn [x] (* x x))]) (freezable? [:a (fn [x] (* x x))])
(freezable? (.getBytes "foo")) (freezable? (.getBytes "foo"))