Try to encode a string object in order to save space */
| 474 | |
| 475 | /* Try to encode a string object in order to save space */ |
| 476 | robj *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 |
no test coverage detected