diff -r ac0d6c09457e Objects/setobject.c --- a/Objects/setobject.c Sun Jan 18 21:25:15 2015 -0800 +++ b/Objects/setobject.c Tue Jan 20 12:30:18 2015 +0200 @@ -61,14 +61,15 @@ set_lookkey(PySetObject *so, PyObject *k int cmp; entry = &table[i & mask]; + if (entry->key == key) + return entry; if (entry->key == NULL) return entry; while (1) { - if (entry->hash == hash && entry->key != dummy) { /* dummy match unlikely */ + if (entry->hash == hash) { PyObject *startkey = entry->key; - if (startkey == key) - return entry; + assert(startkey != dummy); Py_INCREF(startkey); cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); Py_DECREF(startkey); @@ -79,17 +80,18 @@ set_lookkey(PySetObject *so, PyObject *k if (cmp > 0) /* likely */ return entry; } - if (entry->key == dummy && freeslot == NULL) + else if (entry->key == dummy && freeslot == NULL) freeslot = entry; for (j = 1 ; j <= LINEAR_PROBES ; j++) { entry = &table[(i + j) & mask]; + if (entry->key == key) + return entry; if (entry->key == NULL) goto found_null; - if (entry->hash == hash && entry->key != dummy) { + if (entry->hash == hash) { PyObject *startkey = entry->key; - if (startkey == key) - return entry; + assert(startkey != dummy); Py_INCREF(startkey); cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); Py_DECREF(startkey); @@ -100,7 +102,7 @@ set_lookkey(PySetObject *so, PyObject *k if (cmp > 0) return entry; } - if (entry->key == dummy && freeslot == NULL) + else if (entry->key == dummy && freeslot == NULL) freeslot = entry; } @@ -108,6 +110,8 @@ set_lookkey(PySetObject *so, PyObject *k i = i * 5 + 1 + perturb; entry = &table[i & mask]; + if (entry->key == key) + return entry; if (entry->key == NULL) goto found_null; } @@ -131,6 +135,9 @@ set_lookkey_unicode(PySetObject *so, PyO size_t i = (size_t)hash; size_t j; + entry = &table[i & mask]; + if (entry->key == key) + return entry; /* Make sure this function doesn't have to handle non-unicode keys, including subclasses of str; e.g., one reason to subclass strings is to override __eq__, and for speed we don't cater to @@ -139,30 +146,28 @@ set_lookkey_unicode(PySetObject *so, PyO so->lookup = set_lookkey; return set_lookkey(so, key, hash); } - - entry = &table[i & mask]; if (entry->key == NULL) return entry; while (1) { - if (entry->hash == hash - && (entry->key == key - || (entry->key != dummy /* unlikely */ - && unicode_eq(entry->key, key)))) /* likely */ + if (entry->hash == hash && unicode_eq(entry->key, key)) { + assert(entry->key != dummy); return entry; - if (entry->key == dummy && freeslot == NULL) + } + else if (entry->key == dummy && freeslot == NULL) freeslot = entry; for (j = 1 ; j <= LINEAR_PROBES ; j++) { entry = &table[(i + j) & mask]; + if (entry->key == key) + return entry; if (entry->key == NULL) goto found_null; - if (entry->hash == hash - && (entry->key == key - || (entry->key != dummy /* unlikely */ - && unicode_eq(entry->key, key)))) /* likely */ + if (entry->hash == hash && unicode_eq(entry->key, key)) { + assert(entry->key != dummy); return entry; - if (entry->key == dummy && freeslot == NULL) + } + else if (entry->key == dummy && freeslot == NULL) freeslot = entry; } @@ -170,6 +175,8 @@ set_lookkey_unicode(PySetObject *so, PyO i = i * 5 + 1 + perturb; entry = &table[i & mask]; + if (entry->key == key) + return entry; if (entry->key == NULL) goto found_null; } @@ -392,6 +399,7 @@ set_discard_entry(PySetObject *so, seten return DISCARD_NOTFOUND; old_key = entry->key; entry->key = dummy; + entry->hash = -1; so->used--; Py_DECREF(old_key); return DISCARD_FOUND; @@ -676,6 +684,7 @@ set_pop(PySetObject *so) } key = entry->key; entry->key = dummy; + entry->hash = -1; so->used--; so->finger = i + 1; /* next place to start */ return key;