mirror of
https://github.com/python/cpython.git
synced 2024-11-24 18:34:43 +08:00
Tighten-up the lookkey() logic and beautify the code a bit.
Use less code by moving many of the steps from the initial lookup into the main search loop. Beautify the code but keep the overall logic unchanged.
This commit is contained in:
parent
7c1017bfee
commit
afe890923f
@ -79,65 +79,53 @@ NULL if the rich comparison returns an error.
|
|||||||
static setentry *
|
static setentry *
|
||||||
set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
|
set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
|
||||||
{
|
{
|
||||||
size_t i, j; /* Unsigned for defined overflow behavior. */
|
|
||||||
size_t perturb;
|
|
||||||
setentry *freeslot;
|
|
||||||
size_t mask = so->mask;
|
|
||||||
setentry *table = so->table;
|
setentry *table = so->table;
|
||||||
|
setentry *freeslot = NULL;
|
||||||
setentry *entry;
|
setentry *entry;
|
||||||
|
size_t perturb = hash;
|
||||||
|
size_t mask = so->mask;
|
||||||
|
size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior. */
|
||||||
|
size_t j = i;
|
||||||
int cmp;
|
int cmp;
|
||||||
PyObject *startkey;
|
|
||||||
|
|
||||||
i = (size_t)hash & mask;
|
|
||||||
entry = &table[i];
|
entry = &table[i];
|
||||||
if (entry->key == NULL || entry->key == key)
|
if (entry->key == NULL)
|
||||||
return entry;
|
return entry;
|
||||||
if (entry->hash == hash && entry->key != dummy) {
|
|
||||||
startkey = entry->key;
|
|
||||||
Py_INCREF(startkey);
|
|
||||||
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
|
|
||||||
Py_DECREF(startkey);
|
|
||||||
if (cmp < 0)
|
|
||||||
return NULL;
|
|
||||||
if (table == so->table && entry->key == startkey) {
|
|
||||||
if (cmp > 0)
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Start over if the compare altered the set */
|
|
||||||
return set_lookkey(so, key, hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
freeslot = (entry->key == dummy) ? entry : NULL;
|
|
||||||
|
|
||||||
/* In the loop, key == dummy is by far (factor of 100s)
|
|
||||||
the least likely outcome, so test for that last. */
|
|
||||||
j = i;
|
|
||||||
perturb = hash;
|
|
||||||
while (1) {
|
while (1) {
|
||||||
j ^= 1;
|
|
||||||
entry = &table[j];
|
|
||||||
if (entry->key == NULL) {
|
|
||||||
if (freeslot != NULL)
|
|
||||||
entry = freeslot;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (entry->key == key)
|
if (entry->key == key)
|
||||||
break;
|
return entry;
|
||||||
if (entry->hash == hash && entry->key != dummy) {
|
if (entry->hash == hash && entry->key != dummy) {
|
||||||
startkey = entry->key;
|
PyObject *startkey = entry->key;
|
||||||
Py_INCREF(startkey);
|
Py_INCREF(startkey);
|
||||||
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
|
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
|
||||||
Py_DECREF(startkey);
|
Py_DECREF(startkey);
|
||||||
if (cmp < 0)
|
if (cmp < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (table == so->table && entry->key == startkey) {
|
if (table != so->table || entry->key != startkey)
|
||||||
if (cmp > 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return set_lookkey(so, key, hash);
|
return set_lookkey(so, key, hash);
|
||||||
|
if (cmp > 0)
|
||||||
|
return entry;
|
||||||
}
|
}
|
||||||
|
if (entry->key == dummy && freeslot == NULL)
|
||||||
|
freeslot = entry;
|
||||||
|
|
||||||
|
entry = &table[j ^ 1];
|
||||||
|
if (entry->key == NULL)
|
||||||
|
break;
|
||||||
|
if (entry->key == key)
|
||||||
|
return entry;
|
||||||
|
if (entry->hash == hash && entry->key != dummy) {
|
||||||
|
PyObject *startkey = entry->key;
|
||||||
|
Py_INCREF(startkey);
|
||||||
|
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
|
||||||
|
Py_DECREF(startkey);
|
||||||
|
if (cmp < 0)
|
||||||
|
return NULL;
|
||||||
|
if (table != so->table || entry->key != startkey)
|
||||||
|
return set_lookkey(so, key, hash);
|
||||||
|
if (cmp > 0)
|
||||||
|
return entry;
|
||||||
}
|
}
|
||||||
if (entry->key == dummy && freeslot == NULL)
|
if (entry->key == dummy && freeslot == NULL)
|
||||||
freeslot = entry;
|
freeslot = entry;
|
||||||
@ -147,33 +135,10 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
|
|||||||
perturb >>= PERTURB_SHIFT;
|
perturb >>= PERTURB_SHIFT;
|
||||||
|
|
||||||
entry = &table[j];
|
entry = &table[j];
|
||||||
if (entry->key == NULL) {
|
if (entry->key == NULL)
|
||||||
if (freeslot != NULL)
|
|
||||||
entry = freeslot;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (entry->key == key)
|
return freeslot == NULL ? entry : freeslot;
|
||||||
break;
|
|
||||||
if (entry->hash == hash && entry->key != dummy) {
|
|
||||||
startkey = entry->key;
|
|
||||||
Py_INCREF(startkey);
|
|
||||||
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
|
|
||||||
Py_DECREF(startkey);
|
|
||||||
if (cmp < 0)
|
|
||||||
return NULL;
|
|
||||||
if (table == so->table && entry->key == startkey) {
|
|
||||||
if (cmp > 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return set_lookkey(so, key, hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (entry->key == dummy && freeslot == NULL)
|
|
||||||
freeslot = entry;
|
|
||||||
|
|
||||||
}
|
|
||||||
return entry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -184,12 +149,13 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
|
|||||||
static setentry *
|
static setentry *
|
||||||
set_lookkey_unicode(PySetObject *so, PyObject *key, Py_hash_t hash)
|
set_lookkey_unicode(PySetObject *so, PyObject *key, Py_hash_t hash)
|
||||||
{
|
{
|
||||||
size_t i, j; /* Unsigned for defined overflow behavior. */
|
|
||||||
size_t perturb;
|
|
||||||
setentry *freeslot;
|
|
||||||
size_t mask = so->mask;
|
|
||||||
setentry *table = so->table;
|
setentry *table = so->table;
|
||||||
|
setentry *freeslot = NULL;
|
||||||
setentry *entry;
|
setentry *entry;
|
||||||
|
size_t perturb = hash;
|
||||||
|
size_t mask = so->mask;
|
||||||
|
size_t i = (size_t)hash & mask;
|
||||||
|
size_t j = i;
|
||||||
|
|
||||||
/* Make sure this function doesn't have to handle non-unicode keys,
|
/* Make sure this function doesn't have to handle non-unicode keys,
|
||||||
including subclasses of str; e.g., one reason to subclass
|
including subclasses of str; e.g., one reason to subclass
|
||||||
@ -200,25 +166,22 @@ set_lookkey_unicode(PySetObject *so, PyObject *key, Py_hash_t hash)
|
|||||||
return set_lookkey(so, key, hash);
|
return set_lookkey(so, key, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = (size_t)hash & mask;
|
|
||||||
entry = &table[i];
|
entry = &table[i];
|
||||||
if (entry->key == NULL || entry->key == key)
|
|
||||||
return entry;
|
|
||||||
if (entry->key == dummy)
|
|
||||||
freeslot = entry;
|
|
||||||
else {
|
|
||||||
if (entry->hash == hash && unicode_eq(entry->key, key))
|
|
||||||
return entry;
|
|
||||||
freeslot = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
j = i;
|
|
||||||
perturb = hash;
|
|
||||||
while (1) {
|
|
||||||
j ^= 1;
|
|
||||||
entry = &table[j];
|
|
||||||
if (entry->key == NULL)
|
if (entry->key == NULL)
|
||||||
return freeslot == NULL ? entry : freeslot;
|
return entry;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (entry->key == key
|
||||||
|
|| (entry->hash == hash
|
||||||
|
&& entry->key != dummy
|
||||||
|
&& unicode_eq(entry->key, key)))
|
||||||
|
return entry;
|
||||||
|
if (entry->key == dummy && freeslot == NULL)
|
||||||
|
freeslot = entry;
|
||||||
|
|
||||||
|
entry = &table[j ^ 1];
|
||||||
|
if (entry->key == NULL)
|
||||||
|
break;
|
||||||
if (entry->key == key
|
if (entry->key == key
|
||||||
|| (entry->hash == hash
|
|| (entry->hash == hash
|
||||||
&& entry->key != dummy
|
&& entry->key != dummy
|
||||||
@ -233,17 +196,9 @@ set_lookkey_unicode(PySetObject *so, PyObject *key, Py_hash_t hash)
|
|||||||
|
|
||||||
entry = &table[j];
|
entry = &table[j];
|
||||||
if (entry->key == NULL)
|
if (entry->key == NULL)
|
||||||
return freeslot == NULL ? entry : freeslot;
|
break;
|
||||||
if (entry->key == key
|
|
||||||
|| (entry->hash == hash
|
|
||||||
&& entry->key != dummy
|
|
||||||
&& unicode_eq(entry->key, key)))
|
|
||||||
return entry;
|
|
||||||
if (entry->key == dummy && freeslot == NULL)
|
|
||||||
freeslot = entry;
|
|
||||||
}
|
}
|
||||||
assert(0); /* NOT REACHED */
|
return freeslot == NULL ? entry : freeslot;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user