Skip to content

Commit e21c3c9

Browse files
committed
Use PyWeakref_GetRef and critical section in BlockValuesRefs
1 parent ca91dd4 commit e21c3c9

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

pandas/_libs/internals.pyx

+24-12
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ from collections import defaultdict
33
cimport cython
44
from cpython.object cimport PyObject
55
from cpython.pyport cimport PY_SSIZE_T_MAX
6+
from cpython.ref cimport Py_DECREF
67
from cpython.slice cimport PySlice_GetIndicesEx
78
from cpython.weakref cimport (
8-
PyWeakref_GetObject,
9+
PyWeakref_GetRef,
910
PyWeakref_NewRef,
1011
)
1112
from cython cimport Py_ssize_t
@@ -908,11 +909,18 @@ cdef class BlockValuesRefs:
908909
# if force=False. Clearing for every insertion causes slowdowns if
909910
# all these objects stay alive, e.g. df.items() for wide DataFrames
910911
# see GH#55245 and GH#55008
912+
cdef PyObject* pobj
913+
cdef bint status
914+
911915
if force or len(self.referenced_blocks) > self.clear_counter:
912-
self.referenced_blocks = [
913-
ref for ref in self.referenced_blocks
914-
if PyWeakref_GetObject(ref) != Py_None
915-
]
916+
new_referenced_blocks = []
917+
for ref in self.referenced_blocks:
918+
status = PyWeakref_GetRef(ref, &pobj)
919+
if status == 1:
920+
new_referenced_blocks.append(ref)
921+
Py_DECREF(<object>pobj)
922+
self.referenced_blocks = new_referenced_blocks
923+
916924
nr_of_refs = len(self.referenced_blocks)
917925
if nr_of_refs < self.clear_counter // 2:
918926
self.clear_counter = max(self.clear_counter // 2, 500)
@@ -927,8 +935,9 @@ cdef class BlockValuesRefs:
927935
blk : Block
928936
The block that the new references should point to.
929937
"""
930-
self._clear_dead_references()
931-
self.referenced_blocks.append(PyWeakref_NewRef(blk, None))
938+
with cython.critical_section(self):
939+
self._clear_dead_references()
940+
self.referenced_blocks.append(PyWeakref_NewRef(blk, None))
932941

933942
def add_index_reference(self, index: object) -> None:
934943
"""Adds a new reference to our reference collection when creating an index.
@@ -938,8 +947,9 @@ cdef class BlockValuesRefs:
938947
index : Index
939948
The index that the new reference should point to.
940949
"""
941-
self._clear_dead_references()
942-
self.referenced_blocks.append(PyWeakref_NewRef(index, None))
950+
with cython.critical_section(self):
951+
self._clear_dead_references()
952+
self.referenced_blocks.append(PyWeakref_NewRef(index, None))
943953

944954
def has_reference(self) -> bool:
945955
"""Checks if block has foreign references.
@@ -951,6 +961,8 @@ cdef class BlockValuesRefs:
951961
-------
952962
bool
953963
"""
954-
self._clear_dead_references(force=True)
955-
# Checking for more references than block pointing to itself
956-
return len(self.referenced_blocks) > 1
964+
with cython.critical_section(self):
965+
self._clear_dead_references(force=True)
966+
# Checking for more references than block pointing to itself
967+
has_reference = len(self.referenced_blocks) > 1
968+
return has_reference

0 commit comments

Comments
 (0)