summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2013-08-27 11:59:34 +0200
committerantirez <antirez@gmail.com>2013-08-27 12:52:08 +0200
commite3cbc018a38727423c1dc5ac53178664c771f08e (patch)
treecef1d3b678d79cdceed05bb233cd1fb8e2f736c9
parentb5cc22d191e33d0af9394ae1a124fe315f6a69e2 (diff)
downloadredis-e3cbc018a38727423c1dc5ac53178664c771f08e.tar.gz
tryObjectEncoding(): optimize sds strings if possible.
When no encoding is possible, at least try to reallocate the sds string with one that does not waste memory (with free space at the end of the buffer) when the string is large enough.
-rw-r--r--src/object.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/object.c b/src/object.c
index 0f2eeba72..a1c569f5d 100644
--- a/src/object.c
+++ b/src/object.c
@@ -288,7 +288,26 @@ robj *tryObjectEncoding(robj *o) {
/* Check if we can represent this string as a long integer */
len = sdslen(s);
- if (len > 21 || !string2l(s,len,&value)) return o;
+ if (len > 21 || !string2l(s,len,&value)) {
+ /* We can't encode the object...
+ *
+ * Do the last try, and at least optimize the SDS string inside
+ * the string object to require little space, in case there
+ * is more than 10% of free space at the end of the SDS string.
+ *
+ * We do that for larger strings, using the arbitrary value
+ * of 32 bytes. This code was backported from the unstable branch
+ * where this is performed when the object is too large to be
+ * encoded as EMBSTR. */
+ if (len > 32 &&
+ o->encoding == REDIS_ENCODING_RAW &&
+ sdsavail(s) > len/10)
+ {
+ o->ptr = sdsRemoveFreeSpace(o->ptr);
+ }
+ /* Return the original object. */
+ return o;
+ }
/* Ok, this object can be encoded...
*