diff options
author | Raymond Hettinger <python@rcn.com> | 2013-08-17 09:31:53 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2013-08-17 09:31:53 (GMT) |
commit | 237b34b0747ac97d8e63cc5b1379db753da57c18 (patch) | |
tree | ec7e668a1dbbb707920bf62788ebca21f805660d | |
parent | 07b16615bc0181cb6f1334ee170c196cdb3b288a (diff) | |
download | cpython-237b34b0747ac97d8e63cc5b1379db753da57c18.zip cpython-237b34b0747ac97d8e63cc5b1379db753da57c18.tar.gz cpython-237b34b0747ac97d8e63cc5b1379db753da57c18.tar.bz2 |
Use a known unique object for the dummy entry.
This lets us run PyObject_RichCompareBool() without
first needing to check whether the entry is a dummy.
-rw-r--r-- | Objects/setobject.c | 45 |
1 files changed, 20 insertions, 25 deletions
diff --git a/Objects/setobject.c b/Objects/setobject.c index ac501b6..da3b955 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -91,32 +91,27 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash) if (entry->key == NULL || entry->key == key) return entry; - if (entry->key == dummy) - freeslot = entry; - else { - if (entry->hash == hash) { - 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 { - /* The compare did major nasty stuff to the - * set: start over. - */ - return set_lookkey(so, key, hash); - } + if (entry->hash == hash) { + 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 = NULL; } - /* In the loop, key == dummy is by far (factor of 100s) the - least likely outcome, so test for that last. */ + 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. */ for (perturb = hash; ; perturb >>= PERTURB_SHIFT) { i = i * 5 + perturb + 1; entry = &table[i & mask]; @@ -127,7 +122,7 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash) } if (entry->key == key) break; - if (entry->hash == hash && entry->key != dummy) { + if (entry->hash == hash) { startkey = entry->key; Py_INCREF(startkey); cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); @@ -1029,7 +1024,7 @@ make_new_set(PyTypeObject *type, PyObject *iterable) PySetObject *so = NULL; if (dummy == NULL) { /* Auto-initialize dummy */ - dummy = PyUnicode_FromString("<dummy key>"); + dummy = _PyObject_New(&PyBaseObject_Type); if (dummy == NULL) return NULL; } |