Repository: valkey-io/valkey
File: src/sds.h (C/C++)

Code before:
#define SDS_TYPE_5 0
#define SDS_TYPE_8 1
#define SDS_TYPE_16 2
#define SDS_TYPE_32 3
#define SDS_TYPE_64 4
#define SDS_TYPE_MASK 7
#define SDS_TYPE_BITS 3
#define SDS_HDR_VAR(T, s) struct sdshdr##T *sh = (void *)((s) - (sizeof(struct sdshdr##T)));
#define SDS_HDR(T, s) ((struct sdshdr##T *)((s) - (sizeof(struct sdshdr##T))))
#define SDS_TYPE_5_LEN(f) ((unsigned char)(f) >> SDS_TYPE_BITS)

static inline unsigned char sdsType(const_sds s) {
    unsigned char flags = s[-1];
    return flags & SDS_TYPE_MASK;
}

/* Returns a user data bit stored in the SDS header by sdsSetAuxBit. The bit
 * index is 0-4. Returns 0 or 1. Always returns 0 for SDS_TYPE_5. */
static inline int sdsGetAuxBit(const_sds s, int bit) {
    unsigned char flags = s[-1];
    return sdsType(s) == SDS_TYPE_5 ? 0 : flags >> (SDS_TYPE_BITS + bit);
}

/* Stores a bit in an unused area in the SDS header, except for SDS_TYPE_5. The
 * bit index is 0-4. The value is 0 or 1. The aux bits are lost if the SDS is
 * auto-resized. */
static inline void sdsSetAuxBit(sds s, int bit, int value) {
    if (sdsType(s) == SDS_TYPE_5) return;
    unsigned char flags = s[-1];
    if (value) {
        flags |= 1 << (SDS_TYPE_BITS + bit);
    } else {
        flags &= ~(1 << (SDS_TYPE_BITS + bit));
    }
    s[-1] = (char)flags;
}

static inline size_t sdslen(const_sds s) {
    switch (sdsType(s)) {
    case SDS_TYPE_5: return SDS_TYPE_5_LEN(s[-1]);
    case SDS_TYPE_8: return SDS_HDR(8, s)->len;
    case SDS_TYPE_16: return SDS_HDR(16, s)->len;
    case SDS_TYPE_32: return SDS_HDR(32, s)->len;
    case SDS_TYPE_64: return SDS_HDR(64, s)->len;
    }
    return 0;
}

static inline size_t sdsavail(const_sds s) {
    unsigned char flags = s[-1];
    switch (flags & SDS_TYPE_MASK) {

Review comment (refactor):
I agree this worth mentioning. the bits are more fit to be used for immutable strings (in that regard creating an "immutable string type" or "field" type would make sense, but maybe we can do this refactor in a separate PR. 

Code after:
#define SDS_TYPE_5 0
#define SDS_TYPE_8 1
#define SDS_TYPE_16 2
#define SDS_TYPE_32 3
#define SDS_TYPE_64 4
#define SDS_TYPE_MASK 7
#define SDS_TYPE_BITS 3
#define SDS_HDR_VAR(T, s) struct sdshdr##T *sh = (void *)((s) - (sizeof(struct sdshdr##T)));
#define SDS_HDR(T, s) ((struct sdshdr##T *)((s) - (sizeof(struct sdshdr##T))))
#define SDS_TYPE_5_LEN(f) ((unsigned char)(f) >> SDS_TYPE_BITS)

static inline unsigned char sdsType(const_sds s) {
    unsigned char flags = s[-1];
    return flags & SDS_TYPE_MASK;
}

/* Returns a user data bit stored in the SDS header by sdsSetAuxBit. The bit
 * index is 0-4. Returns 0 or 1. Always returns 0 for SDS_TYPE_5. */
static inline int sdsGetAuxBit(const_sds s, int bit) {
    unsigned char flags = s[-1];
    return sdsType(s) == SDS_TYPE_5 ? 0 : flags >> (SDS_TYPE_BITS + bit);
}

/* Stores a bit in an unused area in the SDS header, except for SDS_TYPE_5. The
 * bit index is 0-4. The value is 0 or 1. The aux bits are lost if the SDS is
 * auto-resized. This is only for special uses like immutable SDS embedded in
 * other structures. */
static inline void sdsSetAuxBit(sds s, int bit, int value) {
    if (sdsType(s) == SDS_TYPE_5) return;
    unsigned char flags = s[-1];
    if (value) {
        flags |= 1 << (SDS_TYPE_BITS + bit);
    } else {
        flags &= ~(1 << (SDS_TYPE_BITS + bit));
    }
    s[-1] = (char)flags;
}

static inline size_t sdslen(const_sds s) {
    switch (sdsType(s)) {
    case SDS_TYPE_5: return SDS_TYPE_5_LEN(s[-1]);
    case SDS_TYPE_8: return SDS_HDR(8, s)->len;
    case SDS_TYPE_16: return SDS_HDR(16, s)->len;
    case SDS_TYPE_32: return SDS_HDR(32, s)->len;
    case SDS_TYPE_64: return SDS_HDR(64, s)->len;
    }
    return 0;
}

static inline size_t sdsavail(const_sds s) {
    unsigned char flags = s[-1];