Skip to content

Commit fc39917

Browse files
author
Erlend E. Aasland
committed
Revert LRU cache element optimisation
This reverts commit 6d7cdaf.
1 parent f9ac4c5 commit fc39917

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

Modules/_functoolsmodule.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -762,10 +762,28 @@ typedef struct lru_list_elem {
762762
PyObject *key, *result;
763763
} lru_list_elem;
764764

765+
static int
766+
lru_list_elem_clear(lru_list_elem *link)
767+
{
768+
Py_CLEAR(link->key);
769+
Py_CLEAR(link->result);
770+
return 0;
771+
}
772+
773+
static int
774+
lru_list_elem_traverse(lru_list_elem *link, visitproc visit, void *arg)
775+
{
776+
Py_VISIT(link->key);
777+
Py_VISIT(link->result);
778+
Py_VISIT(Py_TYPE(link));
779+
return 0;
780+
}
781+
765782
static void
766783
lru_list_elem_dealloc(lru_list_elem *link)
767784
{
768785
PyTypeObject *tp = Py_TYPE(link);
786+
PyObject_GC_UnTrack(link);
769787
Py_XDECREF(link->key);
770788
Py_XDECREF(link->result);
771789
tp->tp_free(link);
@@ -774,13 +792,16 @@ lru_list_elem_dealloc(lru_list_elem *link)
774792

775793
static PyType_Slot lru_list_elem_type_slots[] = {
776794
{Py_tp_dealloc, lru_list_elem_dealloc},
795+
{Py_tp_traverse, lru_list_elem_traverse},
796+
{Py_tp_clear, lru_list_elem_clear},
777797
{0, 0}
778798
};
779799

780800
static PyType_Spec lru_list_elem_type_spec = {
781801
.name = "functools._lru_list_elem",
782802
.basicsize = sizeof(lru_list_elem),
783-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
803+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
804+
Py_TPFLAGS_HAVE_GC),
784805
.slots = lru_list_elem_type_slots
785806
};
786807

@@ -1045,8 +1066,8 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
10451066
self->root.next == &self->root)
10461067
{
10471068
/* Cache is not full, so put the result in a new link */
1048-
link = (lru_list_elem *)PyObject_New(lru_list_elem,
1049-
self->lru_list_elem_type);
1069+
link = (lru_list_elem *)PyObject_GC_New(lru_list_elem,
1070+
self->lru_list_elem_type);
10501071
if (link == NULL) {
10511072
Py_DECREF(key);
10521073
Py_DECREF(result);
@@ -1056,6 +1077,7 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
10561077
link->hash = hash;
10571078
link->key = key;
10581079
link->result = result;
1080+
PyObject_GC_Track(link);
10591081
/* What is really needed here is a SetItem variant with a "no clobber"
10601082
option. If the __eq__ call triggers a reentrant call that adds
10611083
this same key, then this setitem call will update the cache dict
@@ -1345,9 +1367,7 @@ lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg)
13451367
lru_list_elem *link = self->root.next;
13461368
while (link != &self->root) {
13471369
lru_list_elem *next = link->next;
1348-
Py_VISIT(link->key);
1349-
Py_VISIT(link->result);
1350-
Py_VISIT(Py_TYPE(link));
1370+
Py_VISIT(link);
13511371
link = next;
13521372
}
13531373
Py_VISIT(self->cache);

0 commit comments

Comments
 (0)