DoxigAlpha

shrinkCapacity

Only shrinks capacity or retains current capacity. It may fail to reduce the capacity in which case the capacity will remain unchanged.

Function parameters

Parameters

#
self:*Self
new_capacity:usize

This is a stack data structure where pointers to indexes have the same lifetime as the data structure

Functions

#
SegmentedList
This is a stack data structure where pointers to indexes have the same lifetime as the data structure

Source

Implementation

#
pub fn shrinkCapacity(self: *Self, allocator: Allocator, new_capacity: usize) void {
    if (new_capacity <= prealloc_item_count) {
        const len = @as(ShelfIndex, @intCast(self.dynamic_segments.len));
        self.freeShelves(allocator, len, 0);
        allocator.free(self.dynamic_segments);
        self.dynamic_segments = &[_][*]T{};
        return;
    }

    const new_cap_shelf_count = shelfCount(new_capacity);
    const old_shelf_count = @as(ShelfIndex, @intCast(self.dynamic_segments.len));
    assert(new_cap_shelf_count <= old_shelf_count);
    if (new_cap_shelf_count == old_shelf_count) return;

    // freeShelves() must be called before resizing the dynamic
    // segments, but we don't know if resizing the dynamic segments
    // will work until we try it. So we must allocate a fresh memory
    // buffer in order to reduce capacity.
    const new_dynamic_segments = allocator.alloc([*]T, new_cap_shelf_count) catch return;
    self.freeShelves(allocator, old_shelf_count, new_cap_shelf_count);
    if (allocator.resize(self.dynamic_segments, new_cap_shelf_count)) {
        // We didn't need the new memory allocation after all.
        self.dynamic_segments = self.dynamic_segments[0..new_cap_shelf_count];
        allocator.free(new_dynamic_segments);
    } else {
        // Good thing we allocated that new memory slice.
        @memcpy(new_dynamic_segments, self.dynamic_segments[0..new_cap_shelf_count]);
        allocator.free(self.dynamic_segments);
        self.dynamic_segments = new_dynamic_segments;
    }
}