diff options
Diffstat (limited to 'pymemcache/serde.py')
-rw-r--r-- | pymemcache/serde.py | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/pymemcache/serde.py b/pymemcache/serde.py index f92aeb7..6e77766 100644 --- a/pymemcache/serde.py +++ b/pymemcache/serde.py @@ -16,12 +16,13 @@ from functools import partial import logging from io import BytesIO import pickle +import zlib FLAG_BYTES = 0 FLAG_PICKLE = 1 << 0 FLAG_INTEGER = 1 << 1 FLAG_LONG = 1 << 2 -FLAG_COMPRESSED = 1 << 3 # unused, to main compatibility with python-memcached +FLAG_COMPRESSED = 1 << 3 FLAG_TEXT = 1 << 4 # Pickle protocol version (highest available to runtime) @@ -121,6 +122,55 @@ class PickleSerde: return python_memcache_deserializer(key, value, flags) +pickle_serde = PickleSerde() + + +class CompressedSerde: + """ + An object which implements the serialization/deserialization protocol for + :py:class:`pymemcache.client.base.Client` and its descendants with + configurable compression. + """ + + def __init__( + self, + compress=zlib.compress, + decompress=zlib.decompress, + serde=pickle_serde, + # Discovered via the `test_optimal_compression_length` test. + min_compress_len=400, + ): + self._serde = serde + self._compress = compress + self._decompress = decompress + self._min_compress_len = min_compress_len + + def serialize(self, key, value): + value, flags = self._serde.serialize(key, value) + + if len(value) > self._min_compress_len > 0: + old_value = value + value = self._compress(value) + # Don't use the compressed value if our end result is actually + # larger uncompressed. + if len(old_value) < len(value): + value = old_value + else: + flags |= FLAG_COMPRESSED + + return value, flags + + def deserialize(self, key, value, flags): + if flags & FLAG_COMPRESSED: + value = self._decompress(value) + + value = self._serde.deserialize(key, value, flags) + return value + + +compressed_serde = CompressedSerde() + + class LegacyWrappingSerde: """ This class defines how to wrap legacy de/serialization functions into a @@ -141,6 +191,3 @@ class LegacyWrappingSerde: def _default_deserialize(self, key, value, flags): return value - - -pickle_serde = PickleSerde() |