Remove unneeded dummy test from the set search loop (when the hashes match we know the key is not a dummy).

This commit is contained in:
Raymond Hettinger 2015-01-26 21:54:35 -08:00
parent 3037e84ad1
commit a5ebbf6295
2 changed files with 15 additions and 5 deletions

View File

@ -14,7 +14,10 @@ extern "C" {
2. Active: key != NULL and key != dummy
3. Dummy: key == dummy
The hash field of Unused or Dummy slots have no meaning.
The hash field of Unused slots have no meaning.
The hash field of Dummny slots are set to -1
meaning that dummy entries can be detected by
either entry->key==dummy or by entry->hash==-1.
*/
#define PySet_MINSIZE 8

View File

@ -65,8 +65,10 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
return entry;
while (1) {
if (entry->hash == hash && entry->key != dummy) { /* dummy match unlikely */
if (entry->hash == hash) {
PyObject *startkey = entry->key;
/* startkey cannot be a dummy because the dummy hash field is -1 */
assert(startkey != dummy);
if (startkey == key)
return entry;
if (PyUnicode_CheckExact(startkey)
@ -83,15 +85,18 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
if (cmp > 0) /* likely */
return entry;
}
if (entry->key == dummy && freeslot == NULL)
if (entry->hash == -1 && freeslot == NULL) {
assert(entry->key == dummy);
freeslot = entry;
}
for (j = 1 ; j <= LINEAR_PROBES ; j++) {
entry = &table[(i + j) & mask];
if (entry->key == NULL)
goto found_null;
if (entry->hash == hash && entry->key != dummy) {
if (entry->hash == hash) {
PyObject *startkey = entry->key;
assert(startkey != dummy);
if (startkey == key)
return entry;
if (PyUnicode_CheckExact(startkey)
@ -108,9 +113,11 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
if (cmp > 0)
return entry;
}
if (entry->key == dummy && freeslot == NULL)
if (entry->hash == -1 && freeslot == NULL) {
assert(entry->key == dummy);
freeslot = entry;
}
}
perturb >>= PERTURB_SHIFT;
i = i * 5 + 1 + perturb;