Kaydet (Commit) 67962ab1 authored tarafından Raymond Hettinger's avatar Raymond Hettinger

Model set.pop() after dict.popitem().

üst 6a694508
...@@ -13,6 +13,10 @@ There are three kinds of slots in the table: ...@@ -13,6 +13,10 @@ There are three kinds of slots in the table:
1. Unused: key == NULL 1. Unused: key == NULL
2. Active: key != NULL and key != dummy 2. Active: key != NULL and key != dummy
3. Dummy: 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.
*/ */
#define PySet_MINSIZE 8 #define PySet_MINSIZE 8
......
...@@ -1508,24 +1508,42 @@ static PyObject * ...@@ -1508,24 +1508,42 @@ static PyObject *
set_pop(PySetObject *so) set_pop(PySetObject *so)
{ {
PyObject *key; PyObject *key;
int pos = 0; register setentry *entry;
int rv; register int i = 0;
if (!set_next_internal(so, &pos, &key)) { assert (PyAnySet_Check(so));
if (so->used == 0) {
PyErr_SetString(PyExc_KeyError, "pop from an empty set"); PyErr_SetString(PyExc_KeyError, "pop from an empty set");
return NULL; return NULL;
} }
Py_INCREF(key);
rv = set_discard_internal(so, key); /* Set entry to "the first" unused or dummy set entry. We abuse
if (rv == -1) { * the hash field of slot 0 to hold a search finger:
Py_DECREF(key); * If slot 0 has a value, use slot 0.
return NULL; * Else slot 0 is being used to hold a search finger,
} else if (rv == DISCARD_NOTFOUND) { * and we use its hash value as the first index to look.
Py_DECREF(key); */
PyErr_SetObject(PyExc_KeyError, key); entry = &so->table[0];
return NULL; if (entry->key == NULL || entry->key == dummy) {
i = (int)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 */
while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
i++;
if (i > so->mask)
i = 1;
}
} }
key = entry->key;
Py_INCREF(dummy);
entry->key = dummy;
so->used--;
so->table[0].hash = i + 1; /* next place to start */
return key; return key;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment