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:36:09 +0200
commitfacc5c0661fa13ff395d9fd250d76161d090072f (patch)
treeb50a0267ae4012efd3f361b64c4a049ef934d04e
parent79a1d335c85be3b66a89962f71e830df7eea8c35 (diff)
downloadredis-facc5c0661fa13ff395d9fd250d76161d090072f.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 1c9c37e80..6095a1154 100644
--- a/src/object.c
+++ b/src/object.c
@@ -293,7 +293,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...
*