-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
bpo-37596: compile to reproducible frozen sets #27769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -99,6 +99,8 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash) | |||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
static int set_table_resize(PySetObject *, Py_ssize_t); | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
PyTypeObject PyReproducibleFrozenSet_Type; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
static int | ||||||||||||||||||||||||||||
set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) | ||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||
|
@@ -118,9 +120,15 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) | |||||||||||||||||||||||||||
restart: | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
mask = so->mask; | ||||||||||||||||||||||||||||
i = (size_t)hash & mask; | ||||||||||||||||||||||||||||
freeslot = NULL; | ||||||||||||||||||||||||||||
perturb = hash; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
if (_PyReproducibleFrozenSet_CheckExact(so)) { | ||||||||||||||||||||||||||||
i = 0; | ||||||||||||||||||||||||||||
perturb = 0; | ||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||
i = (size_t)hash & mask; | ||||||||||||||||||||||||||||
perturb = hash; | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
Comment on lines
+125
to
+131
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately, this impacts the performance of normal set operations, and given that is a basic type of the interpreter I am not very convinced about it. This is one of the reasons I said:
Because a new type will require a new set of independent functions on the required path to not impact the regular set and frozenset and that is much more code than what I am confortable with. On the other hand, others may have other views on this, so I am happy to be convinced otherwise :) |
||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
while (1) { | ||||||||||||||||||||||||||||
entry = &so->table[i]; | ||||||||||||||||||||||||||||
|
@@ -2233,6 +2241,53 @@ PyTypeObject PyFrozenSet_Type = { | |||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
PyTypeObject _PyReproducibleFrozenSet_Type = { | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For new types, please use C99 named fields like cpython/Doc/includes/custom2.c Lines 98 to 110 in bb3e0c2
|
||||||||||||||||||||||||||||
PyVarObject_HEAD_INIT(&PyType_Type, 0) | ||||||||||||||||||||||||||||
"reproducible_frozenset", /* tp_name */ | ||||||||||||||||||||||||||||
sizeof(PySetObject), /* tp_basicsize */ | ||||||||||||||||||||||||||||
0, /* tp_itemsize */ | ||||||||||||||||||||||||||||
/* methods */ | ||||||||||||||||||||||||||||
(destructor)set_dealloc, /* tp_dealloc */ | ||||||||||||||||||||||||||||
0, /* tp_vectorcall_offset */ | ||||||||||||||||||||||||||||
0, /* tp_getattr */ | ||||||||||||||||||||||||||||
0, /* tp_setattr */ | ||||||||||||||||||||||||||||
0, /* tp_as_async */ | ||||||||||||||||||||||||||||
(reprfunc)set_repr, /* tp_repr */ | ||||||||||||||||||||||||||||
&frozenset_as_number, /* tp_as_number */ | ||||||||||||||||||||||||||||
&set_as_sequence, /* tp_as_sequence */ | ||||||||||||||||||||||||||||
0, /* tp_as_mapping */ | ||||||||||||||||||||||||||||
frozenset_hash, /* tp_hash */ | ||||||||||||||||||||||||||||
0, /* tp_call */ | ||||||||||||||||||||||||||||
0, /* tp_str */ | ||||||||||||||||||||||||||||
PyObject_GenericGetAttr, /* tp_getattro */ | ||||||||||||||||||||||||||||
0, /* tp_setattro */ | ||||||||||||||||||||||||||||
0, /* tp_as_buffer */ | ||||||||||||||||||||||||||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | | ||||||||||||||||||||||||||||
Py_TPFLAGS_BASETYPE | | ||||||||||||||||||||||||||||
_Py_TPFLAGS_MATCH_SELF, /* tp_flags */ | ||||||||||||||||||||||||||||
frozenset_doc, /* tp_doc */ | ||||||||||||||||||||||||||||
(traverseproc)set_traverse, /* tp_traverse */ | ||||||||||||||||||||||||||||
(inquiry)set_clear_internal, /* tp_clear */ | ||||||||||||||||||||||||||||
(richcmpfunc)set_richcompare, /* tp_richcompare */ | ||||||||||||||||||||||||||||
offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */ | ||||||||||||||||||||||||||||
(getiterfunc)set_iter, /* tp_iter */ | ||||||||||||||||||||||||||||
0, 8000 /* tp_iternext */ | ||||||||||||||||||||||||||||
0, /* tp_methods */ | ||||||||||||||||||||||||||||
0, /* tp_members */ | ||||||||||||||||||||||||||||
0, /* tp_getset */ | ||||||||||||||||||||||||||||
&PyFrozenSet_Type, /* tp_base */ | ||||||||||||||||||||||||||||
0, /* tp_dict */ | ||||||||||||||||||||||||||||
0, /* tp_descr_get */ | ||||||||||||||||||||||||||||
0, /* tp_descr_set */ | ||||||||||||||||||||||||||||
0, /* tp_dictoffset */ | ||||||||||||||||||||||||||||
0, /* tp_init */ | ||||||||||||||||||||||||||||
PyType_GenericAlloc, /* tp_alloc */ | ||||||||||||||||||||||||||||
frozenset_new, /* tp_new */ | ||||||||||||||||||||||||||||
PyObject_GC_Del, /* tp_free */ | ||||||||||||||||||||||||||||
.tp_vectorcall = frozenset_vectorcall, | ||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
/***** C API functions *************************************************/ | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
PyObject * | ||||||||||||||||||||||||||||
|
@@ -2247,6 +2302,12 @@ PyFrozenSet_New(PyObject *iterable) | |||||||||||||||||||||||||||
return make_new_set(&PyFrozenSet_Type, iterable); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
PyObject * | ||||||||||||||||||||||||||||
_PyReproducibleFrozenSet_New(PyObject *iterable) | ||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||
return make_new_set(&_PyReproducibleFrozenSet_Type, iterable); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
Py_ssize_t | ||||||||||||||||||||||||||||
PySet_Size(PyObject *anyset) | ||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These functions should not be public. I think we really should not expose this type to be used or checked from outside CPython