Skip to content

Commit a9d9936

Browse files
committed
* Move copyright notice to top and indicate derivation from sets.py and
dictobject.c. * Have frozenset_hash() use entry->hash instead of re-computing each individual hash with PyObject_Hash(o); * Finalize the dummy entry before a system exit.
1 parent ea9dcdc commit a9d9936

1 file changed

Lines changed: 17 additions & 22 deletions

File tree

Objects/setobject.c

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
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.
14
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.
47
*/
58

69
#include "Python.h"
10+
#include "structmember.h"
711

812
/* This must be >= 1. */
913
#define PERTURB_SHIFT 5
1014

1115
/* 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() */
1317

1418
#define EMPTY_TO_MINSIZE(so) do { \
1519
memset((so)->smalltable, 0, sizeof((so)->smalltable)); \
@@ -515,7 +519,7 @@ set_contains_internal(PySetObject *so, PyObject *key)
515519
return key != NULL && key != dummy;
516520
}
517521

518-
/***** Set iterator types **********************************************/
522+
/***** Set iterator type ***********************************************/
519523

520524
static PyTypeObject PySetIter_Type; /* Forward */
521525

@@ -558,7 +562,6 @@ setiter_len(setiterobject *si)
558562

559563
static PySequenceMethods setiter_as_sequence = {
560564
(inquiry)setiter_len, /* sq_length */
561-
0, /* sq_concat */
562565
};
563566

564567
static PyObject *setiter_iternext(setiterobject *si)
@@ -632,19 +635,6 @@ static PyTypeObject PySetIter_Type = {
632635
(iternextfunc)setiter_iternext, /* tp_iternext */
633636
};
634637

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-
648638
static int
649639
set_len(PyObject *so)
650640
{
@@ -764,6 +754,7 @@ frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
764754
void
765755
PySet_Fini(void)
766756
{
757+
Py_XDECREF(dummy);
767758
Py_XDECREF(emptyfrozenset);
768759
}
769760

@@ -1309,22 +1300,26 @@ set_nocmp(PyObject *self)
13091300
static long
13101301
frozenset_hash(PyObject *self)
13111302
{
1312-
PyObject *key;
13131303
PySetObject *so = (PySetObject *)self;
1314-
int pos = 0;
13151304
long hash = 1927868237L;
1305+
int i, j;
13161306

13171307
if (so->hash != -1)
13181308
return so->hash;
13191309

13201310
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++;
13221317
/* Work to increase the bit dispersion for closely spaced hash
13231318
values. The is important because some use cases have many
13241319
combinations of a small number of elements with nearby
13251320
hashes so that many distinct combinations collapse to only
13261321
a handful of distinct hash values. */
1327-
long h = PyObject_Hash(key);
1322+
h = entry->hash;
13281323
hash ^= (h ^ (h << 16) ^ 89869747L) * 3644798167u;
13291324
}
13301325
hash = hash * 69069L + 907133923L;

0 commit comments

Comments
 (0)