Skip to content

Commit 085d8d9

Browse files
committed
Optimize sds free
Eliminates cache-miss on free of String. SdsHdrSize is retieved from calculating %8 operation on sds pointer. Added padding in 2 Sds Headers to have unique value of %8 operation.
1 parent 4062e26 commit 085d8d9

File tree

4 files changed

+35
-1
lines changed

4 files changed

+35
-1
lines changed

src/object.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,12 @@ robj *createModuleObject(moduleType *mt, void *value) {
281281
return createObject(OBJ_MODULE,mv);
282282
}
283283

284+
void freeStringObjectOptim(robj *o) {
285+
if (o->encoding == OBJ_ENCODING_RAW) {
286+
sdsfreeOptim(o->ptr);
287+
}
288+
}
289+
284290
void freeStringObject(robj *o) {
285291
if (o->encoding == OBJ_ENCODING_RAW) {
286292
sdsfree(o->ptr);
@@ -356,7 +362,7 @@ void incrRefCount(robj *o) {
356362
static void _decrRefCount(robj *o, int on_dram) {
357363
if (o->refcount == 1) {
358364
switch(o->type) {
359-
case OBJ_STRING: freeStringObject(o); break;
365+
case OBJ_STRING: freeStringObjectOptim(o); break;
360366
case OBJ_LIST: freeListObject(o); break;
361367
case OBJ_SET: freeSetObject(o); break;
362368
case OBJ_ZSET: freeZsetObject(o); break;

src/sds.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@ static inline int sdsHdrSize(char type) {
6060
return 0;
6161
}
6262

63+
/* Returns size of sdsHdr by checking pointer alignment (expects 8 byte
64+
* alignment). Optimizes retriving sdsHdr size by not refering to sds data */
65+
static inline int sdsHdrSizeOptim(char* s) {
66+
switch((uintptr_t)s&7) {
67+
case SDS_MOD8(5):
68+
return sizeof(struct sdshdr5);
69+
case SDS_MOD8(8):
70+
return sizeof(struct sdshdr8);
71+
case SDS_MOD8(16):
72+
return sizeof(struct sdshdr16);
73+
case SDS_MOD8(32):
74+
return sizeof(struct sdshdr32);
75+
case SDS_MOD8(64):
76+
return sizeof(struct sdshdr64);
77+
}
78+
return 0;
79+
}
80+
6381
static inline char sdsReqType(size_t string_size) {
6482
if (string_size < 1<<5)
6583
return SDS_TYPE_5;
@@ -185,6 +203,11 @@ void sdsfree(sds s) {
185203
s_free((char*)s-sdsHdrSize(s[-1]));
186204
}
187205

206+
void sdsfreeOptim(sds s) {
207+
if (s == NULL) return;
208+
s_free((char*)s-sdsHdrSizeOptim(s));
209+
}
210+
188211
/* Set the sds string length to the length as obtained with strlen(), so
189212
* considering as content only up to the first null term character.
190213
*

src/sds.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,14 @@ struct __attribute__ ((__packed__)) sdshdr32 {
6464
uint32_t len; /* used */
6565
uint32_t alloc; /* excluding the header and null terminator */
6666
unsigned char flags; /* 3 lsb of type, 5 unused bits */
67+
char padding; /* Added to have unique value for %8 operation*/
6768
char buf[];
6869
};
6970
struct __attribute__ ((__packed__)) sdshdr64 {
7071
uint64_t len; /* used */
7172
uint64_t alloc; /* excluding the header and null terminator */
7273
unsigned char flags; /* 3 lsb of type, 5 unused bits */
74+
char padding[3]; /* Added to have unique value for %8 operation */
7375
char buf[];
7476
};
7577

@@ -83,6 +85,7 @@ struct __attribute__ ((__packed__)) sdshdr64 {
8385
#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (void*)((s)-(sizeof(struct sdshdr##T)));
8486
#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))
8587
#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS)
88+
#define SDS_MOD8(T) (sizeof(struct sdshdr##T)&7)
8689

8790
static inline size_t sdslen(const sds s) {
8891
unsigned char flags = s[-1];
@@ -221,6 +224,7 @@ sds sdsempty(void);
221224
sds sdsdramempty(void);
222225
sds sdsdup(const sds s);
223226
void sdsfree(sds s);
227+
void sdsfreeOptim(sds s);
224228
sds sdsgrowzero(sds s, size_t len);
225229
sds sdscatlen(sds s, const void *t, size_t len);
226230
sds sdscat(sds s, const char *t);

src/server.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,7 @@ void incrRefCount(robj *o);
17241724
robj *makeObjectShared(robj *o);
17251725
robj *resetRefCount(robj *obj);
17261726
void freeStringObject(robj *o);
1727+
void freeStringObjectOptim(robj *o);
17271728
void freeListObject(robj *o);
17281729
void freeSetObject(robj *o);
17291730
void freeZsetObject(robj *o);

0 commit comments

Comments
 (0)