Try to encode a string object in order to save space */
| 436 | |
| 437 | /* Try to encode a string object in order to save space */ |
| 438 | robj *tryObjectEncoding(robj *o) { |
| 439 | long value; |
| 440 | sds s = o->ptr; |
| 441 | size_t len; |
| 442 | |
| 443 | /* Make sure this is a string object, the only type we encode |
| 444 | * in this function. Other types use encoded memory efficient |
| 445 | * representations but are handled by the commands implementing |
| 446 | * the type. */ |
| 447 | serverAssertWithInfo(NULL,o,o->type == OBJ_STRING); |
| 448 | |
| 449 | /* We try some specialized encoding only for objects that are |
| 450 | * RAW or EMBSTR encoded, in other words objects that are still |
| 451 | * in represented by an actually array of chars. */ |
| 452 | if (!sdsEncodedObject(o)) return o; |
| 453 | |
| 454 | /* It's not safe to encode shared objects: shared objects can be shared |
| 455 | * everywhere in the "object space" of Redis and may end in places where |
| 456 | * they are not handled. We handle them only as values in the keyspace. */ |
| 457 | if (o->refcount > 1) return o; |
| 458 | |
| 459 | /* Check if we can represent this string as a long integer. |
| 460 | * Note that we are sure that a string larger than 20 chars is not |
| 461 | * representable as a 32 nor 64 bit integer. */ |
| 462 | len = sdslen(s); |
| 463 | if (len <= 20 && string2l(s,len,&value)) { |
| 464 | /* This object is encodable as a long. Try to use a shared object. |
| 465 | * Note that we avoid using shared integers when maxmemory is used |
| 466 | * because every object needs to have a private LRU field for the LRU |
| 467 | * algorithm to work well. */ |
| 468 | if ((server.maxmemory == 0 || |
| 469 | !(server.maxmemory_policy & MAXMEMORY_FLAG_NO_SHARED_INTEGERS)) && |
| 470 | value >= 0 && |
| 471 | value < OBJ_SHARED_INTEGERS) |
| 472 | { |
| 473 | decrRefCount(o); |
| 474 | incrRefCount(shared.integers[value]); |
| 475 | return shared.integers[value]; |
| 476 | } else { |
| 477 | if (o->encoding == OBJ_ENCODING_RAW) { |
| 478 | sdsfree(o->ptr); |
| 479 | o->encoding = OBJ_ENCODING_INT; |
| 480 | o->ptr = (void*) value; |
| 481 | return o; |
| 482 | } else if (o->encoding == OBJ_ENCODING_EMBSTR) { |
| 483 | decrRefCount(o); |
| 484 | return createStringObjectFromLongLongForValue(value); |
| 485 | } |
| 486 | } |
| 487 | } |
| 488 | |
| 489 | /* If the string is small and is still RAW encoded, |
| 490 | * try the EMBSTR encoding which is more efficient. |
| 491 | * In this representation the object and the SDS string are allocated |
| 492 | * in the same chunk of memory to save space and cache misses. */ |
| 493 | if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT) { |
| 494 | robj *emb; |
| 495 |
no test coverage detected