MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / tryObjectEncoding

Function tryObjectEncoding

src/object.cpp:476–553  ·  view source on GitHub ↗

Try to encode a string object in order to save space */

Source from the content-addressed store, hash-verified

474
475/* Try to encode a string object in order to save space */
476robj *tryObjectEncoding(robj *o) {
477 long value;
478 sds s = szFromObj(o);
479 size_t len;
480
481 /* Make sure this is a string object, the only type we encode
482 * in this function. Other types use encoded memory efficient
483 * representations but are handled by the commands implementing
484 * the type. */
485 serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);
486
487 /* We try some specialized encoding only for objects that are
488 * RAW or EMBSTR encoded, in other words objects that are still
489 * in represented by an actually array of chars. */
490 if (!sdsEncodedObject(o)) return o;
491
492 /* It's not safe to encode shared objects: shared objects can be shared
493 * everywhere in the "object space" of Redis and may end in places where
494 * they are not handled. We handle them only as values in the keyspace. */
495 if (o->getrefcount(std::memory_order_relaxed) > 1) return o;
496
497 /* Check if we can represent this string as a long integer.
498 * Note that we are sure that a string larger than 20 chars is not
499 * representable as a 32 nor 64 bit integer. */
500 len = sdslen(s);
501 if (len <= 20 && string2l(s,len,&value)) {
502 /* This object is encodable as a long. Try to use a shared object.
503 * Note that we avoid using shared integers when maxmemory is used
504 * because every object needs to have a private LRU field for the LRU
505 * algorithm to work well. */
506 if ((g_pserver->maxmemory == 0 ||
507 !(g_pserver->maxmemory_policy & MAXMEMORY_FLAG_NO_SHARED_INTEGERS)) &&
508 value >= 0 &&
509 value < OBJ_SHARED_INTEGERS)
510 {
511 decrRefCount(o);
512 incrRefCount(shared.integers[value]);
513 return shared.integers[value];
514 } else {
515 if (o->encoding == OBJ_ENCODING_RAW) {
516 sdsfree(szFromObj(o));
517 o->encoding = OBJ_ENCODING_INT;
518 o->m_ptr = (void*) value;
519 return o;
520 } else if (o->encoding == OBJ_ENCODING_EMBSTR) {
521 decrRefCount(o);
522 return createStringObjectFromLongLongForValue(value);
523 }
524 }
525 }
526
527 /* If the string is small and is still RAW encoded,
528 * try the EMBSTR encoding which is more efficient.
529 * In this representation the object and the SDS string are allocated
530 * in the same chunk of memory to save space and cache misses. */
531 if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT) {
532 robj *emb;
533

Callers 8

rdbLoadObjectFunction · 0.85
setCommandFunction · 0.85
setnxCommandFunction · 0.85
setexCommandFunction · 0.85
psetexCommandFunction · 0.85
getsetCommandFunction · 0.85
msetGenericCommandFunction · 0.85
appendCommandFunction · 0.85

Calls 10

szFromObjFunction · 0.85
sdslenFunction · 0.85
string2lFunction · 0.85
decrRefCountFunction · 0.85
incrRefCountFunction · 0.85
sdsfreeFunction · 0.85
trimStringObjectIfNeededFunction · 0.85
getrefcountMethod · 0.80

Tested by

no test coverage detected