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

Code before:
}

sds hashTypeEntryGetValue(const hashTypeEntry *entry) {
    switch (entryGetEncoding(entry)) {
    case ENTRY_ENC_EMB_VALUE: {
        /* Skip field content, field null terminator and value sds8 hdr. */
        size_t offset = sdslen(entry) + 1 + sdsHdrSize(SDS_TYPE_8);
        char *buf = (char *)entry + offset;
        return buf;
    }
    case ENTRY_ENC_PTR_VALUE: {
        const hashTypeEntryPtrValue *entry_struct = getEntryStruct(entry);
        return entry_struct->value;
    }
    default:
        serverPanic("Unknown type");
    }
}

/* Returns the address of the entry allocation. */
static void *hashTypeEntryAllocPtr(hashTypeEntry *entry) {
    switch (entryGetEncoding(entry)) {
    case ENTRY_ENC_EMB_VALUE:
        return sdsAllocPtr(entry);
    case ENTRY_ENC_PTR_VALUE:
        return getEntryStruct(entry);
    default:
        serverPanic("Unknown type");
    }
}

/* Frees previous value, takes ownership of new value, returns entry (may be
 * reallocated). */
static hashTypeEntry *hashTypeEntryReplaceValue(hashTypeEntry *entry, sds value) {
    sds field = (sds)entry;
    size_t field_size = sdsHdrSize(sdsType(field)) + sdsalloc(field) + 1;
    size_t value_len = sdslen(value);
    size_t value_size = sdsReqSize(value_len, SDS_TYPE_8);
    switch (entryGetEncoding(entry)) {
    case ENTRY_ENC_EMB_VALUE: {
        /* Reuse the allocation if the new value fits and leaves no more than
         * 25% unused space after replacing the value. */
        char *alloc_ptr = sdsAllocPtr(entry);
        size_t required_size = field_size + value_size;
        size_t alloc_size;
        if (required_size <= CACHE_LINE_SIZE &&
            required_size <= (alloc_size = zmalloc_usable_size(alloc_ptr)) &&
            required_size >= alloc_size * 3 / 4) {
            /* It fits in the allocation and leaves max 25% unused space. */
            sdswrite(alloc_ptr + field_size, alloc_size - field_size, SDS_TYPE_8, value, value_len);
            sdsfree(value);

Review comment (suggestion):
```suggestion
        return encodedPtrValueEntryGetValueref(entry);
```

Code after:
        return *hashTypeEntryGetValueRef(entry);
    } else {
        /* Skip field content, field null terminator and value sds8 hdr. */
        size_t offset = sdslen(entry) + 1 + sdsHdrSize(SDS_TYPE_8);
        return (char *)entry + offset;
    }
}

/* Returns the address of the entry allocation. */
static void *hashTypeEntryAllocPtr(hashTypeEntry *entry) {
    char *buf = sdsAllocPtr(entry);
    if (entryHasValuePtr(entry)) {
        buf -= sizeof(sds *);
    }
    return buf;
}

/* Frees previous value, takes ownership of new value, returns entry (may be
 * reallocated). */
static hashTypeEntry *hashTypeEntryReplaceValue(hashTypeEntry *entry, sds value) {
    sds field = (sds)entry;
    size_t field_size = sdsHdrSize(sdsType(field)) + sdsalloc(field) + 1;
    size_t value_len = sdslen(value);
    size_t value_size = sdsReqSize(value_len, SDS_TYPE_8);
    if (!entryHasValuePtr(entry)) {
        /* Reuse the allocation if the new value fits and leaves no more than
         * 25% unused space after replacing the value. */
        char *alloc_ptr = sdsAllocPtr(entry);
        size_t required_size = field_size + value_size;
        size_t alloc_size;
        if (required_size <= EMBED_VALUE_MAX_ALLOC_SIZE &&
            required_size <= (alloc_size = hashTypeEntryMemUsage(entry)) &&
            required_size >= alloc_size * 3 / 4) {
            /* It fits in the allocation and leaves max 25% unused space. */
            sdswrite(alloc_ptr + field_size, alloc_size - field_size, SDS_TYPE_8, value, value_len);
            sdsfree(value);
            return entry;
        }
        hashTypeEntry *new_entry = hashTypeCreateEntry(hashTypeEntryGetField(entry), value);
        freeHashTypeEntry(entry);
        return new_entry;
    } else {
        /* The value pointer is located before the embedded field. */
        if (field_size + value_size <= EMBED_VALUE_MAX_ALLOC_SIZE) {
            /* Convert to entry with embedded value. */
            hashTypeEntry *new_entry = hashTypeCreateEntry(field, value);
            freeHashTypeEntry(entry);
            return new_entry;
        } else {
            /* Not embedded value. */
            sds *value_ref = hashTypeEntryGetValueRef(entry);