Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Cache empty HAMT node
  • Loading branch information
Yury Selivanov
Yury Selivanov committed Jan 22, 2018
commit 52dc25ba70ddf194e5e05ac4f98aca0f5a2a8fd2
1 change: 1 addition & 0 deletions Lib/test/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,7 @@ def test_hamt_gc_1(self):
A = HashKey(100, 'A')

h = hamt()
h = h.set(0, 0) # empty HAMT node is memoized in hamt.c
ref = weakref.ref(h)

a = []
Expand Down
15 changes: 15 additions & 0 deletions Python/hamt.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ typedef struct {


static PyHamtNode_Bitmap *_empty_bitmap_node;
static PyHamtObject *_empty_hamt;


static PyHamtObject *
Expand Down Expand Up @@ -2467,6 +2468,13 @@ hamt_alloc(void)
PyHamtObject *
_PyHamt_New(void)
{
if (_empty_hamt != NULL) {
/* HAMT is an immutable object so we can easily cache an
empty instance. */
Py_INCREF(_empty_hamt);
return _empty_hamt;
}

PyHamtObject *o = hamt_alloc();
if (o == NULL) {
return NULL;
Expand All @@ -2479,6 +2487,12 @@ _PyHamt_New(void)
}

o->h_count = 0;

if (_empty_hamt == NULL) {
Py_INCREF(o);
_empty_hamt = o;
}

return o;
}

Expand Down Expand Up @@ -2958,5 +2972,6 @@ _PyHamt_Init(void)
void
_PyHamt_Fini(void)
{
Py_CLEAR(_empty_hamt);
Py_CLEAR(_empty_bitmap_node);
}