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
b7d20a20
Commit
b7d20a20
authored
Feb 04, 2015
by
antirez
Browse files
Less blocking dictGetRandomKeys().
Related to issue #2306.
parent
3a0e69f3
Changes
1
Show whitespace changes
Inline
Side-by-side
src/dict.c
View file @
b7d20a20
...
...
@@ -663,18 +663,30 @@ dictEntry *dictGetRandomKey(dict *d)
* at producing N elements, and the elements are guaranteed to be non
* repeating. */
unsigned
int
dictGetRandomKeys
(
dict
*
d
,
dictEntry
**
des
,
unsigned
int
count
)
{
int
j
;
/* internal hash table id, 0 or 1. */
unsigned
int
stored
=
0
;
unsigned
int
j
;
/* internal hash table id, 0 or 1. */
unsigned
int
tables
;
/* 1 or 2 tables? */
unsigned
int
stored
=
0
,
maxsizemask
;
if
(
dictSize
(
d
)
<
count
)
count
=
dictSize
(
d
);
while
(
stored
<
count
)
{
for
(
j
=
0
;
j
<
2
;
j
++
)
{
/* Pick a random point inside the hash table 0 or 1. */
unsigned
int
i
=
random
()
&
d
->
ht
[
j
].
sizemask
;
int
size
=
d
->
ht
[
j
].
size
;
/* Make sure to visit every bucket by iterating 'size' times. */
while
(
size
--
)
{
/* Try to do a rehashing work proportional to 'count'. */
for
(
j
=
0
;
j
<
count
;
j
++
)
{
if
(
dictIsRehashing
(
d
))
_dictRehashStep
(
d
);
else
break
;
}
tables
=
dictIsRehashing
(
d
)
?
2
:
1
;
maxsizemask
=
d
->
ht
[
0
].
sizemask
;
if
(
tables
>
1
&&
maxsizemask
<
d
->
ht
[
1
].
sizemask
)
maxsizemask
=
d
->
ht
[
1
].
sizemask
;
/* Pick a random point inside the larger table. */
unsigned
int
i
=
random
()
&
maxsizemask
;
while
(
stored
<
count
)
{
for
(
j
=
0
;
j
<
tables
;
j
++
)
{
if
(
i
>=
d
->
ht
[
j
].
size
)
continue
;
/* Out of range for this table. */
dictEntry
*
he
=
d
->
ht
[
j
].
table
[
i
];
while
(
he
)
{
/* Collect all the elements of the buckets found non
...
...
@@ -685,12 +697,8 @@ unsigned int dictGetRandomKeys(dict *d, dictEntry **des, unsigned int count) {
stored
++
;
if
(
stored
==
count
)
return
stored
;
}
i
=
(
i
+
1
)
&
d
->
ht
[
j
].
sizemask
;
}
/* If there is only one table and we iterated it all, we should
* already have 'count' elements. Assert this condition. */
assert
(
dictIsRehashing
(
d
)
!=
0
);
}
i
=
(
i
+
1
)
&
maxsizemask
;
}
return
stored
;
/* Never reached. */
}
...
...
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