diff --git a/src/module.c b/src/module.c index 28a4d3e64..e69d3dc61 100644 --- a/src/module.c +++ b/src/module.c @@ -523,12 +523,17 @@ void RedisModuleCommandDispatcher(client *c) { moduleFreeContext(&ctx); /* In some cases processMultibulkBuffer uses sdsMakeRoomFor to - * expand the querybuf, but later in some cases it uses that query - * buffer as is for an argv element (see "Optimization"), which means - * that the sds in argv may have a lot of wasted space, and then in case - * modules keep that argv RedisString inside their data structure, this - * space waste will remain for long (until restarted from rdb). */ + * expand the query buffer, and in order to avoid a big object copy + * the query buffer SDS may be used directly as the SDS string backing + * the client argument vectors: sometimes this will result in the SDS + * string having unused space at the end. Later if a module takes ownership + * of the RedisString, such space will be wasted forever. Inside the + * Redis core this is not a problem because tryObjectEncoding() is called + * before storing strings in the key space. Here we need to do it + * for the module. */ for (int i = 0; i < c->argc; i++) { + /* Only do the work if the module took ownership of the object: + * in that case the refcount is no longer 1. */ if (c->argv[i]->refcount > 1) trimStringObjectIfNeeded(c->argv[i]); } diff --git a/src/object.c b/src/object.c index 42c247b87..24e99d191 100644 --- a/src/object.c +++ b/src/object.c @@ -415,10 +415,11 @@ int isObjectRepresentableAsLongLong(robj *o, long long *llval) { } } +/* 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. This happens because SDS strings tend to overallocate to avoid + * wasting too much time in allocations when appending to the string. */ void trimStringObjectIfNeeded(robj *o) { - /* 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. */ if (o->encoding == OBJ_ENCODING_RAW && sdsavail(o->ptr) > sdslen(o->ptr)/10) {