mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 08:38:27 -05:00
SDS: New sds type 5 implemented.
This is an attempt to use the refcount feature of the sds.c fork provided in the Pull Request #2509. A new type, SDS_TYPE_5 is introduced having a one byte header with just the string length, without information about the available additional length at the end of the string (this means that sdsMakeRoomFor() will be required each time we want to append something, since the string will always report to have 0 bytes available). More work needed in order to avoid common SDS functions will pay the cost of this type. For example both sdscatprintf() and sdscatfmt() should try to upgrade to SDS_TYPE_8 ASAP when appending chars.
This commit is contained in:
parent
056a0ca199
commit
0ab27a4594
68
src/sds.c
68
src/sds.c
@ -38,6 +38,8 @@
|
|||||||
|
|
||||||
static inline int sdsHdrSize(char type) {
|
static inline int sdsHdrSize(char type) {
|
||||||
switch(type&SDS_TYPE_MASK) {
|
switch(type&SDS_TYPE_MASK) {
|
||||||
|
case SDS_TYPE_5:
|
||||||
|
return sizeof(struct sdshdr5);
|
||||||
case SDS_TYPE_8:
|
case SDS_TYPE_8:
|
||||||
return sizeof(struct sdshdr8);
|
return sizeof(struct sdshdr8);
|
||||||
case SDS_TYPE_16:
|
case SDS_TYPE_16:
|
||||||
@ -51,11 +53,13 @@ static inline int sdsHdrSize(char type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline char sdsReqType(size_t string_size) {
|
static inline char sdsReqType(size_t string_size) {
|
||||||
if (string_size<0xff)
|
if (string_size < 32)
|
||||||
|
return SDS_TYPE_5;
|
||||||
|
if (string_size < 0xff)
|
||||||
return SDS_TYPE_8;
|
return SDS_TYPE_8;
|
||||||
if (string_size<0xffff)
|
if (string_size < 0xffff)
|
||||||
return SDS_TYPE_16;
|
return SDS_TYPE_16;
|
||||||
if (string_size<0xffffffff)
|
if (string_size < 0xffffffff)
|
||||||
return SDS_TYPE_32;
|
return SDS_TYPE_32;
|
||||||
return SDS_TYPE_64;
|
return SDS_TYPE_64;
|
||||||
}
|
}
|
||||||
@ -77,63 +81,54 @@ sds sdsnewlen(const void *init, size_t initlen) {
|
|||||||
sds s;
|
sds s;
|
||||||
char type = sdsReqType(initlen);
|
char type = sdsReqType(initlen);
|
||||||
int hdrlen = sdsHdrSize(type);
|
int hdrlen = sdsHdrSize(type);
|
||||||
|
unsigned char *fp; /* flags pointer. */
|
||||||
|
|
||||||
sh = zmalloc(hdrlen+initlen+1);
|
sh = zmalloc(hdrlen+initlen+1);
|
||||||
if (!init)
|
if (!init)
|
||||||
memset(sh, 0, hdrlen+initlen+1);
|
memset(sh, 0, hdrlen+initlen+1);
|
||||||
if (sh == NULL) return NULL;
|
if (sh == NULL) return NULL;
|
||||||
s = (char*)sh+hdrlen;
|
s = (char*)sh+hdrlen;
|
||||||
|
fp = ((unsigned char*)s)-1;
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
case SDS_TYPE_5: {
|
||||||
|
*fp = type | (initlen << SDS_TYPE_BITS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SDS_TYPE_8: {
|
case SDS_TYPE_8: {
|
||||||
SDS_HDR_VAR(8,s);
|
SDS_HDR_VAR(8,s);
|
||||||
sh->len = initlen;
|
sh->len = initlen;
|
||||||
sh->alloc = initlen;
|
sh->alloc = initlen;
|
||||||
|
*fp = type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDS_TYPE_16: {
|
case SDS_TYPE_16: {
|
||||||
SDS_HDR_VAR(16,s);
|
SDS_HDR_VAR(16,s);
|
||||||
sh->len = initlen;
|
sh->len = initlen;
|
||||||
sh->alloc = initlen;
|
sh->alloc = initlen;
|
||||||
|
*fp = type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDS_TYPE_32: {
|
case SDS_TYPE_32: {
|
||||||
SDS_HDR_VAR(32,s);
|
SDS_HDR_VAR(32,s);
|
||||||
sh->len = initlen;
|
sh->len = initlen;
|
||||||
sh->alloc = initlen;
|
sh->alloc = initlen;
|
||||||
|
*fp = type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDS_TYPE_64: {
|
case SDS_TYPE_64: {
|
||||||
SDS_HDR_VAR(64,s);
|
SDS_HDR_VAR(64,s);
|
||||||
sh->len = initlen;
|
sh->len = initlen;
|
||||||
sh->alloc = initlen;
|
sh->alloc = initlen;
|
||||||
|
*fp = type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s[-1] = type;
|
|
||||||
if (initlen && init)
|
if (initlen && init)
|
||||||
memcpy(s, init, initlen);
|
memcpy(s, init, initlen);
|
||||||
s[initlen] = '\0';
|
s[initlen] = '\0';
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdsIncRefcount(sds s) {
|
|
||||||
unsigned char flags = s[-1];
|
|
||||||
unsigned refs = flags>>SDS_TYPE_BITS;
|
|
||||||
assert(++refs);
|
|
||||||
s[-1] = (refs<<SDS_TYPE_BITS) | (flags&SDS_TYPE_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sdsDecRefcount(sds s) {
|
|
||||||
unsigned char flags = s[-1];
|
|
||||||
void *sh = (char*)s-sdsHdrSize(s[-1]);
|
|
||||||
unsigned refs = flags>>SDS_TYPE_BITS;
|
|
||||||
assert(refs);
|
|
||||||
if (!(--refs))
|
|
||||||
zfree(sh);
|
|
||||||
else
|
|
||||||
s[-1] = (refs<<SDS_TYPE_BITS) | (flags&SDS_TYPE_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create an empty (zero length) sds string. Even in this case the string
|
/* Create an empty (zero length) sds string. Even in this case the string
|
||||||
* always has an implicit null term. */
|
* always has an implicit null term. */
|
||||||
sds sdsempty(void) {
|
sds sdsempty(void) {
|
||||||
@ -195,7 +190,7 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
|
|||||||
void *sh, *newsh;
|
void *sh, *newsh;
|
||||||
size_t avail = sdsavail(s);
|
size_t avail = sdsavail(s);
|
||||||
size_t len, newlen;
|
size_t len, newlen;
|
||||||
char type, oldtype = s[-1];
|
char type, oldtype = s[-1] & SDS_TYPE_MASK;
|
||||||
int hdrlen;
|
int hdrlen;
|
||||||
|
|
||||||
if (avail >= addlen) return s;
|
if (avail >= addlen) return s;
|
||||||
@ -207,7 +202,6 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
|
|||||||
else
|
else
|
||||||
newlen += SDS_MAX_PREALLOC;
|
newlen += SDS_MAX_PREALLOC;
|
||||||
|
|
||||||
assert(!(s[-1]>>SDS_TYPE_BITS));/* verify that the ref count is 0 (non ref count managed string) */
|
|
||||||
type = sdsReqType(newlen);
|
type = sdsReqType(newlen);
|
||||||
hdrlen = sdsHdrSize(type);
|
hdrlen = sdsHdrSize(type);
|
||||||
if (oldtype==type) {
|
if (oldtype==type) {
|
||||||
@ -215,7 +209,8 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
|
|||||||
if (newsh == NULL) return NULL;
|
if (newsh == NULL) return NULL;
|
||||||
s = (char*)newsh+hdrlen;
|
s = (char*)newsh+hdrlen;
|
||||||
} else {
|
} else {
|
||||||
/* since the header size changes, need to move the string forward, and can't use realloc */
|
/* Since the header size changes, need to move the string forward,
|
||||||
|
* and can't use realloc */
|
||||||
newsh = zmalloc(hdrlen+newlen+1);
|
newsh = zmalloc(hdrlen+newlen+1);
|
||||||
if (newsh == NULL) return NULL;
|
if (newsh == NULL) return NULL;
|
||||||
memcpy((char*)newsh+hdrlen, s, len+1);
|
memcpy((char*)newsh+hdrlen, s, len+1);
|
||||||
@ -225,7 +220,6 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
|
|||||||
sdssetlen(s, len);
|
sdssetlen(s, len);
|
||||||
}
|
}
|
||||||
sdssetalloc(s, newlen);
|
sdssetalloc(s, newlen);
|
||||||
s[-1] = type;
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +231,7 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
|
|||||||
* references must be substituted with the new pointer returned by the call. */
|
* references must be substituted with the new pointer returned by the call. */
|
||||||
sds sdsRemoveFreeSpace(sds s) {
|
sds sdsRemoveFreeSpace(sds s) {
|
||||||
void *sh, *newsh;
|
void *sh, *newsh;
|
||||||
char type, oldtype = s[-1];
|
char type, oldtype = s[-1] & SDS_TYPE_MASK;
|
||||||
int hdrlen;
|
int hdrlen;
|
||||||
size_t len = sdslen(s);
|
size_t len = sdslen(s);
|
||||||
sh = (char*)s-sdsHdrSize(oldtype);
|
sh = (char*)s-sdsHdrSize(oldtype);
|
||||||
@ -258,8 +252,6 @@ sds sdsRemoveFreeSpace(sds s) {
|
|||||||
sdssetlen(s, len);
|
sdssetlen(s, len);
|
||||||
}
|
}
|
||||||
sdssetalloc(s, len);
|
sdssetalloc(s, len);
|
||||||
assert(!(s[-1]>>SDS_TYPE_BITS));/* verify that the ref count is 0 (non ref count managed string) */
|
|
||||||
s[-1] = type;
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,9 +298,17 @@ size_t sdsZmallocSize(sds s) {
|
|||||||
* sdsIncrLen(s, nread);
|
* sdsIncrLen(s, nread);
|
||||||
*/
|
*/
|
||||||
void sdsIncrLen(sds s, int incr) {
|
void sdsIncrLen(sds s, int incr) {
|
||||||
char flags = s[-1];
|
unsigned char flags = s[-1];
|
||||||
size_t len;
|
size_t len;
|
||||||
switch(flags&SDS_TYPE_MASK) {
|
switch(flags&SDS_TYPE_MASK) {
|
||||||
|
case SDS_TYPE_5: {
|
||||||
|
unsigned char *fp = ((unsigned char*)s)-1;
|
||||||
|
unsigned char oldlen = SDS_TYPE_5_LEN(flags);
|
||||||
|
assert((incr > 0 && oldlen+incr < 32) || (incr < 0 && oldlen >= (unsigned int)(-incr)));
|
||||||
|
*fp = SDS_TYPE_5 | ((oldlen+1) << SDS_TYPE_BITS);
|
||||||
|
len = oldlen+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SDS_TYPE_8: {
|
case SDS_TYPE_8: {
|
||||||
SDS_HDR_VAR(8,s);
|
SDS_HDR_VAR(8,s);
|
||||||
assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr)));
|
assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr)));
|
||||||
@ -1069,11 +1069,8 @@ sds sdsjoin(char **argv, int argc, char *sep) {
|
|||||||
#include "limits.h"
|
#include "limits.h"
|
||||||
|
|
||||||
#define UNUSED(x) (void)(x)
|
#define UNUSED(x) (void)(x)
|
||||||
int sdsTest(int argc, char *argv[]) {
|
int sdsTest(void) {
|
||||||
UNUSED(argc);
|
|
||||||
UNUSED(argv);
|
|
||||||
{
|
{
|
||||||
struct sdshdr *sh;
|
|
||||||
sds x = sdsnew("foo"), y;
|
sds x = sdsnew("foo"), y;
|
||||||
|
|
||||||
test_cond("Create a string and obtain the length",
|
test_cond("Create a string and obtain the length",
|
||||||
@ -1109,6 +1106,7 @@ int sdsTest(int argc, char *argv[]) {
|
|||||||
sdslen(x) == 60 &&
|
sdslen(x) == 60 &&
|
||||||
memcmp(x,"--Hello Hi! World -9223372036854775808,"
|
memcmp(x,"--Hello Hi! World -9223372036854775808,"
|
||||||
"9223372036854775807--",60) == 0)
|
"9223372036854775807--",60) == 0)
|
||||||
|
printf("[%s]\n",x);
|
||||||
|
|
||||||
sdsfree(x);
|
sdsfree(x);
|
||||||
x = sdsnew("--");
|
x = sdsnew("--");
|
||||||
@ -1195,6 +1193,7 @@ int sdsTest(int argc, char *argv[]) {
|
|||||||
test_cond("sdscatrepr(...data...)",
|
test_cond("sdscatrepr(...data...)",
|
||||||
memcmp(y,"\"\\a\\n\\x00foo\\r\"",15) == 0)
|
memcmp(y,"\"\\a\\n\\x00foo\\r\"",15) == 0)
|
||||||
|
|
||||||
|
#if 0
|
||||||
{
|
{
|
||||||
unsigned int oldfree;
|
unsigned int oldfree;
|
||||||
|
|
||||||
@ -1215,6 +1214,7 @@ int sdsTest(int argc, char *argv[]) {
|
|||||||
|
|
||||||
sdsfree(x);
|
sdsfree(x);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
test_report()
|
test_report()
|
||||||
return 0;
|
return 0;
|
||||||
|
68
src/sds.h
68
src/sds.h
@ -39,43 +39,53 @@
|
|||||||
|
|
||||||
typedef char *sds;
|
typedef char *sds;
|
||||||
|
|
||||||
|
/* Note: sdshdr5 is never used, we just access the flags byte directly.
|
||||||
|
* However is here to document the layout of type 5 SDS strings. */
|
||||||
|
struct __attribute__ ((__packed__)) sdshdr5 {
|
||||||
|
unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
|
||||||
|
char buf[];
|
||||||
|
};
|
||||||
struct __attribute__ ((__packed__)) sdshdr8 {
|
struct __attribute__ ((__packed__)) sdshdr8 {
|
||||||
uint8_t len; /* used */
|
uint8_t len; /* used */
|
||||||
uint8_t alloc; /* excluding the header and null terminator */
|
uint8_t alloc; /* excluding the header and null terminator */
|
||||||
char flags; /* 2 lsb of type, and 6 msb of refcount */
|
unsigned char flags; /* 3 lsb of type, 5 unused bits */
|
||||||
char buf[];
|
char buf[];
|
||||||
};
|
};
|
||||||
struct __attribute__ ((__packed__)) sdshdr16 {
|
struct __attribute__ ((__packed__)) sdshdr16 {
|
||||||
uint16_t len; /* used */
|
uint16_t len; /* used */
|
||||||
uint16_t alloc; /* excluding the header and null terminator */
|
uint16_t alloc; /* excluding the header and null terminator */
|
||||||
char flags; /* 2 lsb of type, and 6 msb of refcount */
|
unsigned char flags; /* 3 lsb of type, 5 unused bits */
|
||||||
char buf[];
|
char buf[];
|
||||||
};
|
};
|
||||||
struct __attribute__ ((__packed__)) sdshdr32 {
|
struct __attribute__ ((__packed__)) sdshdr32 {
|
||||||
uint32_t len; /* used */
|
uint32_t len; /* used */
|
||||||
uint32_t alloc; /* excluding the header and null terminator */
|
uint32_t alloc; /* excluding the header and null terminator */
|
||||||
char flags; /* 2 lsb of type, and 6 msb of refcount */
|
unsigned char flags; /* 3 lsb of type, 5 unused bits */
|
||||||
char buf[];
|
char buf[];
|
||||||
};
|
};
|
||||||
struct __attribute__ ((__packed__)) sdshdr64 {
|
struct __attribute__ ((__packed__)) sdshdr64 {
|
||||||
uint64_t len; /* used */
|
uint64_t len; /* used */
|
||||||
uint64_t alloc; /* excluding the header and null terminator */
|
uint64_t alloc; /* excluding the header and null terminator */
|
||||||
char flags; /* 2 lsb of type, and 6 msb of refcount */
|
unsigned char flags; /* 3 lsb of type, 5 unused bits */
|
||||||
char buf[];
|
char buf[];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SDS_TYPE_8 0
|
#define SDS_TYPE_5 0
|
||||||
#define SDS_TYPE_16 1
|
#define SDS_TYPE_8 1
|
||||||
#define SDS_TYPE_32 2
|
#define SDS_TYPE_16 2
|
||||||
#define SDS_TYPE_64 3
|
#define SDS_TYPE_32 3
|
||||||
#define SDS_TYPE_MASK 3
|
#define SDS_TYPE_64 4
|
||||||
#define SDS_TYPE_BITS 2
|
#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_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_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))
|
||||||
|
#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS)
|
||||||
|
|
||||||
static inline size_t sdslen(const sds s) {
|
static inline size_t sdslen(const sds s) {
|
||||||
char flags = s[-1];
|
unsigned char flags = s[-1];
|
||||||
switch(flags&SDS_TYPE_MASK) {
|
switch(flags&SDS_TYPE_MASK) {
|
||||||
|
case SDS_TYPE_5:
|
||||||
|
return SDS_TYPE_5_LEN(flags);
|
||||||
case SDS_TYPE_8:
|
case SDS_TYPE_8:
|
||||||
return SDS_HDR(8,s)->len;
|
return SDS_HDR(8,s)->len;
|
||||||
case SDS_TYPE_16:
|
case SDS_TYPE_16:
|
||||||
@ -89,8 +99,11 @@ static inline size_t sdslen(const sds s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t sdsavail(const sds s) {
|
static inline size_t sdsavail(const sds s) {
|
||||||
char flags = s[-1];
|
unsigned char flags = s[-1];
|
||||||
switch(flags&SDS_TYPE_MASK) {
|
switch(flags&SDS_TYPE_MASK) {
|
||||||
|
case SDS_TYPE_5: {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case SDS_TYPE_8: {
|
case SDS_TYPE_8: {
|
||||||
SDS_HDR_VAR(8,s);
|
SDS_HDR_VAR(8,s);
|
||||||
return sh->alloc - sh->len;
|
return sh->alloc - sh->len;
|
||||||
@ -112,8 +125,14 @@ static inline size_t sdsavail(const sds s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void sdssetlen(sds s, size_t newlen) {
|
static inline void sdssetlen(sds s, size_t newlen) {
|
||||||
char flags = s[-1];
|
unsigned char flags = s[-1];
|
||||||
switch(flags&SDS_TYPE_MASK) {
|
switch(flags&SDS_TYPE_MASK) {
|
||||||
|
case SDS_TYPE_5:
|
||||||
|
{
|
||||||
|
unsigned char *fp = ((unsigned char*)s)-1;
|
||||||
|
*fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SDS_TYPE_8:
|
case SDS_TYPE_8:
|
||||||
SDS_HDR(8,s)->len = newlen;
|
SDS_HDR(8,s)->len = newlen;
|
||||||
break;
|
break;
|
||||||
@ -130,8 +149,15 @@ static inline void sdssetlen(sds s, size_t newlen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void sdsinclen(sds s, size_t inc) {
|
static inline void sdsinclen(sds s, size_t inc) {
|
||||||
char flags = s[-1];
|
unsigned char flags = s[-1];
|
||||||
switch(flags&SDS_TYPE_MASK) {
|
switch(flags&SDS_TYPE_MASK) {
|
||||||
|
case SDS_TYPE_5:
|
||||||
|
{
|
||||||
|
unsigned char *fp = ((unsigned char*)s)-1;
|
||||||
|
unsigned char newlen = SDS_TYPE_5_LEN(flags)+inc;
|
||||||
|
*fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SDS_TYPE_8:
|
case SDS_TYPE_8:
|
||||||
SDS_HDR(8,s)->len += inc;
|
SDS_HDR(8,s)->len += inc;
|
||||||
break;
|
break;
|
||||||
@ -149,8 +175,10 @@ static inline void sdsinclen(sds s, size_t inc) {
|
|||||||
|
|
||||||
/* sdsalloc() = sdsavail() + sdslen() */
|
/* sdsalloc() = sdsavail() + sdslen() */
|
||||||
static inline size_t sdsalloc(const sds s) {
|
static inline size_t sdsalloc(const sds s) {
|
||||||
char flags = s[-1];
|
unsigned char flags = s[-1];
|
||||||
switch(flags&SDS_TYPE_MASK) {
|
switch(flags&SDS_TYPE_MASK) {
|
||||||
|
case SDS_TYPE_5:
|
||||||
|
return SDS_TYPE_5_LEN(flags);
|
||||||
case SDS_TYPE_8:
|
case SDS_TYPE_8:
|
||||||
return SDS_HDR(8,s)->alloc;
|
return SDS_HDR(8,s)->alloc;
|
||||||
case SDS_TYPE_16:
|
case SDS_TYPE_16:
|
||||||
@ -164,8 +192,11 @@ static inline size_t sdsalloc(const sds s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void sdssetalloc(sds s, size_t newlen) {
|
static inline void sdssetalloc(sds s, size_t newlen) {
|
||||||
char flags = s[-1];
|
unsigned char flags = s[-1];
|
||||||
switch(flags&SDS_TYPE_MASK) {
|
switch(flags&SDS_TYPE_MASK) {
|
||||||
|
case SDS_TYPE_5:
|
||||||
|
/* Nothing to do, this type has no total allocation info. */
|
||||||
|
break;
|
||||||
case SDS_TYPE_8:
|
case SDS_TYPE_8:
|
||||||
SDS_HDR(8,s)->alloc = newlen;
|
SDS_HDR(8,s)->alloc = newlen;
|
||||||
break;
|
break;
|
||||||
@ -193,11 +224,6 @@ sds sdscatsds(sds s, const sds t);
|
|||||||
sds sdscpylen(sds s, const char *t, size_t len);
|
sds sdscpylen(sds s, const char *t, size_t len);
|
||||||
sds sdscpy(sds s, const char *t);
|
sds sdscpy(sds s, const char *t);
|
||||||
|
|
||||||
/* we can add a reference count on top of any
|
|
||||||
* existing sds. (max up to 63 references) */
|
|
||||||
void sdsIncRefcount(sds s);
|
|
||||||
void sdsDecRefcount(sds s);
|
|
||||||
|
|
||||||
sds sdscatvprintf(sds s, const char *fmt, va_list ap);
|
sds sdscatvprintf(sds s, const char *fmt, va_list ap);
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
sds sdscatprintf(sds s, const char *fmt, ...)
|
sds sdscatprintf(sds s, const char *fmt, ...)
|
||||||
|
Loading…
Reference in New Issue
Block a user