Skip to content

Commit 5fb70a6

Browse files
authored
Merge pull request #202 from jschmieg/optimSdsFree
Optimize cache-misses on sds free
2 parents 4b72f11 + 085d8d9 commit 5fb70a6

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);
@@ -364,7 +370,7 @@ void incrRefCount(robj *o) {
364370
static void _decrRefCount(robj *o, int on_dram) {
365371
if (o->refcount == 1) {
366372
switch(o->type) {
367-
case OBJ_STRING: freeStringObject(o); break;
373+
case OBJ_STRING: freeStringObjectOptim(o); break;
368374
case OBJ_LIST: freeListObject(o); break;
369375
case OBJ_SET: freeSetObject(o); break;
370376
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
@@ -1756,6 +1756,7 @@ void incrRefCount(robj *o);
17561756
robj *makeObjectShared(robj *o);
17571757
robj *resetRefCount(robj *obj);
17581758
void freeStringObject(robj *o);
1759+
void freeStringObjectOptim(robj *o);
17591760
void freeListObject(robj *o);
17601761
void freeSetObject(robj *o);
17611762
void freeZsetObject(robj *o);

0 commit comments

Comments
 (0)