summaryrefslogtreecommitdiff
path: root/src/sds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sds.c')
-rw-r--r--src/sds.c72
1 files changed, 36 insertions, 36 deletions
diff --git a/src/sds.c b/src/sds.c
index dbf6c64ad..4771b6b3e 100644
--- a/src/sds.c
+++ b/src/sds.c
@@ -38,6 +38,8 @@
static inline int sdsHdrSize(char type) {
switch(type&SDS_TYPE_MASK) {
+ case SDS_TYPE_5:
+ return sizeof(struct sdshdr5);
case SDS_TYPE_8:
return sizeof(struct sdshdr8);
case SDS_TYPE_16:
@@ -51,11 +53,13 @@ static inline int sdsHdrSize(char type) {
}
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;
- if (string_size<0xffff)
+ if (string_size < 0xffff)
return SDS_TYPE_16;
- if (string_size<0xffffffff)
+ if (string_size < 0xffffffff)
return SDS_TYPE_32;
return SDS_TYPE_64;
}
@@ -77,63 +81,54 @@ sds sdsnewlen(const void *init, size_t initlen) {
sds s;
char type = sdsReqType(initlen);
int hdrlen = sdsHdrSize(type);
-
+ unsigned char *fp; /* flags pointer. */
+
sh = zmalloc(hdrlen+initlen+1);
if (!init)
memset(sh, 0, hdrlen+initlen+1);
if (sh == NULL) return NULL;
s = (char*)sh+hdrlen;
+ fp = ((unsigned char*)s)-1;
switch(type) {
+ case SDS_TYPE_5: {
+ *fp = type | (initlen << SDS_TYPE_BITS);
+ break;
+ }
case SDS_TYPE_8: {
SDS_HDR_VAR(8,s);
sh->len = initlen;
sh->alloc = initlen;
+ *fp = type;
break;
}
case SDS_TYPE_16: {
SDS_HDR_VAR(16,s);
sh->len = initlen;
sh->alloc = initlen;
+ *fp = type;
break;
}
case SDS_TYPE_32: {
SDS_HDR_VAR(32,s);
sh->len = initlen;
sh->alloc = initlen;
+ *fp = type;
break;
}
case SDS_TYPE_64: {
SDS_HDR_VAR(64,s);
sh->len = initlen;
sh->alloc = initlen;
+ *fp = type;
break;
}
}
- s[-1] = type;
if (initlen && init)
memcpy(s, init, initlen);
s[initlen] = '\0';
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
* always has an implicit null term. */
sds sdsempty(void) {
@@ -195,7 +190,7 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
void *sh, *newsh;
size_t avail = sdsavail(s);
size_t len, newlen;
- char type, oldtype = s[-1];
+ char type, oldtype = s[-1] & SDS_TYPE_MASK;
int hdrlen;
if (avail >= addlen) return s;
@@ -207,7 +202,6 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
else
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);
hdrlen = sdsHdrSize(type);
if (oldtype==type) {
@@ -215,7 +209,8 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
if (newsh == NULL) return NULL;
s = (char*)newsh+hdrlen;
} 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);
if (newsh == NULL) return NULL;
memcpy((char*)newsh+hdrlen, s, len+1);
@@ -225,7 +220,6 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
sdssetlen(s, len);
}
sdssetalloc(s, newlen);
- s[-1] = type;
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. */
sds sdsRemoveFreeSpace(sds s) {
void *sh, *newsh;
- char type, oldtype = s[-1];
+ char type, oldtype = s[-1] & SDS_TYPE_MASK;
int hdrlen;
size_t len = sdslen(s);
sh = (char*)s-sdsHdrSize(oldtype);
@@ -258,8 +252,6 @@ sds sdsRemoveFreeSpace(sds s) {
sdssetlen(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;
}
@@ -275,7 +267,7 @@ size_t sdsAllocSize(sds s) {
return sdsHdrSize(s[-1])+alloc+1;
}
-/* Return the size consumed from the allocator,
+/* Return the size consumed from the allocator,
* including internal fragmentation */
size_t sdsZmallocSize(sds s) {
struct sdshdr *sh = (void*) (s-sdsHdrSize(s[-1]));
@@ -306,9 +298,17 @@ size_t sdsZmallocSize(sds s) {
* sdsIncrLen(s, nread);
*/
void sdsIncrLen(sds s, int incr) {
- char flags = s[-1];
+ unsigned char flags = s[-1];
size_t len;
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: {
SDS_HDR_VAR(8,s);
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"
#define UNUSED(x) (void)(x)
-int sdsTest(int argc, char *argv[]) {
- UNUSED(argc);
- UNUSED(argv);
+int sdsTest(void) {
{
- struct sdshdr *sh;
sds x = sdsnew("foo"), y;
test_cond("Create a string and obtain the length",
@@ -1109,6 +1106,7 @@ int sdsTest(int argc, char *argv[]) {
sdslen(x) == 60 &&
memcmp(x,"--Hello Hi! World -9223372036854775808,"
"9223372036854775807--",60) == 0)
+ printf("[%s]\n",x);
sdsfree(x);
x = sdsnew("--");
@@ -1195,6 +1193,7 @@ int sdsTest(int argc, char *argv[]) {
test_cond("sdscatrepr(...data...)",
memcmp(y,"\"\\a\\n\\x00foo\\r\"",15) == 0)
+#if 0
{
unsigned int oldfree;
@@ -1215,6 +1214,7 @@ int sdsTest(int argc, char *argv[]) {
sdsfree(x);
}
+#endif
}
test_report()
return 0;