FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Model set.pop() after dict.popitem(). · python/cpython@67962ab · GitHub

Repository navigation

Commit 67962ab

Browse files
committed
Model set.pop() after dict.popitem().
1 parent 6a69450 commit 67962ab

2 files changed

Lines changed: 34 additions & 12 deletions

File tree

‎Include/setobject.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ There are three kinds of slots in the table:
1313
1. Unused: key == NULL
1414
2. Active: key != NULL and key != dummy
1515
3. Dummy: key == dummy
16+
17+
Note: .pop() abuses the hash field of an Unused or Dummy slot to
18+
hold a search finger. The hash field of Unused or Dummy slots has
19+
no meaning otherwise.
1620
*/
1721

1822
#define PySet_MINSIZE 8

‎Objects/setobject.c‎

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,24 +1508,42 @@ static PyObject *
15081508
set_pop(PySetObject *so)
15091509
{
15101510
PyObject *key;
1511-
int pos = 0;
1512-
int rv;
1511+
register setentry *entry;
1512+
register int i = 0;
15131513

1514-
if (!set_next_internal(so, &pos, &key)) {
1514+
assert (PyAnySet_Check(so));
1515+
if (so->used == 0) {
15151516
PyErr_SetString(PyExc_KeyError, "pop from an empty set");
15161517
return NULL;
15171518
}
1518-
Py_INCREF(key);
15191519

1520-
rv = set_discard_internal(so, key);
1521-
if (rv == -1) {
1522-
Py_DECREF(key);
1523-
return NULL;
1524-
} else if (rv == DISCARD_NOTFOUND) {
1525-
Py_DECREF(key);
1526-
PyErr_SetObject(PyExc_KeyError, key);
1527-
return NULL;
1520+
/* Set entry to "the first" unused or dummy set entry. We abuse
1521+
* the hash field of slot 0 to hold a search finger:
1522+
* If slot 0 has a value, use slot 0.
1523+
* Else slot 0 is being used to hold a search finger,
1524+
* and we use its hash value as the first index to look.
1525+
*/
1526+
entry = &so->table[0];
1527+
if (entry->key == NULL || entry->key == dummy) {
1528+
i = (int)entry->hash;
1529+
/* The hash field may be a real hash value, or it may be a
1530+
* legit search finger, or it may be a once-legit search
1531+
* finger that's out of bounds now because it wrapped around
1532+
* or the table shrunk -- simply make sure it's in bounds now.
1533+
*/
1534+
if (i > so->mask || i < 1)
1535+
i = 1; /* skip slot 0 */
1536+
while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
1537+
i++;
1538+
if (i > so->mask)
1539+
i = 1;
1540+
}
15281541
}
1542+
key = entry->key;
1543+
Py_INCREF(dummy);
1544+
entry->key = dummy;
1545+
so->used--;
1546+
so->table[0].hash = i + 1; /* next place to start */
15291547
return key;
15301548
}
15311549

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL