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
1dab60df
Commit
1dab60df
authored
Sep 23, 2015
by
antirez
Browse files
Hash new implementation memleaks fixed.
parent
97ba4e38
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/server.h
View file @
1dab60df
...
@@ -1334,7 +1334,6 @@ void hashTypeConvert(robj *o, int enc);
...
@@ -1334,7 +1334,6 @@ 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
);
int
hashTypeExists
(
robj
*
o
,
sds
key
);
int
hashTypeExists
(
robj
*
o
,
sds
key
);
int
hashTypeSet
(
robj
*
o
,
sds
key
,
sds
value
);
int
hashTypeDelete
(
robj
*
o
,
sds
key
);
int
hashTypeDelete
(
robj
*
o
,
sds
key
);
unsigned
long
hashTypeLength
(
robj
*
o
);
unsigned
long
hashTypeLength
(
robj
*
o
);
hashTypeIterator
*
hashTypeInitIterator
(
robj
*
subject
);
hashTypeIterator
*
hashTypeInitIterator
(
robj
*
subject
);
...
...
src/t_hash.c
View file @
1dab60df
...
@@ -179,9 +179,27 @@ int hashTypeExists(robj *o, sds field) {
...
@@ -179,9 +179,27 @@ int hashTypeExists(robj *o, sds field) {
}
}
/* Add a new field, overwrite the old with the new value if it already exists.
/* Add a new field, overwrite the old with the new value if it already exists.
* Return 0 on insert and 1 on update. The key and value SDS strings are copied
* Return 0 on insert and 1 on update.
* if needed, so the caller retains ownership of the strings passed. */
*
int
hashTypeSet
(
robj
*
o
,
sds
field
,
sds
value
)
{
* By default, the key and value SDS strings are copied if needed, so the
* caller retains ownership of the strings passed. However this behavior
* can be effected by passing appropriate flags (possibly bitwise OR-ed):
*
* HASH_SET_TAKE_FIELD -- The SDS field ownership passes to the function.
* HASH_SET_TAKE_VALUE -- The SDS value ownership passes to the function.
*
* When the flags are used the caller does not need to release the passed
* SDS string(s). It's up to the function to use the string to create a new
* entry or to free the SDS string before returning to the caller.
*
* HASH_SET_COPY corresponds to no flags passed, and means the default
* semantics of copying the values if needed.
*
*/
#define HASH_SET_TAKE_FIELD (1<<0)
#define HASH_SET_TAKE_VALUE (1<<1)
#define HASH_SET_COPY 0
int
hashTypeSet
(
robj
*
o
,
sds
field
,
sds
value
,
int
flags
)
{
int
update
=
0
;
int
update
=
0
;
if
(
o
->
encoding
==
OBJ_ENCODING_ZIPLIST
)
{
if
(
o
->
encoding
==
OBJ_ENCODING_ZIPLIST
)
{
...
@@ -222,14 +240,37 @@ int hashTypeSet(robj *o, sds field, sds value) {
...
@@ -222,14 +240,37 @@ int hashTypeSet(robj *o, sds field, sds value) {
dictEntry
*
de
=
dictFind
(
o
->
ptr
,
field
);
dictEntry
*
de
=
dictFind
(
o
->
ptr
,
field
);
if
(
de
)
{
if
(
de
)
{
sdsfree
(
dictGetVal
(
de
));
sdsfree
(
dictGetVal
(
de
));
dictGetVal
(
de
)
=
sdsdup
(
value
);
if
(
flags
&
HASH_SET_TAKE_VALUE
)
{
dictGetVal
(
de
)
=
value
;
value
=
NULL
;
}
else
{
dictGetVal
(
de
)
=
sdsdup
(
value
);
}
update
=
1
;
update
=
1
;
}
else
{
}
else
{
dictAdd
(
o
->
ptr
,
sdsdup
(
field
),
sdsdup
(
value
));
sds
f
,
v
;
if
(
flags
&
HASH_SET_TAKE_FIELD
)
{
f
=
field
;
field
=
NULL
;
}
else
{
f
=
sdsdup
(
field
);
}
if
(
flags
&
HASH_SET_TAKE_VALUE
)
{
v
=
value
;
value
=
NULL
;
}
else
{
v
=
sdsdup
(
value
);
}
dictAdd
(
o
->
ptr
,
f
,
v
);
}
}
}
else
{
}
else
{
serverPanic
(
"Unknown hash encoding"
);
serverPanic
(
"Unknown hash encoding"
);
}
}
/* Free SDS strings we did not referenced elsewhere if the flags
* want this function to be responsible. */
if
(
flags
&
HASH_SET_TAKE_FIELD
&&
field
)
sdsfree
(
field
);
if
(
flags
&
HASH_SET_TAKE_VALUE
&&
value
)
sdsfree
(
value
);
return
update
;
return
update
;
}
}
...
@@ -476,7 +517,7 @@ void hsetCommand(client *c) {
...
@@ -476,7 +517,7 @@ void hsetCommand(client *c) {
if
((
o
=
hashTypeLookupWriteOrCreate
(
c
,
c
->
argv
[
1
]))
==
NULL
)
return
;
if
((
o
=
hashTypeLookupWriteOrCreate
(
c
,
c
->
argv
[
1
]))
==
NULL
)
return
;
hashTypeTryConversion
(
o
,
c
->
argv
,
2
,
3
);
hashTypeTryConversion
(
o
,
c
->
argv
,
2
,
3
);
update
=
hashTypeSet
(
o
,
c
->
argv
[
2
]
->
ptr
,
c
->
argv
[
3
]
->
ptr
);
update
=
hashTypeSet
(
o
,
c
->
argv
[
2
]
->
ptr
,
c
->
argv
[
3
]
->
ptr
,
HASH_SET_COPY
);
addReply
(
c
,
update
?
shared
.
czero
:
shared
.
cone
);
addReply
(
c
,
update
?
shared
.
czero
:
shared
.
cone
);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
notifyKeyspaceEvent
(
NOTIFY_HASH
,
"hset"
,
c
->
argv
[
1
],
c
->
db
->
id
);
notifyKeyspaceEvent
(
NOTIFY_HASH
,
"hset"
,
c
->
argv
[
1
],
c
->
db
->
id
);
...
@@ -491,7 +532,7 @@ void hsetnxCommand(client *c) {
...
@@ -491,7 +532,7 @@ void hsetnxCommand(client *c) {
if
(
hashTypeExists
(
o
,
c
->
argv
[
2
]
->
ptr
))
{
if
(
hashTypeExists
(
o
,
c
->
argv
[
2
]
->
ptr
))
{
addReply
(
c
,
shared
.
czero
);
addReply
(
c
,
shared
.
czero
);
}
else
{
}
else
{
hashTypeSet
(
o
,
c
->
argv
[
2
]
->
ptr
,
c
->
argv
[
3
]
->
ptr
);
hashTypeSet
(
o
,
c
->
argv
[
2
]
->
ptr
,
c
->
argv
[
3
]
->
ptr
,
HASH_SET_COPY
);
addReply
(
c
,
shared
.
cone
);
addReply
(
c
,
shared
.
cone
);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
notifyKeyspaceEvent
(
NOTIFY_HASH
,
"hset"
,
c
->
argv
[
1
],
c
->
db
->
id
);
notifyKeyspaceEvent
(
NOTIFY_HASH
,
"hset"
,
c
->
argv
[
1
],
c
->
db
->
id
);
...
@@ -511,7 +552,7 @@ void hmsetCommand(client *c) {
...
@@ -511,7 +552,7 @@ void hmsetCommand(client *c) {
if
((
o
=
hashTypeLookupWriteOrCreate
(
c
,
c
->
argv
[
1
]))
==
NULL
)
return
;
if
((
o
=
hashTypeLookupWriteOrCreate
(
c
,
c
->
argv
[
1
]))
==
NULL
)
return
;
hashTypeTryConversion
(
o
,
c
->
argv
,
2
,
c
->
argc
-
1
);
hashTypeTryConversion
(
o
,
c
->
argv
,
2
,
c
->
argc
-
1
);
for
(
i
=
2
;
i
<
c
->
argc
;
i
+=
2
)
{
for
(
i
=
2
;
i
<
c
->
argc
;
i
+=
2
)
{
hashTypeSet
(
o
,
c
->
argv
[
i
]
->
ptr
,
c
->
argv
[
i
+
1
]
->
ptr
);
hashTypeSet
(
o
,
c
->
argv
[
i
]
->
ptr
,
c
->
argv
[
i
+
1
]
->
ptr
,
HASH_SET_COPY
);
}
}
addReply
(
c
,
shared
.
ok
);
addReply
(
c
,
shared
.
ok
);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
...
@@ -547,7 +588,7 @@ void hincrbyCommand(client *c) {
...
@@ -547,7 +588,7 @@ void hincrbyCommand(client *c) {
}
}
value
+=
incr
;
value
+=
incr
;
new
=
sdsfromlonglong
(
value
);
new
=
sdsfromlonglong
(
value
);
hashTypeSet
(
o
,
c
->
argv
[
2
]
->
ptr
,
new
);
hashTypeSet
(
o
,
c
->
argv
[
2
]
->
ptr
,
new
,
HASH_SET_TAKE_VALUE
);
addReplyLongLong
(
c
,
value
);
addReplyLongLong
(
c
,
value
);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
notifyKeyspaceEvent
(
NOTIFY_HASH
,
"hincrby"
,
c
->
argv
[
1
],
c
->
db
->
id
);
notifyKeyspaceEvent
(
NOTIFY_HASH
,
"hincrby"
,
c
->
argv
[
1
],
c
->
db
->
id
);
...
@@ -582,8 +623,8 @@ void hincrbyfloatCommand(client *c) {
...
@@ -582,8 +623,8 @@ void hincrbyfloatCommand(client *c) {
char
buf
[
256
];
char
buf
[
256
];
int
len
=
ld2string
(
buf
,
sizeof
(
buf
),
value
,
1
);
int
len
=
ld2string
(
buf
,
sizeof
(
buf
),
value
,
1
);
new
=
sdsnewlen
(
buf
,
len
);
new
=
sdsnewlen
(
buf
,
len
);
hashTypeSet
(
o
,
c
->
argv
[
2
]
->
ptr
,
new
);
hashTypeSet
(
o
,
c
->
argv
[
2
]
->
ptr
,
new
,
HASH_SET_TAKE_VALUE
);
addReplyBulk
Sds
(
c
,
new
);
addReplyBulk
CBuffer
(
c
,
buf
,
len
);
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
++
;
...
...
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