mirror of https://github.com/python/cpython
Issue 23261: Clean-up the hack to store the set.pop() search finger in a hash field instead of the setobject.
This commit is contained in:
parent
a556af77a7
commit
1202a4733e
|
@ -14,9 +14,7 @@ extern "C" {
|
|||
2. Active: key != NULL and key != dummy
|
||||
3. Dummy: key == dummy
|
||||
|
||||
Note: .pop() abuses the hash field of an Unused or Dummy slot to
|
||||
hold a search finger. The hash field of Unused or Dummy slots has
|
||||
no meaning otherwise.
|
||||
The hash field of Unused or Dummy slots have no meaning.
|
||||
*/
|
||||
|
||||
#define PySet_MINSIZE 8
|
||||
|
@ -59,6 +57,7 @@ typedef struct _setobject {
|
|||
Py_hash_t hash; /* Only used by frozenset objects */
|
||||
setentry smalltable[PySet_MINSIZE];
|
||||
|
||||
Py_ssize_t finger; /* Search finger for pop() */
|
||||
PyObject *weakreflist; /* List of weak references */
|
||||
} PySetObject;
|
||||
|
||||
|
|
|
@ -994,7 +994,7 @@ class SizeofTest(unittest.TestCase):
|
|||
# frozenset
|
||||
PySet_MINSIZE = 8
|
||||
samples = [[], range(10), range(50)]
|
||||
s = size('3n2P' + PySet_MINSIZE*'nP' + 'nP')
|
||||
s = size('3n2P' + PySet_MINSIZE*'nP' + '2nP')
|
||||
for sample in samples:
|
||||
minused = len(sample)
|
||||
if minused == 0: tmp = 1
|
||||
|
|
|
@ -668,32 +668,22 @@ set_pop(PySetObject *so)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Set entry to "the first" unused or dummy set entry. We abuse
|
||||
* the hash field of slot 0 to hold a search finger:
|
||||
* If slot 0 has a value, use slot 0.
|
||||
* Else slot 0 is being used to hold a search finger,
|
||||
* and we use its hash value as the first index to look.
|
||||
i = so->finger;
|
||||
/* This may be a legit search finger, or it may be a once legit
|
||||
* search finger that's out of bounds now (due to wrapping or
|
||||
* resizing). We simply make sure it's in bounds now.
|
||||
*/
|
||||
entry = &so->table[0];
|
||||
if (entry->key == NULL || entry->key == dummy) {
|
||||
i = entry->hash;
|
||||
/* The hash field may be a real hash value, or it may be a
|
||||
* legit search finger, or it may be a once-legit search
|
||||
* finger that's out of bounds now because it wrapped around
|
||||
* or the table shrunk -- simply make sure it's in bounds now.
|
||||
*/
|
||||
if (i > so->mask || i < 1)
|
||||
i = 1; /* skip slot 0 */
|
||||
if (i > so->mask)
|
||||
i = 0;
|
||||
while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
|
||||
i++;
|
||||
if (i > so->mask)
|
||||
i = 1;
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
key = entry->key;
|
||||
entry->key = dummy;
|
||||
so->used--;
|
||||
so->table[0].hash = i + 1; /* next place to start */
|
||||
so->finger = i + 1; /* next place to start */
|
||||
return key;
|
||||
}
|
||||
|
||||
|
@ -1012,6 +1002,7 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
|
|||
so->table = so->smalltable;
|
||||
so->lookup = set_lookkey_unicode;
|
||||
so->hash = -1;
|
||||
so->finger = 0;
|
||||
so->weakreflist = NULL;
|
||||
|
||||
if (iterable != NULL) {
|
||||
|
|
Loading…
Reference in New Issue