summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2013-08-23 08:22:15 (GMT)
committerRaymond Hettinger <python@rcn.com>2013-08-23 08:22:15 (GMT)
commitbfc1e1a9cd669e5e4b2d288a5c0cdc407a93074a (patch)
tree30cf354a76aa47dd6f98bdc4a1e74734a7d1cf8b
parenta1db94554b0f9e26db5e0a75f6363436fe9661a3 (diff)
downloadcpython-bfc1e1a9cd669e5e4b2d288a5c0cdc407a93074a.zip
cpython-bfc1e1a9cd669e5e4b2d288a5c0cdc407a93074a.tar.gz
cpython-bfc1e1a9cd669e5e4b2d288a5c0cdc407a93074a.tar.bz2
Add the same dummy type that is used in dictionaries.
-rw-r--r--Objects/setobject.c64
1 files changed, 49 insertions, 15 deletions
diff --git a/Objects/setobject.c b/Objects/setobject.c
index 94789c6..8a855a3 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -29,7 +29,10 @@ set_key_error(PyObject *arg)
#define PERTURB_SHIFT 5
/* Object used as dummy key to fill deleted entries */
-static PyObject *dummy = NULL; /* Initialized by first call to make_new_set() */
+
+static PyObject _dummy_struct;
+
+#define dummy (&_dummy_struct)
#ifdef Py_REF_DEBUG
PyObject *
@@ -329,7 +332,6 @@ set_table_resize(PySetObject *so, Py_ssize_t minused)
Py_ssize_t i;
int is_oldtable_malloced;
setentry small_copy[PySet_MINSIZE];
- PyObject *dummy_entry;
assert(minused >= 0);
@@ -386,10 +388,8 @@ set_table_resize(PySetObject *so, Py_ssize_t minused)
/* Copy the data over; this is refcount-neutral for active entries;
dummy entries aren't copied over, of course */
- dummy_entry = dummy;
for (entry = oldtable; i > 0; entry++) {
- if (entry->key != NULL && entry->key != dummy_entry) {
- /* ACTIVE */
+ if (entry->key != NULL && entry->key != dummy) {
--i;
set_insert_clean(so, entry->key, entry->hash);
}
@@ -674,7 +674,6 @@ set_merge(PySetObject *so, PyObject *otherset)
{
PySetObject *other;
PyObject *key;
- PyObject *dummy_entry;
Py_hash_t hash;
Py_ssize_t i;
setentry *entry;
@@ -694,13 +693,12 @@ set_merge(PySetObject *so, PyObject *otherset)
if (set_table_resize(so, (so->used + other->used)*2) != 0)
return -1;
}
- dummy_entry = dummy;
for (i = 0; i <= other->mask; i++) {
entry = &other->table[i];
key = entry->key;
hash = entry->hash;
if (key != NULL &&
- key != dummy_entry) {
+ key != dummy) {
Py_INCREF(key);
if (set_insert_key(so, key, hash) == -1) {
Py_DECREF(key);
@@ -1070,12 +1068,6 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
{
PySetObject *so = NULL;
- if (dummy == NULL) { /* Auto-initialize dummy */
- dummy = PyUnicode_FromString("<dummy key>");
- if (dummy == NULL)
- return NULL;
- }
-
/* create PySetObject structure */
if (numfree &&
(type == &PySet_Type || type == &PyFrozenSet_Type)) {
@@ -1172,7 +1164,6 @@ void
PySet_Fini(void)
{
PySet_ClearFreeList();
- Py_CLEAR(dummy);
Py_CLEAR(emptyfrozenset);
}
@@ -2581,3 +2572,46 @@ test_c_api(PySetObject *so)
#undef assertRaises
#endif
+
+/***** Dummy Struct *************************************************/
+
+static PyObject *
+dummy_repr(PyObject *op)
+{
+ return PyUnicode_FromString("<dummy key>");
+}
+
+static void
+dummy_dealloc(PyObject* ignore)
+{
+ Py_FatalError("deallocating <dummy key>");
+}
+
+static PyTypeObject _PySetDummy_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "<dummy key> type",
+ 0,
+ 0,
+ dummy_dealloc, /*tp_dealloc*/ /*never called*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_reserved*/
+ dummy_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call */
+ 0, /*tp_str */
+ 0, /*tp_getattro */
+ 0, /*tp_setattro */
+ 0, /*tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /*tp_flags */
+};
+
+static PyObject _dummy_struct = {
+ _PyObject_EXTRA_INIT
+ 2, &_PySetDummy_Type
+};
+