Lazyfree: Hash converted to use plain SDS WIP 2.
This commit is contained in:
parent
1c247556c6
commit
777396aeba
32
src/object.c
32
src/object.c
@ -135,37 +135,7 @@ robj *createStringObjectFromLongLong(long long value) {
|
|||||||
* The 'humanfriendly' option is used for INCRBYFLOAT and HINCRBYFLOAT. */
|
* The 'humanfriendly' option is used for INCRBYFLOAT and HINCRBYFLOAT. */
|
||||||
robj *createStringObjectFromLongDouble(long double value, int humanfriendly) {
|
robj *createStringObjectFromLongDouble(long double value, int humanfriendly) {
|
||||||
char buf[256];
|
char buf[256];
|
||||||
int len;
|
int len = ld2string(buf,sizeof(buf),value,humanfriendly);
|
||||||
|
|
||||||
if (isinf(value)) {
|
|
||||||
/* Libc in odd systems (Hi Solaris!) will format infinite in a
|
|
||||||
* different way, so better to handle it in an explicit way. */
|
|
||||||
if (value > 0) {
|
|
||||||
memcpy(buf,"inf",3);
|
|
||||||
len = 3;
|
|
||||||
} else {
|
|
||||||
memcpy(buf,"-inf",4);
|
|
||||||
len = 4;
|
|
||||||
}
|
|
||||||
} else if (humanfriendly) {
|
|
||||||
/* We use 17 digits precision since with 128 bit floats that precision
|
|
||||||
* after rounding is able to represent most small decimal numbers in a
|
|
||||||
* way that is "non surprising" for the user (that is, most small
|
|
||||||
* decimal numbers will be represented in a way that when converted
|
|
||||||
* back into a string are exactly the same as what the user typed.) */
|
|
||||||
len = snprintf(buf,sizeof(buf),"%.17Lf", value);
|
|
||||||
/* Now remove trailing zeroes after the '.' */
|
|
||||||
if (strchr(buf,'.') != NULL) {
|
|
||||||
char *p = buf+len-1;
|
|
||||||
while(*p == '0') {
|
|
||||||
p--;
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
if (*p == '.') len--;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
len = snprintf(buf,sizeof(buf),"%.17Lg", value);
|
|
||||||
}
|
|
||||||
return createStringObject(buf,len);
|
return createStringObject(buf,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
src/t_hash.c
16
src/t_hash.c
@ -545,10 +545,12 @@ void hincrbyCommand(client *c) {
|
|||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX From here. */
|
||||||
|
|
||||||
void hincrbyfloatCommand(client *c) {
|
void hincrbyfloatCommand(client *c) {
|
||||||
double value, incr;
|
double value, incr;
|
||||||
long long ll;
|
long long ll;
|
||||||
robj *o, *doubleobj;
|
robj *o;
|
||||||
sds new;
|
sds new;
|
||||||
unsigned char *vstr;
|
unsigned char *vstr;
|
||||||
unsigned int *lven;
|
unsigned int *lven;
|
||||||
@ -569,10 +571,12 @@ void hincrbyfloatCommand(client *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
value += incr;
|
value += incr;
|
||||||
doubleobj = createStringObjectFromLongDouble(value,1);
|
|
||||||
decrRefCount(doubleobj);
|
char buf[256];
|
||||||
|
int len = ld2string(buf,sizeof(buf),value,humanfriendly);
|
||||||
|
new = sdsnewlen(buf,len);
|
||||||
hashTypeSet(o,c->argv[2],new);
|
hashTypeSet(o,c->argv[2],new);
|
||||||
addReplyBulk(c,new);
|
addReplyBulkSds(c,new);
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(NOTIFY_HASH,"hincrbyfloat",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_HASH,"hincrbyfloat",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
@ -580,11 +584,13 @@ void hincrbyfloatCommand(client *c) {
|
|||||||
/* Always replicate HINCRBYFLOAT as an HSET command with the final value
|
/* Always replicate HINCRBYFLOAT as an HSET command with the final value
|
||||||
* in order to make sure that differences in float pricision or formatting
|
* in order to make sure that differences in float pricision or formatting
|
||||||
* will not create differences in replicas or after an AOF restart. */
|
* will not create differences in replicas or after an AOF restart. */
|
||||||
|
robj *aux, *newobj;
|
||||||
aux = createStringObject("HSET",4);
|
aux = createStringObject("HSET",4);
|
||||||
|
newobj = createRawStringObject(buf,len);
|
||||||
rewriteClientCommandArgument(c,0,aux);
|
rewriteClientCommandArgument(c,0,aux);
|
||||||
decrRefCount(aux);
|
decrRefCount(aux);
|
||||||
rewriteClientCommandArgument(c,3,new);
|
rewriteClientCommandArgument(c,3,new);
|
||||||
decrRefCount(new);
|
decrRefCount(newobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addHashFieldToReply(client *c, robj *o, robj *field) {
|
static void addHashFieldToReply(client *c, robj *o, robj *field) {
|
||||||
|
52
src/util.c
52
src/util.c
@ -444,7 +444,10 @@ int string2d(const char *s, size_t slen, double *dp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Convert a double to a string representation. Returns the number of bytes
|
/* Convert a double to a string representation. Returns the number of bytes
|
||||||
* required. The representation should always be parsable by strtod(3). */
|
* required. The representation should always be parsable by strtod(3).
|
||||||
|
* This function does not support human-friendly formatting like ld2string
|
||||||
|
* does. It is intented mainly to be used inside t_zset.c when writing scores
|
||||||
|
* into a ziplist representing a sorted set. */
|
||||||
int d2string(char *buf, size_t len, double value) {
|
int d2string(char *buf, size_t len, double value) {
|
||||||
if (isnan(value)) {
|
if (isnan(value)) {
|
||||||
len = snprintf(buf,len,"nan");
|
len = snprintf(buf,len,"nan");
|
||||||
@ -482,6 +485,53 @@ int d2string(char *buf, size_t len, double value) {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert a long double into a string. If humanfriendly is non-zero
|
||||||
|
* it does not use exponential format and trims trailing zeroes at the end,
|
||||||
|
* however this results in loss of precision. Otherwise exp format is used
|
||||||
|
* and the output of snprintf() is not modified.
|
||||||
|
*
|
||||||
|
* The function returns the length of the string or zero if there was not
|
||||||
|
* enough buffer room to store it. */
|
||||||
|
int ld2string(char *buf, size_t len, long double value, int humanfriendly) {
|
||||||
|
char buf[256];
|
||||||
|
size_t l;
|
||||||
|
|
||||||
|
if (isinf(value)) {
|
||||||
|
/* Libc in odd systems (Hi Solaris!) will format infinite in a
|
||||||
|
* different way, so better to handle it in an explicit way. */
|
||||||
|
if (len < 5) return 0; /* No room. 5 is "-inf\0" */
|
||||||
|
if (value > 0) {
|
||||||
|
memcpy(buf,"inf",3);
|
||||||
|
l = 3;
|
||||||
|
} else {
|
||||||
|
memcpy(buf,"-inf",4);
|
||||||
|
l = 4;
|
||||||
|
}
|
||||||
|
} else if (humanfriendly) {
|
||||||
|
/* We use 17 digits precision since with 128 bit floats that precision
|
||||||
|
* after rounding is able to represent most small decimal numbers in a
|
||||||
|
* way that is "non surprising" for the user (that is, most small
|
||||||
|
* decimal numbers will be represented in a way that when converted
|
||||||
|
* back into a string are exactly the same as what the user typed.) */
|
||||||
|
l = snprintf(buf,len,"%.17Lf", value);
|
||||||
|
if (l+1 > len) return 0; /* No room. */
|
||||||
|
/* Now remove trailing zeroes after the '.' */
|
||||||
|
if (strchr(buf,'.') != NULL) {
|
||||||
|
char *p = buf+len-1;
|
||||||
|
while(*p == '0') {
|
||||||
|
p--;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
if (*p == '.') len--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
l = snprintf(buf,len,"%.17Lg", value);
|
||||||
|
if (l+1 > len) return 0; /* No room. */
|
||||||
|
}
|
||||||
|
buf[l] = '\0';
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
/* Generate the Redis "Run ID", a SHA1-sized random number that identifies a
|
/* Generate the Redis "Run ID", a SHA1-sized random number that identifies a
|
||||||
* given execution of Redis, so that if you are talking with an instance
|
* given execution of Redis, so that if you are talking with an instance
|
||||||
* having run_id == A, and you reconnect and it has run_id == B, you can be
|
* having run_id == A, and you reconnect and it has run_id == B, you can be
|
||||||
|
@ -43,6 +43,7 @@ int string2ll(const char *s, size_t slen, long long *value);
|
|||||||
int string2l(const char *s, size_t slen, long *value);
|
int string2l(const char *s, size_t slen, long *value);
|
||||||
int string2d(const char *s, size_t slen, double *dp);
|
int string2d(const char *s, size_t slen, double *dp);
|
||||||
int d2string(char *buf, size_t len, double value);
|
int d2string(char *buf, size_t len, double value);
|
||||||
|
int ld2string(char *buf, size_t len, long double value, int humanfriendly);
|
||||||
sds getAbsolutePath(char *filename);
|
sds getAbsolutePath(char *filename);
|
||||||
int pathIsBaseName(char *path);
|
int pathIsBaseName(char *path);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user