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
d4e9e0ae
Commit
d4e9e0ae
authored
Nov 18, 2022
by
Viktor Söderqvist
Browse files
activeDefragSdsDict use scan instead of iterator and drop dictSetNext
Also delete unused function activeDefragSdsListAndDict
parent
a67957ed
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/defrag.c
View file @
d4e9e0ae
...
@@ -149,35 +149,6 @@ luaScript *activeDefragLuaScript(luaScript *script, long *defragged) {
...
@@ -149,35 +149,6 @@ luaScript *activeDefragLuaScript(luaScript *script, long *defragged) {
return
ret
;
return
ret
;
}
}
/* Defrag helper for dictEntries to be used during dict iteration (called on
* each step). Returns a stat of how many pointers were moved. */
long
dictIterDefragEntry
(
dictIterator
*
iter
)
{
/* This function is a little bit dirty since it messes with the internals
* of the dict and it's iterator, but the benefit is that it is very easy
* to use, and require no other changes in the dict. */
long
defragged
=
0
;
/* Handle the next entry (if there is one), and update the pointer in the
* current entry. */
if
(
iter
->
nextEntry
)
{
dictEntry
*
newde
=
activeDefragAlloc
(
iter
->
nextEntry
);
if
(
newde
)
{
defragged
++
;
iter
->
nextEntry
=
newde
;
dictSetNext
(
iter
->
entry
,
newde
);
}
}
/* handle the case of the first entry in the hash bucket. */
if
(
iter
->
d
->
ht_table
[
iter
->
table
][
iter
->
index
]
==
iter
->
entry
)
{
dictEntry
*
newde
=
activeDefragAlloc
(
iter
->
entry
);
if
(
newde
)
{
iter
->
entry
=
newde
;
iter
->
d
->
ht_table
[
iter
->
table
][
iter
->
index
]
=
newde
;
defragged
++
;
}
}
return
defragged
;
}
/* Defrag helper for dict main allocations (dict struct, and hash tables).
/* Defrag helper for dict main allocations (dict struct, and hash tables).
* receives a pointer to the dict* and implicitly updates it when the dict
* receives a pointer to the dict* and implicitly updates it when the dict
* struct itself was moved. Returns a stat of how many pointers were moved. */
* struct itself was moved. Returns a stat of how many pointers were moved. */
...
@@ -279,38 +250,49 @@ long activeDefragZsetEntry(zset *zs, dictEntry *de) {
...
@@ -279,38 +250,49 @@ long activeDefragZsetEntry(zset *zs, dictEntry *de) {
#define DEFRAG_SDS_DICT_VAL_VOID_PTR 3
#define DEFRAG_SDS_DICT_VAL_VOID_PTR 3
#define DEFRAG_SDS_DICT_VAL_LUA_SCRIPT 4
#define DEFRAG_SDS_DICT_VAL_LUA_SCRIPT 4
/* Defrag a dict with sds key and optional value (either ptr, sds or robj string) */
typedef
struct
{
long
activeDefragSdsDict
(
dict
*
d
,
int
val_type
)
{
dict
*
dict
;
dictIterator
*
di
;
int
val_type
;
dictEntry
*
de
;
long
defragged
;
long
defragged
=
0
;
}
activeDefragSdsDictData
;
di
=
dictGetIterator
(
d
);
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
void
activeDefragSdsDictCallback
(
void
*
privdata
,
const
dictEntry
*
_de
)
{
sds
sdsele
=
dictGetKey
(
de
),
newsds
;
dictEntry
*
de
=
(
dictEntry
*
)
_de
;
activeDefragSdsDictData
*
data
=
privdata
;
dict
*
d
=
data
->
dict
;
int
val_type
=
data
->
val_type
;
sds
sdsele
=
dictGetKey
(
de
),
newsds
;
if
((
newsds
=
activeDefragSds
(
sdsele
)))
dictSetKey
(
d
,
de
,
newsds
),
data
->
defragged
++
;
/* defrag the value */
if
(
val_type
==
DEFRAG_SDS_DICT_VAL_IS_SDS
)
{
sdsele
=
dictGetVal
(
de
);
if
((
newsds
=
activeDefragSds
(
sdsele
)))
if
((
newsds
=
activeDefragSds
(
sdsele
)))
dictSetKey
(
d
,
de
,
newsds
),
defragged
++
;
dictSetVal
(
d
,
de
,
newsds
),
data
->
defragged
++
;
/* defrag the value */
}
else
if
(
val_type
==
DEFRAG_SDS_DICT_VAL_IS_STROB
)
{
if
(
val_type
==
DEFRAG_SDS_DICT_VAL_IS_SDS
)
{
robj
*
newele
,
*
ele
=
dictGetVal
(
de
);
sdsele
=
dictGetVal
(
de
);
if
((
newele
=
activeDefragStringOb
(
ele
,
&
data
->
defragged
)))
if
((
newsds
=
activeDefragSds
(
sdsele
)))
dictSetVal
(
d
,
de
,
newele
);
dictSetVal
(
d
,
de
,
newsds
),
defragged
++
;
}
else
if
(
val_type
==
DEFRAG_SDS_DICT_VAL_VOID_PTR
)
{
}
else
if
(
val_type
==
DEFRAG_SDS_DICT_VAL_IS_STROB
)
{
void
*
newptr
,
*
ptr
=
dictGetVal
(
de
);
robj
*
newele
,
*
ele
=
dictGetVal
(
de
);
if
((
newptr
=
activeDefragAlloc
(
ptr
)))
if
((
newele
=
activeDefragStringOb
(
ele
,
&
defragged
)))
dictSetVal
(
d
,
de
,
newptr
),
data
->
defragged
++
;
dictSetVal
(
d
,
de
,
newele
);
}
else
if
(
val_type
==
DEFRAG_SDS_DICT_VAL_LUA_SCRIPT
)
{
}
else
if
(
val_type
==
DEFRAG_SDS_DICT_VAL_VOID_PTR
)
{
void
*
newptr
,
*
ptr
=
dictGetVal
(
de
);
void
*
newptr
,
*
ptr
=
dictGetVal
(
de
);
if
((
newptr
=
activeDefragLuaScript
(
ptr
,
&
data
->
defragged
)))
if
((
newptr
=
activeDefragAlloc
(
ptr
)))
dictSetVal
(
d
,
de
,
newptr
);
dictSetVal
(
d
,
de
,
newptr
),
defragged
++
;
}
else
if
(
val_type
==
DEFRAG_SDS_DICT_VAL_LUA_SCRIPT
)
{
void
*
newptr
,
*
ptr
=
dictGetVal
(
de
);
if
((
newptr
=
activeDefragLuaScript
(
ptr
,
&
defragged
)))
dictSetVal
(
d
,
de
,
newptr
);
}
defragged
+=
dictIterDefragEntry
(
di
);
}
}
dictReleaseIterator
(
di
);
}
return
defragged
;
/* Defrag a dict with sds key and optional value (either ptr, sds or robj string) */
long
activeDefragSdsDict
(
dict
*
d
,
int
val_type
)
{
activeDefragSdsDictData
data
=
{
d
,
val_type
,
0
};
unsigned
long
cursor
=
0
;
do
{
cursor
=
dictScan
(
d
,
cursor
,
activeDefragSdsDictCallback
,
defragDictBucketCallback
,
&
data
);
}
while
(
cursor
!=
0
);
return
data
.
defragged
;
}
}
/* Defrag a list of ptr, sds or robj string values */
/* Defrag a list of ptr, sds or robj string values */
...
@@ -347,62 +329,6 @@ long activeDefragList(list *l, int val_type) {
...
@@ -347,62 +329,6 @@ long activeDefragList(list *l, int val_type) {
return
defragged
;
return
defragged
;
}
}
/* Defrag a list of sds values and a dict with the same sds keys */
long
activeDefragSdsListAndDict
(
list
*
l
,
dict
*
d
,
int
dict_val_type
)
{
long
defragged
=
0
;
sds
newsds
,
sdsele
;
listNode
*
ln
,
*
newln
;
dictIterator
*
di
;
dictEntry
*
de
;
/* Defrag the list and it's sds values */
for
(
ln
=
l
->
head
;
ln
;
ln
=
ln
->
next
)
{
if
((
newln
=
activeDefragAlloc
(
ln
)))
{
if
(
newln
->
prev
)
newln
->
prev
->
next
=
newln
;
else
l
->
head
=
newln
;
if
(
newln
->
next
)
newln
->
next
->
prev
=
newln
;
else
l
->
tail
=
newln
;
ln
=
newln
;
defragged
++
;
}
sdsele
=
ln
->
value
;
if
((
newsds
=
activeDefragSds
(
sdsele
)))
{
/* When defragging an sds value, we need to update the dict key */
uint64_t
hash
=
dictGetHash
(
d
,
newsds
);
dictEntry
**
deref
=
dictFindEntryRefByPtrAndHash
(
d
,
sdsele
,
hash
);
if
(
deref
)
dictSetKey
(
d
,
*
deref
,
newsds
);
ln
->
value
=
newsds
;
defragged
++
;
}
}
/* Defrag the dict values (keys were already handled) */
di
=
dictGetIterator
(
d
);
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
if
(
dict_val_type
==
DEFRAG_SDS_DICT_VAL_IS_SDS
)
{
sds
newsds
,
sdsele
=
dictGetVal
(
de
);
if
((
newsds
=
activeDefragSds
(
sdsele
)))
dictSetVal
(
d
,
de
,
newsds
),
defragged
++
;
}
else
if
(
dict_val_type
==
DEFRAG_SDS_DICT_VAL_IS_STROB
)
{
robj
*
newele
,
*
ele
=
dictGetVal
(
de
);
if
((
newele
=
activeDefragStringOb
(
ele
,
&
defragged
)))
dictSetVal
(
d
,
de
,
newele
);
}
else
if
(
dict_val_type
==
DEFRAG_SDS_DICT_VAL_VOID_PTR
)
{
void
*
newptr
,
*
ptr
=
dictGetVal
(
de
);
if
((
newptr
=
activeDefragAlloc
(
ptr
)))
dictSetVal
(
d
,
de
,
newptr
),
defragged
++
;
}
defragged
+=
dictIterDefragEntry
(
di
);
}
dictReleaseIterator
(
di
);
return
defragged
;
}
/* Utility function that replaces an old key pointer in the dictionary with a
/* Utility function that replaces an old key pointer in the dictionary with a
* new pointer. Additionally, we try to defrag the dictEntry in that dict.
* new pointer. Additionally, we try to defrag the dictEntry in that dict.
* Oldkey may be a dead pointer and should not be accessed (we get a
* Oldkey may be a dead pointer and should not be accessed (we get a
...
...
src/dict.c
View file @
d4e9e0ae
...
@@ -647,11 +647,6 @@ double dictIncrDoubleVal(dictEntry *de, double val) {
...
@@ -647,11 +647,6 @@ double dictIncrDoubleVal(dictEntry *de, double val) {
return
de
->
v
.
d
+=
val
;
return
de
->
v
.
d
+=
val
;
}
}
/* Only used when the next in hash bucket has been reallocated. */
void
dictSetNext
(
dictEntry
*
de
,
dictEntry
*
next
)
{
de
->
next
=
next
;
}
/* A pointer to the metadata section within the dict entry. */
/* A pointer to the metadata section within the dict entry. */
void
*
dictMetadata
(
dictEntry
*
de
)
{
void
*
dictMetadata
(
dictEntry
*
de
)
{
return
&
de
->
metadata
;
return
&
de
->
metadata
;
...
...
src/dict.h
View file @
d4e9e0ae
...
@@ -160,7 +160,6 @@ void dictSetDoubleVal(dictEntry *de, double val);
...
@@ -160,7 +160,6 @@ void dictSetDoubleVal(dictEntry *de, double val);
int64_t
dictIncrSignedIntegerVal
(
dictEntry
*
de
,
int64_t
val
);
int64_t
dictIncrSignedIntegerVal
(
dictEntry
*
de
,
int64_t
val
);
uint64_t
dictIncrUnsignedIntegerVal
(
dictEntry
*
de
,
uint64_t
val
);
uint64_t
dictIncrUnsignedIntegerVal
(
dictEntry
*
de
,
uint64_t
val
);
double
dictIncrDoubleVal
(
dictEntry
*
de
,
double
val
);
double
dictIncrDoubleVal
(
dictEntry
*
de
,
double
val
);
void
dictSetNext
(
dictEntry
*
de
,
dictEntry
*
next
);
void
*
dictMetadata
(
dictEntry
*
de
);
void
*
dictMetadata
(
dictEntry
*
de
);
void
*
dictGetKey
(
const
dictEntry
*
de
);
void
*
dictGetKey
(
const
dictEntry
*
de
);
void
*
dictGetVal
(
const
dictEntry
*
de
);
void
*
dictGetVal
(
const
dictEntry
*
de
);
...
...
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