Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
9554fd5a
Commit
9554fd5a
authored
Sep 07, 2016
by
antirez
Browse files
dict.c improvements to rehashing and reallocation.
parent
96224f75
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/dict.c
View file @
9554fd5a
...
...
@@ -147,13 +147,26 @@ unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len) {
/* ----------------------------- API implementation ------------------------- */
dictEntry
*
dictPushEntry
(
dictEntryVector
**
table
,
unsigned
int
idx
,
const
void
*
key
,
const
void
*
val
,
unsigned
int
hash
)
/* Push a new entry in a vector of entries, taking care of allocating or
* reallocating the vector if needed. If 'orig_entries' is non zero it
* means that we are moving entries in the course of rehashing to a bigger
* table, from a vector that had 'orig_entires' entries. The function can
* use this hint to make better reallocation choices. */
dictEntry
*
dictPushEntry
(
dictEntryVector
**
table
,
unsigned
int
idx
,
const
void
*
key
,
const
void
*
val
,
unsigned
int
hash
,
uint32_t
orig_entries
)
{
dictEntryVector
*
dv
=
table
[
idx
];
dictEntry
*
he
;
if
(
dv
==
NULL
)
{
int
initlen
=
dict_resize_ratio
/
4
;
int
initlen
;
if
(
orig_entries
)
{
/* If we are rehashing to a larger table, in the average this
* slot will take orig_entries/2 slots, assuming the new table
* is double in size. */
initlen
=
orig_entries
/
2
;
}
else
{
initlen
=
dict_resize_ratio
/
4
;
}
if
(
initlen
==
0
)
initlen
=
1
;
dv
=
table
[
idx
]
=
zcalloc
(
sizeof
(
dictEntryVector
)
+
sizeof
(
dictEntry
)
*
initlen
);
...
...
@@ -161,7 +174,7 @@ dictEntry *dictPushEntry(dictEntryVector **table, unsigned int idx, const void *
dv
->
free
=
initlen
-
1
;
he
=
dv
->
entry
;
}
else
if
(
dv
->
free
==
0
)
{
int
newlen
=
(
dv
->
used
+
dv
->
free
)
*
2
;
int
newlen
=
dv
->
used
*
2
;
dv
=
table
[
idx
]
=
zrealloc
(
table
[
idx
],
sizeof
(
dictEntryVector
)
+
sizeof
(
dictEntry
)
*
newlen
);
he
=
dv
->
entry
+
dv
->
used
;
dv
->
used
++
;
...
...
@@ -279,6 +292,7 @@ int dictExpandToOptimalSize(dict *d, unsigned long entries) {
int
dictRehash
(
dict
*
d
,
int
n
)
{
int
empty_visits
=
n
*
10
;
/* Max number of empty buckets to visit. */
if
(
!
dictIsRehashing
(
d
))
return
0
;
int
to_smaller
=
d
->
ht
[
0
].
size
>
d
->
ht
[
1
].
size
;
/* Moving to smaller tab? */
while
(
n
--
&&
d
->
ht
[
0
].
used
!=
0
)
{
dictEntryVector
*
dv
;
...
...
@@ -297,6 +311,7 @@ int dictRehash(dict *d, int n) {
* to the next, since all the entries of this table will hash into
* the same slot of the target table. */
uint32_t
entries
=
dv
?
(
dv
->
used
+
dv
->
free
)
:
0
;
uint32_t
entries_hint
=
to_smaller
?
0
:
entries
;
uint32_t
j
;
for
(
j
=
0
;
j
<
entries
;
j
++
)
{
...
...
@@ -304,9 +319,9 @@ int dictRehash(dict *d, int n) {
/* Get the index in the new hash table */
if
(
dv
->
entry
[
j
].
key
==
NULL
)
continue
;
h
=
dictHashKey
(
d
,
dv
->
entry
[
j
].
key
)
&
d
->
ht
[
1
].
sizemask
;
h
=
dv
->
entry
[
j
].
hash
&
d
->
ht
[
1
].
sizemask
;
dictPushEntry
(
d
->
ht
[
1
].
table
,
h
,
dv
->
entry
[
j
].
key
,
dv
->
entry
[
j
].
v
.
val
,
dv
->
entry
[
j
].
hash
);
dv
->
entry
[
j
].
hash
,
entries_hint
);
d
->
ht
[
1
].
used
++
;
d
->
ht
[
0
].
used
--
;
}
...
...
@@ -401,7 +416,7 @@ dictEntry *dictAddRaw(dict *d, void *key)
/* Store the new entry: if we are rehashing all new entries go to
* the new table. */
ht
=
dictIsRehashing
(
d
)
?
&
d
->
ht
[
1
]
:
&
d
->
ht
[
0
];
entry
=
dictPushEntry
(
ht
->
table
,
index
,
key
,
NULL
,
hash
);
entry
=
dictPushEntry
(
ht
->
table
,
index
,
key
,
NULL
,
hash
,
0
);
ht
->
used
++
;
return
entry
;
}
...
...
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