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
976a7d23
Commit
976a7d23
authored
Sep 06, 2016
by
antirez
Browse files
dict.c key hash caching.
parent
8504bf18
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/dict.c
View file @
976a7d23
...
@@ -67,7 +67,7 @@ static unsigned int dict_force_resize_ratio = 60;
...
@@ -67,7 +67,7 @@ static unsigned int dict_force_resize_ratio = 60;
static
int
_dictExpandIfNeeded
(
dict
*
ht
);
static
int
_dictExpandIfNeeded
(
dict
*
ht
);
static
unsigned
long
_dictNextPower
(
unsigned
long
size
);
static
unsigned
long
_dictNextPower
(
unsigned
long
size
);
static
int
_dictKeyIndex
(
dict
*
ht
,
const
void
*
key
);
static
int
_dictKeyIndex
(
dict
*
ht
,
const
void
*
key
,
unsigned
int
*
hash
);
static
int
_dictInit
(
dict
*
ht
,
dictType
*
type
,
void
*
privDataPtr
);
static
int
_dictInit
(
dict
*
ht
,
dictType
*
type
,
void
*
privDataPtr
);
/* -------------------------- hash functions -------------------------------- */
/* -------------------------- hash functions -------------------------------- */
...
@@ -147,18 +147,18 @@ unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len) {
...
@@ -147,18 +147,18 @@ unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len) {
/* ----------------------------- API implementation ------------------------- */
/* ----------------------------- API implementation ------------------------- */
dictEntry
*
dictPushEntry
(
dictEntryVector
**
table
,
unsigned
int
h
,
const
void
*
key
,
const
void
*
val
)
dictEntry
*
dictPushEntry
(
dictEntryVector
**
table
,
unsigned
int
idx
,
const
void
*
key
,
const
void
*
val
,
unsigned
int
hash
)
{
{
dictEntryVector
*
dv
=
table
[
h
];
dictEntryVector
*
dv
=
table
[
idx
];
dictEntry
*
he
;
dictEntry
*
he
;
if
(
dv
==
NULL
)
{
if
(
dv
==
NULL
)
{
dv
=
table
[
h
]
=
zmalloc
(
sizeof
(
dictEntryVector
)
+
sizeof
(
dictEntry
));
dv
=
table
[
idx
]
=
zmalloc
(
sizeof
(
dictEntryVector
)
+
sizeof
(
dictEntry
));
dv
->
used
=
1
;
dv
->
used
=
1
;
dv
->
free
=
0
;
dv
->
free
=
0
;
he
=
dv
->
entry
;
he
=
dv
->
entry
;
}
else
if
(
dv
->
free
==
0
)
{
}
else
if
(
dv
->
free
==
0
)
{
dv
=
table
[
h
]
=
zrealloc
(
table
[
h
],
sizeof
(
dictEntryVector
)
+
sizeof
(
dictEntry
)
*
(
dv
->
used
+
1
));
dv
=
table
[
idx
]
=
zrealloc
(
table
[
idx
],
sizeof
(
dictEntryVector
)
+
sizeof
(
dictEntry
)
*
(
dv
->
used
+
1
));
he
=
dv
->
entry
+
dv
->
used
;
he
=
dv
->
entry
+
dv
->
used
;
dv
->
used
++
;
dv
->
used
++
;
}
else
{
}
else
{
...
@@ -173,6 +173,7 @@ dictEntry *dictPushEntry(dictEntryVector **table, unsigned int h, const void *ke
...
@@ -173,6 +173,7 @@ dictEntry *dictPushEntry(dictEntryVector **table, unsigned int h, const void *ke
}
}
he
->
key
=
(
void
*
)
key
;
he
->
key
=
(
void
*
)
key
;
he
->
v
.
val
=
(
void
*
)
val
;
he
->
v
.
val
=
(
void
*
)
val
;
he
->
hash
=
hash
;
return
he
;
return
he
;
}
}
...
@@ -298,7 +299,8 @@ int dictRehash(dict *d, int n) {
...
@@ -298,7 +299,8 @@ int dictRehash(dict *d, int n) {
/* Get the index in the new hash table */
/* Get the index in the new hash table */
if
(
dv
->
entry
[
j
].
key
==
NULL
)
continue
;
if
(
dv
->
entry
[
j
].
key
==
NULL
)
continue
;
h
=
dictHashKey
(
d
,
dv
->
entry
[
j
].
key
)
&
d
->
ht
[
1
].
sizemask
;
h
=
dictHashKey
(
d
,
dv
->
entry
[
j
].
key
)
&
d
->
ht
[
1
].
sizemask
;
dictPushEntry
(
d
->
ht
[
1
].
table
,
h
,
dv
->
entry
[
j
].
key
,
dv
->
entry
[
j
].
v
.
val
);
dictPushEntry
(
d
->
ht
[
1
].
table
,
h
,
dv
->
entry
[
j
].
key
,
dv
->
entry
[
j
].
v
.
val
,
dv
->
entry
[
j
].
hash
);
d
->
ht
[
1
].
used
++
;
d
->
ht
[
1
].
used
++
;
d
->
ht
[
0
].
used
--
;
d
->
ht
[
0
].
used
--
;
}
}
...
@@ -379,6 +381,7 @@ int dictAdd(dict *d, void *key, void *val)
...
@@ -379,6 +381,7 @@ int dictAdd(dict *d, void *key, void *val)
dictEntry
*
dictAddRaw
(
dict
*
d
,
void
*
key
)
dictEntry
*
dictAddRaw
(
dict
*
d
,
void
*
key
)
{
{
int
index
;
int
index
;
unsigned
int
hash
;
dictEntry
*
entry
;
dictEntry
*
entry
;
dictht
*
ht
;
dictht
*
ht
;
...
@@ -386,13 +389,13 @@ dictEntry *dictAddRaw(dict *d, void *key)
...
@@ -386,13 +389,13 @@ dictEntry *dictAddRaw(dict *d, void *key)
/* Get the index of the new element, or -1 if
/* Get the index of the new element, or -1 if
* the element already exists. */
* the element already exists. */
if
((
index
=
_dictKeyIndex
(
d
,
key
))
==
-
1
)
if
((
index
=
_dictKeyIndex
(
d
,
key
,
&
hash
))
==
-
1
)
return
NULL
;
return
NULL
;
/* Store the new entry: if we are rehashing all new entries go to
/* Store the new entry: if we are rehashing all new entries go to
* the new table. */
* the new table. */
ht
=
dictIsRehashing
(
d
)
?
&
d
->
ht
[
1
]
:
&
d
->
ht
[
0
];
ht
=
dictIsRehashing
(
d
)
?
&
d
->
ht
[
1
]
:
&
d
->
ht
[
0
];
entry
=
dictPushEntry
(
ht
->
table
,
index
,
key
,
NULL
);
entry
=
dictPushEntry
(
ht
->
table
,
index
,
key
,
NULL
,
hash
);
ht
->
used
++
;
ht
->
used
++
;
return
entry
;
return
entry
;
}
}
...
@@ -452,14 +455,15 @@ static int dictGenericDelete(dict *d, const void *key, int nofree) {
...
@@ -452,14 +455,15 @@ static int dictGenericDelete(dict *d, const void *key, int nofree) {
uint32_t
j
;
uint32_t
j
;
for
(
j
=
0
;
j
<
entries
;
j
++
)
{
for
(
j
=
0
;
j
<
entries
;
j
++
)
{
dictEntry
*
he
=
dv
->
entry
+
j
;
dictEntry
*
he
=
dv
->
entry
+
j
;
if
(
he
->
key
==
NULL
)
continue
;
if
(
he
->
key
==
NULL
||
he
->
hash
!=
h
)
continue
;
if
(
key
==
he
->
key
||
dictCompareKeys
(
d
,
key
,
he
->
key
))
{
if
(
key
==
he
->
key
||
dictCompareKeys
(
d
,
key
,
he
->
key
))
{
if
(
!
nofree
)
{
if
(
!
nofree
)
{
dictFreeKey
(
d
,
he
);
dictFreeKey
(
d
,
he
);
dictFreeVal
(
d
,
he
);
dictFreeVal
(
d
,
he
);
}
}
he
->
key
=
NULL
;
he
->
key
=
NULL
;
he
->
v
.
val
=
NULL
;
/* No need to clear val / hash fields. The key set
* to NULL is enough to mark the slot as empty. */
d
->
ht
[
table
].
used
--
;
d
->
ht
[
table
].
used
--
;
dv
->
free
++
;
dv
->
free
++
;
dv
->
used
--
;
dv
->
used
--
;
...
@@ -544,7 +548,7 @@ dictEntry *dictFind(dict *d, const void *key)
...
@@ -544,7 +548,7 @@ dictEntry *dictFind(dict *d, const void *key)
uint32_t
j
;
uint32_t
j
;
for
(
j
=
0
;
j
<
entries
;
j
++
)
{
for
(
j
=
0
;
j
<
entries
;
j
++
)
{
dictEntry
*
he
=
dv
->
entry
+
j
;
dictEntry
*
he
=
dv
->
entry
+
j
;
if
(
he
->
key
==
NULL
)
continue
;
/* Empty slot. */
if
(
he
->
key
==
NULL
||
he
->
hash
!=
h
)
continue
;
if
(
key
==
he
->
key
||
dictCompareKeys
(
d
,
key
,
he
->
key
))
if
(
key
==
he
->
key
||
dictCompareKeys
(
d
,
key
,
he
->
key
))
return
he
;
return
he
;
}
}
...
@@ -1006,7 +1010,7 @@ static unsigned long _dictNextPower(unsigned long size)
...
@@ -1006,7 +1010,7 @@ static unsigned long _dictNextPower(unsigned long size)
*
*
* Note that if we are in the process of rehashing the hash table, the
* Note that if we are in the process of rehashing the hash table, the
* index is always returned in the context of the second (new) hash table. */
* index is always returned in the context of the second (new) hash table. */
static
int
_dictKeyIndex
(
dict
*
d
,
const
void
*
key
)
static
int
_dictKeyIndex
(
dict
*
d
,
const
void
*
key
,
unsigned
int
*
hash
)
{
{
unsigned
int
h
,
idx
,
table
;
unsigned
int
h
,
idx
,
table
;
dictEntryVector
*
dv
;
dictEntryVector
*
dv
;
...
@@ -1016,6 +1020,7 @@ static int _dictKeyIndex(dict *d, const void *key)
...
@@ -1016,6 +1020,7 @@ static int _dictKeyIndex(dict *d, const void *key)
return
-
1
;
return
-
1
;
/* Compute the key hash value */
/* Compute the key hash value */
h
=
dictHashKey
(
d
,
key
);
h
=
dictHashKey
(
d
,
key
);
*
hash
=
h
;
for
(
table
=
0
;
table
<=
1
;
table
++
)
{
for
(
table
=
0
;
table
<=
1
;
table
++
)
{
idx
=
h
&
d
->
ht
[
table
].
sizemask
;
idx
=
h
&
d
->
ht
[
table
].
sizemask
;
/* Search if this slot does not already contain the given key */
/* Search if this slot does not already contain the given key */
...
@@ -1025,7 +1030,7 @@ static int _dictKeyIndex(dict *d, const void *key)
...
@@ -1025,7 +1030,7 @@ static int _dictKeyIndex(dict *d, const void *key)
uint32_t
j
;
uint32_t
j
;
for
(
j
=
0
;
j
<
entries
;
j
++
)
{
for
(
j
=
0
;
j
<
entries
;
j
++
)
{
dictEntry
*
he
=
dv
->
entry
+
j
;
dictEntry
*
he
=
dv
->
entry
+
j
;
if
(
he
->
key
==
NULL
)
continue
;
if
(
he
->
key
==
NULL
||
he
->
hash
!=
h
)
continue
;
if
(
key
==
he
->
key
||
dictCompareKeys
(
d
,
key
,
he
->
key
))
if
(
key
==
he
->
key
||
dictCompareKeys
(
d
,
key
,
he
->
key
))
return
-
1
;
return
-
1
;
}
}
...
...
src/dict.h
View file @
976a7d23
...
@@ -52,6 +52,7 @@ typedef struct dictEntry {
...
@@ -52,6 +52,7 @@ typedef struct dictEntry {
int64_t
s64
;
int64_t
s64
;
double
d
;
double
d
;
}
v
;
}
v
;
unsigned
int
hash
;
}
dictEntry
;
}
dictEntry
;
typedef
struct
dictEntryVector
{
typedef
struct
dictEntryVector
{
...
...
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