Skip to content
Open
Changes from all commits
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
45 changes: 43 additions & 2 deletions std/container/binaryheap.d
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,26 @@ Clears the heap by detaching it from the underlying store.
_payload = _payload.init;
}

/**
Clears the inactive portion of the heap (from `length` to `capacity`)
to break GC reachability. This is useful for heaps with large capacities
where the unused portion might hold references to objects.
*/
void removeTail()
{
if (!_payload.refCountedStore.isInitialized) return;
if (_length >= _store.length) return;
alias T = typeof(_store[0]);
static if (hasIndirections!T)
{
// Clear the inactive portion of the store
foreach (i; _length .. _store.length)
{
_store[i] = T.init;
}
}
}

/**
Inserts `value` into the store. If the underlying store is a range
and $(D length == capacity), throws an exception.
Expand Down Expand Up @@ -312,8 +332,8 @@ and $(D length == capacity), throws an exception.
return 1;
}

/**
Removes the largest element from the heap.
/**
Removes the largest element from the heap.
*/
void removeFront()
{
Expand Down Expand Up @@ -637,3 +657,24 @@ original Dyamic Array, but point to a new Dynamic Array.
a[0] = 60;
assert(h.front() == 40);
}

/// Test removeTail() clears inactive portion of heap with references
@system unittest
{
class Node { int value; this(int v) { value = v; } }

Node[] a = new Node[10];
foreach (i; 0 .. 5)
a[i] = new Node(i);

auto h = heapify!"a.value > b.value"(a[0 .. 5]);

h.insert(new Node(6));
Node saved = a[5];
assert(a[6] is null);

// After removeTail(), inactive slots should be cleared
h.removeTail();
assert(a[5] is saved); // Active element unchanged
assert(a[6] is null); // Inactive slots cleared
}