|
| 1 | +/* set object implementation |
| 2 | + Written and maintained by Raymond D. Hettinger <python@rcn.com> |
| 3 | + Derived from Lib/sets.py and Objects/dictobject.c. |
1 | 4 |
|
2 | | -/* Set object implementation using a hash table |
3 | | - Functions adapted from dictobject.c |
| 5 | + Copyright (c) 2003-5 Python Software Foundation. |
| 6 | + All rights reserved. |
4 | 7 | */ |
5 | 8 |
|
6 | 9 | #include "Python.h" |
| 10 | +#include "structmember.h" |
7 | 11 |
|
8 | 12 | /* This must be >= 1. */ |
9 | 13 | #define PERTURB_SHIFT 5 |
10 | 14 |
|
11 | 15 | /* Object used as dummy key to fill deleted entries */ |
12 | | -static PyObject *dummy; /* Initialized by first call to make_new_set() */ |
| 16 | +static PyObject *dummy = NULL; /* Initialized by first call to make_new_set() */ |
13 | 17 |
|
14 | 18 | #define EMPTY_TO_MINSIZE(so) do { \ |
15 | 19 | memset((so)->smalltable, 0, sizeof((so)->smalltable)); \ |
@@ -515,7 +519,7 @@ set_contains_internal(PySetObject *so, PyObject *key) |
515 | 519 | return key != NULL && key != dummy; |
516 | 520 | } |
517 | 521 |
|
518 | | -/***** Set iterator types **********************************************/ |
| 522 | +/***** Set iterator type ***********************************************/ |
519 | 523 |
|
520 | 524 | static PyTypeObject PySetIter_Type; /* Forward */ |
521 | 525 |
|
@@ -558,7 +562,6 @@ setiter_len(setiterobject *si) |
558 | 562 |
|
559 | 563 | static PySequenceMethods setiter_as_sequence = { |
560 | 564 | (inquiry)setiter_len, /* sq_length */ |
561 | | - 0, /* sq_concat */ |
562 | 565 | }; |
563 | 566 |
|
564 | 567 | static PyObject *setiter_iternext(setiterobject *si) |
@@ -632,19 +635,6 @@ static PyTypeObject PySetIter_Type = { |
632 | 635 | (iternextfunc)setiter_iternext, /* tp_iternext */ |
633 | 636 | }; |
634 | 637 |
|
635 | | -/***** Derived functions (table accesses only done with above primitives *****/ |
636 | | - |
637 | | -#include "structmember.h" |
638 | | - |
639 | | -/* set object implementation |
640 | | - written and maintained by Raymond D. Hettinger <python@rcn.com> |
641 | | - derived from sets.py written by Greg V. Wilson, Alex Martelli, |
642 | | - Guido van Rossum, Raymond Hettinger, and Tim Peters. |
643 | | -
|
644 | | - Copyright (c) 2003-5 Python Software Foundation. |
645 | | - All rights reserved. |
646 | | -*/ |
647 | | - |
648 | 638 | static int |
649 | 639 | set_len(PyObject *so) |
650 | 640 | { |
@@ -764,6 +754,7 @@ frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds) |
764 | 754 | void |
765 | 755 | PySet_Fini(void) |
766 | 756 | { |
| 757 | + Py_XDECREF(dummy); |
767 | 758 | Py_XDECREF(emptyfrozenset); |
768 | 759 | } |
769 | 760 |
|
@@ -1309,22 +1300,26 @@ set_nocmp(PyObject *self) |
1309 | 1300 | static long |
1310 | 1301 | frozenset_hash(PyObject *self) |
1311 | 1302 | { |
1312 | | - PyObject *key; |
1313 | 1303 | PySetObject *so = (PySetObject *)self; |
1314 | | - int pos = 0; |
1315 | 1304 | long hash = 1927868237L; |
| 1305 | + int i, j; |
1316 | 1306 |
|
1317 | 1307 | if (so->hash != -1) |
1318 | 1308 | return so->hash; |
1319 | 1309 |
|
1320 | 1310 | hash *= set_len(self) + 1; |
1321 | | - while (set_next_internal(so, &pos, &key)) { |
| 1311 | + for (i=0, j=so->used ; j ; j--, i++) { |
| 1312 | + setentry *entry; |
| 1313 | + long h; |
| 1314 | + |
| 1315 | + while ((entry = &so->table[i])->key == NULL || entry->key==dummy) |
| 1316 | + i++; |
1322 | 1317 | /* Work to increase the bit dispersion for closely spaced hash |
1323 | 1318 | values. The is important because some use cases have many |
1324 | 1319 | combinations of a small number of elements with nearby |
1325 | 1320 | hashes so that many distinct combinations collapse to only |
1326 | 1321 | a handful of distinct hash values. */ |
1327 | | - long h = PyObject_Hash(key); |
| 1322 | + h = entry->hash; |
1328 | 1323 | hash ^= (h ^ (h << 16) ^ 89869747L) * 3644798167u; |
1329 | 1324 | } |
1330 | 1325 | hash = hash * 69069L + 907133923L; |
|
0 commit comments