Repository: valkey-io/valkey
File: src/object.c (C)

Code before:

/* Create a string object with EMBSTR encoding if it is smaller than
 * OBJ_ENCODING_EMBSTR_SIZE_LIMIT, otherwise the RAW encoding is
 * used.
 *
 * The current limit of 44 is chosen so that the biggest string object
 * we allocate as EMBSTR will still fit into the 64 byte arena of jemalloc. */
#define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44
robj *createStringObject(const char *ptr, size_t len) {
    if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT)
        return createEmbeddedStringObject(ptr, len);
    else
        return createRawStringObject(ptr, len);
}

robj *createStringObjectWithKeyAndExpire(const char *ptr, size_t len, const sds key, long long expire) {
    /* When to embed? Embed when the sum is up to 64 bytes. There may be better
     * heuristics, e.g. we can look at the jemalloc sizes (16-byte intervals up
     * to 128 bytes). */
    size_t size = sizeof(robj);
    if (key) {
        size_t key_len = sdslen(key);
        size += sdsReqSize(key_len, sdsReqType(key_len)) + 1; /* 1 byte for prefixed sds hdr size */
    }
    size += (expire != -1) * sizeof(long long);
    size += 4 + len; /* embstr header (3) + nullterm (1) */
    if (size <= 64) {
        return createEmbeddedStringObjectWithKeyAndExpire(ptr, len, key, expire);
    } else {
        return createObjectWithKeyAndExpire(OBJ_STRING, sdsnewlen(ptr, len), key, expire);
    }
}

sds objectGetKey(const robj *val) {
    unsigned char *data = (void *)(val + 1);
    if (val->hasexpire) {
        /* Skip expire field */
        data += sizeof(long long);
    }
    if (val->hasembkey) {
        uint8_t hdr_size = *(uint8_t *)data;
        data += 1 + hdr_size;
        return (sds)data;
    }
    return NULL;
}

long long objectGetExpire(const robj *val) {
    unsigned char *data = (void *)(val + 1);
    if (val->hasexpire) {
        return *(long long *)data;

Review comment (suggestion):
Although no problem here, I would love to see this part changed as well:
size += sdsReqSize(len, SDS_TYPE_8)
```suggestion
    size += sdsReqSize(len, SDS_TYPE_8); /* embstr header (3) + nullterm (1) */
```

Code after:

/* Create a string object with EMBSTR encoding if it is smaller than
 * OBJ_ENCODING_EMBSTR_SIZE_LIMIT, otherwise the RAW encoding is
 * used.
 *
 * The current limit of 44 is chosen so that the biggest string object
 * we allocate as EMBSTR will still fit into the 64 byte arena of jemalloc. */
#define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44
robj *createStringObject(const char *ptr, size_t len) {
    if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT)
        return createEmbeddedStringObject(ptr, len);
    else
        return createRawStringObject(ptr, len);
}

robj *createStringObjectWithKeyAndExpire(const char *ptr, size_t len, const sds key, long long expire) {
    /* When to embed? Embed when the sum is up to 64 bytes. There may be better
     * heuristics, e.g. we can look at the jemalloc sizes (16-byte intervals up
     * to 128 bytes). */
    size_t size = sizeof(robj);
    if (key) {
        size_t key_len = sdslen(key);
        size += sdsReqSize(key_len, sdsReqType(key_len)) + 1; /* 1 byte for prefixed sds hdr size */
    }
    size += (expire != -1) * sizeof(long long);
    size += sdsReqSize(len, SDS_TYPE_8);
    if (size <= 64) {
        return createEmbeddedStringObjectWithKeyAndExpire(ptr, len, key, expire);
    } else {
        return createObjectWithKeyAndExpire(OBJ_STRING, sdsnewlen(ptr, len), key, expire);
    }
}

sds objectGetKey(const robj *val) {
    unsigned char *data = (void *)(val + 1);
    if (val->hasexpire) {
        /* Skip expire field */
        data += sizeof(long long);
    }
    if (val->hasembkey) {
        uint8_t hdr_size = *(uint8_t *)data;
        data += 1 + hdr_size;
        return (sds)data;
    }
    return NULL;
}

long long objectGetExpire(const robj *val) {
    unsigned char *data = (void *)(val + 1);
    if (val->hasexpire) {
        return *(long long *)data;