Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
974514b9
Commit
974514b9
authored
Sep 23, 2015
by
antirez
Browse files
Lazyfree: Hash converted to use plain SDS WIP 4.
parent
4a183528
Changes
9
Hide whitespace changes
Inline
Side-by-side
src/aof.c
View file @
974514b9
...
@@ -928,17 +928,13 @@ static int rioWriteHashIteratorCursor(rio *r, hashTypeIterator *hi, int what) {
...
@@ -928,17 +928,13 @@ static int rioWriteHashIteratorCursor(rio *r, hashTypeIterator *hi, int what) {
long
long
vll
=
LLONG_MAX
;
long
long
vll
=
LLONG_MAX
;
hashTypeCurrentFromZiplist
(
hi
,
what
,
&
vstr
,
&
vlen
,
&
vll
);
hashTypeCurrentFromZiplist
(
hi
,
what
,
&
vstr
,
&
vlen
,
&
vll
);
if
(
vstr
)
{
if
(
vstr
)
return
rioWriteBulkString
(
r
,
(
char
*
)
vstr
,
vlen
);
return
rioWriteBulkString
(
r
,
(
char
*
)
vstr
,
vlen
);
}
else
{
else
return
rioWriteBulkLongLong
(
r
,
vll
);
return
rioWriteBulkLongLong
(
r
,
vll
);
}
}
else
if
(
hi
->
encoding
==
OBJ_ENCODING_HT
)
{
}
else
if
(
hi
->
encoding
==
OBJ_ENCODING_HT
)
{
robj
*
value
;
sds
value
=
hashTypeCurrentFromHashTable
(
hi
,
what
);
return
rioWriteBulkString
(
r
,
value
,
sdslen
(
value
));
hashTypeCurrentFromHashTable
(
hi
,
what
,
&
value
);
return
rioWriteBulkObject
(
r
,
value
);
}
}
serverPanic
(
"Unknown hash encoding"
);
serverPanic
(
"Unknown hash encoding"
);
...
...
src/db.c
View file @
974514b9
...
@@ -420,11 +420,11 @@ void scanCallback(void *privdata, const dictEntry *de) {
...
@@ -420,11 +420,11 @@ void scanCallback(void *privdata, const dictEntry *de) {
}
else
if
(
o
->
type
==
OBJ_HASH
)
{
}
else
if
(
o
->
type
==
OBJ_HASH
)
{
sds
sdskey
=
dictGetKey
(
de
);
sds
sdskey
=
dictGetKey
(
de
);
sds
sdsval
=
dictGetVal
(
de
);
sds
sdsval
=
dictGetVal
(
de
);
key
=
createStringObject
(
key
sds
,
sdslen
(
key
sds
));
key
=
createStringObject
(
sds
key
,
sdslen
(
sds
key
));
val
=
createStringObject
(
val
sds
,
sdslen
(
val
sds
));
val
=
createStringObject
(
sds
val
,
sdslen
(
sds
val
));
}
else
if
(
o
->
type
==
OBJ_ZSET
)
{
}
else
if
(
o
->
type
==
OBJ_ZSET
)
{
sds
key
sds
=
dictGetKey
(
de
);
sds
sds
key
=
dictGetKey
(
de
);
key
=
createStringObject
(
key
sds
,
sdslen
(
key
sds
));
key
=
createStringObject
(
sds
key
,
sdslen
(
sds
key
));
val
=
createStringObjectFromLongDouble
(
*
(
double
*
)
dictGetVal
(
de
),
0
);
val
=
createStringObjectFromLongDouble
(
*
(
double
*
)
dictGetVal
(
de
),
0
);
}
else
{
}
else
{
serverPanic
(
"Type not handled in SCAN callback."
);
serverPanic
(
"Type not handled in SCAN callback."
);
...
...
src/debug.c
View file @
974514b9
...
@@ -222,20 +222,18 @@ void computeDatasetDigest(unsigned char *final) {
...
@@ -222,20 +222,18 @@ void computeDatasetDigest(unsigned char *final) {
serverPanic
(
"Unknown sorted set encoding"
);
serverPanic
(
"Unknown sorted set encoding"
);
}
}
}
else
if
(
o
->
type
==
OBJ_HASH
)
{
}
else
if
(
o
->
type
==
OBJ_HASH
)
{
hashTypeIterator
*
hi
;
hashTypeIterator
*
hi
=
hashTypeInitIterator
(
o
);
robj
*
obj
;
hi
=
hashTypeInitIterator
(
o
);
while
(
hashTypeNext
(
hi
)
!=
C_ERR
)
{
while
(
hashTypeNext
(
hi
)
!=
C_ERR
)
{
unsigned
char
eledigest
[
20
];
unsigned
char
eledigest
[
20
];
sds
sdsele
;
memset
(
eledigest
,
0
,
20
);
memset
(
eledigest
,
0
,
20
);
obj
=
hashTypeCurrentObject
(
hi
,
OBJ_HASH_KEY
);
sdsele
=
hashTypeCurrentObject
NewSds
(
hi
,
OBJ_HASH_KEY
);
mix
Object
Digest
(
eledigest
,
obj
);
mixDigest
(
eledigest
,
sdsele
,
sdslen
(
sdsele
)
);
decrRefCount
(
obj
);
sdsfree
(
sdsele
);
obj
=
hashTypeCurrentObject
(
hi
,
OBJ_HASH_VALUE
);
sdsele
=
hashTypeCurrentObject
NewSds
(
hi
,
OBJ_HASH_VALUE
);
mix
Object
Digest
(
eledigest
,
obj
);
mixDigest
(
eledigest
,
sdsele
,
sdslen
(
sdsele
)
);
decrRefCount
(
obj
);
sdsfree
(
sdsele
);
xorDigest
(
digest
,
eledigest
,
20
);
xorDigest
(
digest
,
eledigest
,
20
);
}
}
hashTypeReleaseIterator
(
hi
);
hashTypeReleaseIterator
(
hi
);
...
...
src/object.c
View file @
974514b9
...
@@ -613,7 +613,7 @@ int strict_strtoll(char *str, long long *vp) {
...
@@ -613,7 +613,7 @@ int strict_strtoll(char *str, long long *vp) {
long
long
value
;
long
long
value
;
errno
=
0
;
errno
=
0
;
value
=
strtoll
(
o
->
p
tr
,
&
eptr
,
10
);
value
=
strtoll
(
s
tr
,
&
eptr
,
10
);
if
(
isspace
(
str
[
0
])
||
eptr
[
0
]
!=
'\0'
||
errno
==
ERANGE
)
return
C_ERR
;
if
(
isspace
(
str
[
0
])
||
eptr
[
0
]
!=
'\0'
||
errno
==
ERANGE
)
return
C_ERR
;
if
(
vp
)
*
vp
=
value
;
if
(
vp
)
*
vp
=
value
;
return
C_OK
;
return
C_OK
;
...
...
src/server.c
View file @
974514b9
...
@@ -607,7 +607,7 @@ dictType hashDictType = {
...
@@ -607,7 +607,7 @@ dictType hashDictType = {
dictSdsHash
,
/* hash function */
dictSdsHash
,
/* hash function */
NULL
,
/* key dup */
NULL
,
/* key dup */
NULL
,
/* val dup */
NULL
,
/* val dup */
dict
s
dsKeyCompare
,
/* key compare */
dict
S
dsKeyCompare
,
/* key compare */
dictSdsDestructor
,
/* key destructor */
dictSdsDestructor
,
/* key destructor */
dictSdsDestructor
/* val destructor */
dictSdsDestructor
/* val destructor */
};
};
...
...
src/server.h
View file @
974514b9
...
@@ -1333,10 +1333,9 @@ void setTypeConvert(robj *subject, int enc);
...
@@ -1333,10 +1333,9 @@ void setTypeConvert(robj *subject, int enc);
void
hashTypeConvert
(
robj
*
o
,
int
enc
);
void
hashTypeConvert
(
robj
*
o
,
int
enc
);
void
hashTypeTryConversion
(
robj
*
subject
,
robj
**
argv
,
int
start
,
int
end
);
void
hashTypeTryConversion
(
robj
*
subject
,
robj
**
argv
,
int
start
,
int
end
);
void
hashTypeTryObjectEncoding
(
robj
*
subject
,
robj
**
o1
,
robj
**
o2
);
void
hashTypeTryObjectEncoding
(
robj
*
subject
,
robj
**
o1
,
robj
**
o2
);
robj
*
hashTypeGetObject
(
robj
*
o
,
robj
*
key
);
int
hashTypeExists
(
robj
*
o
,
sds
key
);
int
hashTypeExists
(
robj
*
o
,
robj
*
key
);
int
hashTypeSet
(
robj
*
o
,
sds
key
,
sds
value
);
int
hashTypeSet
(
robj
*
o
,
robj
*
key
,
robj
*
value
);
int
hashTypeDelete
(
robj
*
o
,
sds
key
);
int
hashTypeDelete
(
robj
*
o
,
robj
*
key
);
unsigned
long
hashTypeLength
(
robj
*
o
);
unsigned
long
hashTypeLength
(
robj
*
o
);
hashTypeIterator
*
hashTypeInitIterator
(
robj
*
subject
);
hashTypeIterator
*
hashTypeInitIterator
(
robj
*
subject
);
void
hashTypeReleaseIterator
(
hashTypeIterator
*
hi
);
void
hashTypeReleaseIterator
(
hashTypeIterator
*
hi
);
...
@@ -1345,9 +1344,11 @@ void hashTypeCurrentFromZiplist(hashTypeIterator *hi, int what,
...
@@ -1345,9 +1344,11 @@ void hashTypeCurrentFromZiplist(hashTypeIterator *hi, int what,
unsigned
char
**
vstr
,
unsigned
char
**
vstr
,
unsigned
int
*
vlen
,
unsigned
int
*
vlen
,
long
long
*
vll
);
long
long
*
vll
);
void
hashTypeCurrentFromHashTable
(
hashTypeIterator
*
hi
,
int
what
,
robj
**
dst
);
sds
hashTypeCurrentFromHashTable
(
hashTypeIterator
*
hi
,
int
what
);
robj
*
hashTypeCurrentObject
(
hashTypeIterator
*
hi
,
int
what
);
void
hashTypeCurrentObject
(
hashTypeIterator
*
hi
,
int
what
,
unsigned
char
**
vstr
,
unsigned
int
*
vlen
,
long
long
*
vll
);
sds
hashTypeCurrentObjectNewSds
(
hashTypeIterator
*
hi
,
int
what
);
robj
*
hashTypeLookupWriteOrCreate
(
client
*
c
,
robj
*
key
);
robj
*
hashTypeLookupWriteOrCreate
(
client
*
c
,
robj
*
key
);
robj
*
hashTypeGetValueObject
(
robj
*
o
,
sds
field
);
/* Pub / Sub */
/* Pub / Sub */
int
pubsubUnsubscribeAllChannels
(
client
*
c
,
int
notify
);
int
pubsubUnsubscribeAllChannels
(
client
*
c
,
int
notify
);
...
...
src/sort.c
View file @
974514b9
...
@@ -112,9 +112,9 @@ robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
...
@@ -112,9 +112,9 @@ robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
if
(
fieldobj
)
{
if
(
fieldobj
)
{
if
(
o
->
type
!=
OBJ_HASH
)
goto
noobj
;
if
(
o
->
type
!=
OBJ_HASH
)
goto
noobj
;
/* Retrieve value from hash by the field name. Th
is operation
/* Retrieve value from hash by the field name. Th
e returend object
*
already increases
th
e
refcount
of the returned object
. */
*
is a new object wi
th refcount
already incremented
. */
o
=
hashTypeGetObject
(
o
,
fieldobj
);
o
=
hashTypeGet
Value
Object
(
o
,
fieldobj
->
ptr
);
}
else
{
}
else
{
if
(
o
->
type
!=
OBJ_STRING
)
goto
noobj
;
if
(
o
->
type
!=
OBJ_STRING
)
goto
noobj
;
...
...
src/t_hash.c
View file @
974514b9
...
@@ -67,7 +67,7 @@ int hashTypeGetFromZiplist(robj *o, sds field,
...
@@ -67,7 +67,7 @@ int hashTypeGetFromZiplist(robj *o, sds field,
zl
=
o
->
ptr
;
zl
=
o
->
ptr
;
fptr
=
ziplistIndex
(
zl
,
ZIPLIST_HEAD
);
fptr
=
ziplistIndex
(
zl
,
ZIPLIST_HEAD
);
if
(
fptr
!=
NULL
)
{
if
(
fptr
!=
NULL
)
{
fptr
=
ziplistFind
(
fptr
,
field
,
sdslen
(
field
),
1
);
fptr
=
ziplistFind
(
fptr
,
(
unsigned
char
*
)
field
,
sdslen
(
field
),
1
);
if
(
fptr
!=
NULL
)
{
if
(
fptr
!=
NULL
)
{
/* Grab pointer to the value (fptr points to the field) */
/* Grab pointer to the value (fptr points to the field) */
vptr
=
ziplistNext
(
zl
,
fptr
);
vptr
=
ziplistNext
(
zl
,
fptr
);
...
@@ -106,15 +106,15 @@ sds hashTypeGetFromHashTable(robj *o, sds field) {
...
@@ -106,15 +106,15 @@ sds hashTypeGetFromHashTable(robj *o, sds field) {
* If *vll is populated *vstr is set to NULL, so the caller
* If *vll is populated *vstr is set to NULL, so the caller
* can always check the function return by checking the return value
* can always check the function return by checking the return value
* for C_OK and checking if vll (or vstr) is NULL. */
* for C_OK and checking if vll (or vstr) is NULL. */
int
hashTypeGet
Object
(
robj
*
o
,
sds
field
,
unsigned
char
**
vstr
,
unsigned
int
*
vlen
,
long
long
*
vll
)
{
int
hashTypeGet
Value
(
robj
*
o
,
sds
field
,
unsigned
char
**
vstr
,
unsigned
int
*
vlen
,
long
long
*
vll
)
{
if
(
o
->
encoding
==
OBJ_ENCODING_ZIPLIST
)
{
if
(
o
->
encoding
==
OBJ_ENCODING_ZIPLIST
)
{
*
vstr
=
NULL
;
*
vstr
=
NULL
;
if
(
hashTypeGetFromZiplist
(
o
,
field
,
vstr
,
vlen
,
vll
)
==
0
)
if
(
hashTypeGetFromZiplist
(
o
,
field
,
vstr
,
vlen
,
vll
)
==
0
)
return
C_OK
;
return
C_OK
;
}
else
if
(
o
->
encoding
==
OBJ_ENCODING_HT
)
{
}
else
if
(
o
->
encoding
==
OBJ_ENCODING_HT
)
{
sds
value
;
sds
value
;
if
(
value
=
hashTypeGetFromHashTable
(
o
,
field
)
!=
NULL
)
{
if
(
(
value
=
hashTypeGetFromHashTable
(
o
,
field
)
)
!=
NULL
)
{
*
vstr
=
value
;
*
vstr
=
(
unsigned
char
*
)
value
;
*
vlen
=
sdslen
(
value
);
*
vlen
=
sdslen
(
value
);
return
C_OK
;
return
C_OK
;
}
}
...
@@ -124,6 +124,20 @@ int hashTypeGetObject(robj *o, sds field, unsigned char **vstr, unsigned int *vl
...
@@ -124,6 +124,20 @@ int hashTypeGetObject(robj *o, sds field, unsigned char **vstr, unsigned int *vl
return
C_ERR
;
return
C_ERR
;
}
}
/* Like hashTypeGetValue() but returns a Redis object, which is useful for
* interaction with the hash type outside t_hash.c.
* The function returns NULL if the field is not found in the hash. Otherwise
* a newly allocated string object with the value is returned. */
robj
*
hashTypeGetValueObject
(
robj
*
o
,
sds
field
)
{
unsigned
char
*
vstr
;
unsigned
int
vlen
;
long
long
vll
;
if
(
hashTypeGetValue
(
o
,
field
,
&
vstr
,
&
vlen
,
&
vll
)
==
C_ERR
)
return
NULL
;
if
(
vstr
)
return
createStringObject
((
char
*
)
vstr
,
vlen
);
else
return
createStringObjectFromLongLong
(
vll
);
}
/* Higher level function using hashTypeGet*() to return the length of the
/* Higher level function using hashTypeGet*() to return the length of the
* object associated with the requested field, or 0 if the field does not
* object associated with the requested field, or 0 if the field does not
* exist. */
* exist. */
...
@@ -157,8 +171,6 @@ int hashTypeExists(robj *o, sds field) {
...
@@ -157,8 +171,6 @@ int hashTypeExists(robj *o, sds field) {
if
(
hashTypeGetFromZiplist
(
o
,
field
,
&
vstr
,
&
vlen
,
&
vll
)
==
0
)
return
1
;
if
(
hashTypeGetFromZiplist
(
o
,
field
,
&
vstr
,
&
vlen
,
&
vll
)
==
0
)
return
1
;
}
else
if
(
o
->
encoding
==
OBJ_ENCODING_HT
)
{
}
else
if
(
o
->
encoding
==
OBJ_ENCODING_HT
)
{
robj
*
aux
;
if
(
hashTypeGetFromHashTable
(
o
,
field
)
!=
NULL
)
return
1
;
if
(
hashTypeGetFromHashTable
(
o
,
field
)
!=
NULL
)
return
1
;
}
else
{
}
else
{
serverPanic
(
"Unknown hash encoding"
);
serverPanic
(
"Unknown hash encoding"
);
...
@@ -178,7 +190,7 @@ int hashTypeSet(robj *o, sds field, sds value) {
...
@@ -178,7 +190,7 @@ int hashTypeSet(robj *o, sds field, sds value) {
zl
=
o
->
ptr
;
zl
=
o
->
ptr
;
fptr
=
ziplistIndex
(
zl
,
ZIPLIST_HEAD
);
fptr
=
ziplistIndex
(
zl
,
ZIPLIST_HEAD
);
if
(
fptr
!=
NULL
)
{
if
(
fptr
!=
NULL
)
{
fptr
=
ziplistFind
(
fptr
,
field
,
sdslen
(
field
),
1
);
fptr
=
ziplistFind
(
fptr
,
(
unsigned
char
*
)
field
,
sdslen
(
field
),
1
);
if
(
fptr
!=
NULL
)
{
if
(
fptr
!=
NULL
)
{
/* Grab pointer to the value (fptr points to the field) */
/* Grab pointer to the value (fptr points to the field) */
vptr
=
ziplistNext
(
zl
,
fptr
);
vptr
=
ziplistNext
(
zl
,
fptr
);
...
@@ -189,14 +201,17 @@ int hashTypeSet(robj *o, sds field, sds value) {
...
@@ -189,14 +201,17 @@ int hashTypeSet(robj *o, sds field, sds value) {
zl
=
ziplistDelete
(
zl
,
&
vptr
);
zl
=
ziplistDelete
(
zl
,
&
vptr
);
/* Insert new value */
/* Insert new value */
zl
=
ziplistInsert
(
zl
,
vptr
,
value
->
ptr
,
sdslen
(
value
->
ptr
));
zl
=
ziplistInsert
(
zl
,
vptr
,
(
unsigned
char
*
)
value
,
sdslen
(
value
));
}
}
}
}
if
(
!
update
)
{
if
(
!
update
)
{
/* Push new field/value pair onto the tail of the ziplist */
/* Push new field/value pair onto the tail of the ziplist */
zl
=
ziplistPush
(
zl
,
field
,
sdslen
(
field
),
ZIPLIST_TAIL
);
zl
=
ziplistPush
(
zl
,
(
unsigned
char
*
)
field
,
sdslen
(
field
),
zl
=
ziplistPush
(
zl
,
value
,
sdslen
(
value
),
ZIPLIST_TAIL
);
ZIPLIST_TAIL
);
zl
=
ziplistPush
(
zl
,
(
unsigned
char
*
)
value
,
sdslen
(
value
),
ZIPLIST_TAIL
);
}
}
o
->
ptr
=
zl
;
o
->
ptr
=
zl
;
...
@@ -210,7 +225,7 @@ int hashTypeSet(robj *o, sds field, sds value) {
...
@@ -210,7 +225,7 @@ int hashTypeSet(robj *o, sds field, sds value) {
dictGetVal
(
de
)
=
sdsdup
(
value
);
dictGetVal
(
de
)
=
sdsdup
(
value
);
update
=
1
;
update
=
1
;
}
else
{
}
else
{
dictAdd
(
o
->
ptr
,
sdsdup
(
key
),
sdsdup
(
value
));
dictAdd
(
o
->
ptr
,
sdsdup
(
field
),
sdsdup
(
value
));
}
}
}
else
{
}
else
{
serverPanic
(
"Unknown hash encoding"
);
serverPanic
(
"Unknown hash encoding"
);
...
@@ -229,7 +244,7 @@ int hashTypeDelete(robj *o, sds field) {
...
@@ -229,7 +244,7 @@ int hashTypeDelete(robj *o, sds field) {
zl
=
o
->
ptr
;
zl
=
o
->
ptr
;
fptr
=
ziplistIndex
(
zl
,
ZIPLIST_HEAD
);
fptr
=
ziplistIndex
(
zl
,
ZIPLIST_HEAD
);
if
(
fptr
!=
NULL
)
{
if
(
fptr
!=
NULL
)
{
fptr
=
ziplistFind
(
fptr
,
field
,
sdslen
(
field
),
1
);
fptr
=
ziplistFind
(
fptr
,
(
unsigned
char
*
)
field
,
sdslen
(
field
),
1
);
if
(
fptr
!=
NULL
)
{
if
(
fptr
!=
NULL
)
{
zl
=
ziplistDelete
(
zl
,
&
fptr
);
zl
=
ziplistDelete
(
zl
,
&
fptr
);
zl
=
ziplistDelete
(
zl
,
&
fptr
);
zl
=
ziplistDelete
(
zl
,
&
fptr
);
...
@@ -237,9 +252,6 @@ int hashTypeDelete(robj *o, sds field) {
...
@@ -237,9 +252,6 @@ int hashTypeDelete(robj *o, sds field) {
deleted
=
1
;
deleted
=
1
;
}
}
}
}
decrRefCount
(
field
);
}
else
if
(
o
->
encoding
==
OBJ_ENCODING_HT
)
{
}
else
if
(
o
->
encoding
==
OBJ_ENCODING_HT
)
{
if
(
dictDelete
((
dict
*
)
o
->
ptr
,
field
)
==
C_OK
)
{
if
(
dictDelete
((
dict
*
)
o
->
ptr
,
field
)
==
C_OK
)
{
deleted
=
1
;
deleted
=
1
;
...
@@ -376,7 +388,7 @@ void hashTypeCurrentObject(hashTypeIterator *hi, int what, unsigned char **vstr,
...
@@ -376,7 +388,7 @@ void hashTypeCurrentObject(hashTypeIterator *hi, int what, unsigned char **vstr,
hashTypeCurrentFromZiplist
(
hi
,
what
,
vstr
,
vlen
,
vll
);
hashTypeCurrentFromZiplist
(
hi
,
what
,
vstr
,
vlen
,
vll
);
}
else
if
(
hi
->
encoding
==
OBJ_ENCODING_HT
)
{
}
else
if
(
hi
->
encoding
==
OBJ_ENCODING_HT
)
{
sds
ele
=
hashTypeCurrentFromHashTable
(
hi
,
what
);
sds
ele
=
hashTypeCurrentFromHashTable
(
hi
,
what
);
*
vstr
=
ele
;
*
vstr
=
(
unsigned
char
*
)
ele
;
*
vlen
=
sdslen
(
ele
);
*
vlen
=
sdslen
(
ele
);
}
else
{
}
else
{
serverPanic
(
"Unknown hash encoding"
);
serverPanic
(
"Unknown hash encoding"
);
...
@@ -424,14 +436,11 @@ void hashTypeConvertZiplist(robj *o, int enc) {
...
@@ -424,14 +436,11 @@ void hashTypeConvertZiplist(robj *o, int enc) {
dict
=
dictCreate
(
&
hashDictType
,
NULL
);
dict
=
dictCreate
(
&
hashDictType
,
NULL
);
while
(
hashTypeNext
(
hi
)
!=
C_ERR
)
{
while
(
hashTypeNext
(
hi
)
!=
C_ERR
)
{
unsigned
char
*
vstr
;
unsigned
int
vlen
;
long
long
vll
;
sds
key
,
value
;
sds
key
,
value
;
key
=
hashTypeCurrentObjectNewSds
(
hi
,
OBJ_HASH_KEY
);
key
=
hashTypeCurrentObjectNewSds
(
hi
,
OBJ_HASH_KEY
);
value
=
hashTypeCurrentObjectNewSds
(
hi
,
OBJ_HASH_VALUE
);
value
=
hashTypeCurrentObjectNewSds
(
hi
,
OBJ_HASH_VALUE
);
ret
=
dictAdd
(
dict
,
field
,
value
);
ret
=
dictAdd
(
dict
,
key
,
value
);
if
(
ret
!=
DICT_OK
)
{
if
(
ret
!=
DICT_OK
)
{
serverLogHexDump
(
LL_WARNING
,
"ziplist with dup elements dump"
,
serverLogHexDump
(
LL_WARNING
,
"ziplist with dup elements dump"
,
o
->
ptr
,
ziplistBlobLen
(
o
->
ptr
));
o
->
ptr
,
ziplistBlobLen
(
o
->
ptr
));
...
@@ -515,17 +524,17 @@ void hincrbyCommand(client *c) {
...
@@ -515,17 +524,17 @@ void hincrbyCommand(client *c) {
robj
*
o
;
robj
*
o
;
sds
new
;
sds
new
;
unsigned
char
*
vstr
;
unsigned
char
*
vstr
;
unsigned
int
*
l
ven
;
unsigned
int
v
l
en
;
if
(
getLongLongFromObjectOrReply
(
c
,
c
->
argv
[
3
],
&
incr
,
NULL
)
!=
C_OK
)
return
;
if
(
getLongLongFromObjectOrReply
(
c
,
c
->
argv
[
3
],
&
incr
,
NULL
)
!=
C_OK
)
return
;
if
((
o
=
hashTypeLookupWriteOrCreate
(
c
,
c
->
argv
[
1
]))
==
NULL
)
return
;
if
((
o
=
hashTypeLookupWriteOrCreate
(
c
,
c
->
argv
[
1
]))
==
NULL
)
return
;
if
(
hashTypeGet
Object
(
o
,
c
->
argv
[
2
],
&
vstr
,
&
vlen
,
&
value
)
==
C_OK
)
{
if
(
hashTypeGet
Value
(
o
,
c
->
argv
[
2
]
->
ptr
,
&
vstr
,
&
vlen
,
&
value
)
==
C_OK
)
{
if
(
vstr
)
{
if
(
vstr
)
{
if
(
string2ll
(
vstr
,
vlen
,
&
value
)
==
0
)
{
if
(
string2ll
(
(
char
*
)
vstr
,
vlen
,
&
value
)
==
0
)
{
addReplyError
(
c
,
"hash value is not an integer"
);
addReplyError
(
c
,
"hash value is not an integer"
);
return
;
return
;
}
}
}
/* Else hashTypeGet
Object
() already stored it into &value */
}
/* Else hashTypeGet
Value
() already stored it into &value */
}
else
{
}
else
{
value
=
0
;
value
=
0
;
}
}
...
@@ -551,13 +560,13 @@ void hincrbyfloatCommand(client *c) {
...
@@ -551,13 +560,13 @@ void hincrbyfloatCommand(client *c) {
robj
*
o
;
robj
*
o
;
sds
new
;
sds
new
;
unsigned
char
*
vstr
;
unsigned
char
*
vstr
;
unsigned
int
*
l
ven
;
unsigned
int
v
l
en
;
if
(
get
Long
DoubleFromObjectOrReply
(
c
,
c
->
argv
[
3
],
&
incr
,
NULL
)
!=
C_OK
)
return
;
if
(
getDoubleFromObjectOrReply
(
c
,
c
->
argv
[
3
],
&
incr
,
NULL
)
!=
C_OK
)
return
;
if
((
o
=
hashTypeLookupWriteOrCreate
(
c
,
c
->
argv
[
1
]))
==
NULL
)
return
;
if
((
o
=
hashTypeLookupWriteOrCreate
(
c
,
c
->
argv
[
1
]))
==
NULL
)
return
;
if
(
hashTypeGet
Object
(
o
,
c
->
argv
[
2
]
,
vstr
,
vlen
,
&
ll
)
==
C_OK
)
{
if
(
hashTypeGet
Value
(
o
,
c
->
argv
[
2
]
->
ptr
,
&
vstr
,
&
vlen
,
&
ll
)
==
C_OK
)
{
if
(
vstr
)
{
if
(
vstr
)
{
if
(
string2d
(
vstr
,
vlen
,
&
value
)
==
0
)
{
if
(
string2d
(
(
char
*
)
vstr
,
vlen
,
&
value
)
==
0
)
{
addReplyError
(
c
,
"hash value is not an integer"
);
addReplyError
(
c
,
"hash value is not an integer"
);
return
;
return
;
}
}
...
@@ -571,9 +580,9 @@ void hincrbyfloatCommand(client *c) {
...
@@ -571,9 +580,9 @@ void hincrbyfloatCommand(client *c) {
value
+=
incr
;
value
+=
incr
;
char
buf
[
256
];
char
buf
[
256
];
int
len
=
ld2string
(
buf
,
sizeof
(
buf
),
value
,
humanfriendly
);
int
len
=
ld2string
(
buf
,
sizeof
(
buf
),
value
,
1
);
new
=
sdsnewlen
(
buf
,
len
);
new
=
sdsnewlen
(
buf
,
len
);
hashTypeSet
(
o
,
c
->
argv
[
2
],
new
);
hashTypeSet
(
o
,
c
->
argv
[
2
]
->
ptr
,
new
);
addReplyBulkSds
(
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
);
...
@@ -587,12 +596,10 @@ void hincrbyfloatCommand(client *c) {
...
@@ -587,12 +596,10 @@ void hincrbyfloatCommand(client *c) {
newobj
=
createRawStringObject
(
buf
,
len
);
newobj
=
createRawStringObject
(
buf
,
len
);
rewriteClientCommandArgument
(
c
,
0
,
aux
);
rewriteClientCommandArgument
(
c
,
0
,
aux
);
decrRefCount
(
aux
);
decrRefCount
(
aux
);
rewriteClientCommandArgument
(
c
,
3
,
new
);
rewriteClientCommandArgument
(
c
,
3
,
new
obj
);
decrRefCount
(
newobj
);
decrRefCount
(
newobj
);
}
}
/* XXX From here. */
static
void
addHashFieldToReply
(
client
*
c
,
robj
*
o
,
sds
field
)
{
static
void
addHashFieldToReply
(
client
*
c
,
robj
*
o
,
sds
field
)
{
int
ret
;
int
ret
;
...
...
src/util.c
View file @
974514b9
...
@@ -427,12 +427,17 @@ int string2l(const char *s, size_t slen, long *lval) {
...
@@ -427,12 +427,17 @@ int string2l(const char *s, size_t slen, long *lval) {
* a double: no spaces or other characters before or after the string
* a double: no spaces or other characters before or after the string
* representing the number are accepted. */
* representing the number are accepted. */
int
string2d
(
const
char
*
s
,
size_t
slen
,
double
*
dp
)
{
int
string2d
(
const
char
*
s
,
size_t
slen
,
double
*
dp
)
{
char
buf
[
256
];
double
value
;
double
value
;
char
*
eptr
;
if
(
slen
>=
sizeof
(
buf
))
return
0
;
memcpy
(
buf
,
s
,
slen
);
buf
[
slen
]
=
'\0'
;
errno
=
0
;
errno
=
0
;
value
=
strtod
(
o
->
ptr
,
&
eptr
);
value
=
strtod
(
buf
,
&
eptr
);
if
(
isspace
(((
char
*
)
o
->
ptr
)[
0
])
||
if
(
isspace
(
buf
[
0
])
||
eptr
[
0
]
!=
'\0'
||
eptr
[
0
]
!=
'\0'
||
(
errno
==
ERANGE
&&
(
errno
==
ERANGE
&&
(
value
==
HUGE_VAL
||
value
==
-
HUGE_VAL
||
value
==
0
))
||
(
value
==
HUGE_VAL
||
value
==
-
HUGE_VAL
||
value
==
0
))
||
errno
==
EINVAL
||
errno
==
EINVAL
||
...
@@ -493,7 +498,6 @@ int d2string(char *buf, size_t len, double value) {
...
@@ -493,7 +498,6 @@ int d2string(char *buf, size_t len, double value) {
* The function returns the length of the string or zero if there was not
* The function returns the length of the string or zero if there was not
* enough buffer room to store it. */
* enough buffer room to store it. */
int
ld2string
(
char
*
buf
,
size_t
len
,
long
double
value
,
int
humanfriendly
)
{
int
ld2string
(
char
*
buf
,
size_t
len
,
long
double
value
,
int
humanfriendly
)
{
char
buf
[
256
];
size_t
l
;
size_t
l
;
if
(
isinf
(
value
))
{
if
(
isinf
(
value
))
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment