Skip to content

Commit 17fbb7c

Browse files
committed
Try to get segment reference counting under controll
1 parent 072e153 commit 17fbb7c

File tree

2 files changed

+28
-28
lines changed

2 files changed

+28
-28
lines changed

src/Index.zig

+3-3
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ pub const PendingUpdate = struct {
148148

149149
pub fn deinit(self: *@This(), allocator: Allocator) void {
150150
if (self.finished) return;
151-
self.segments.release(allocator, .{allocator});
151+
MemorySegmentList.destroySegments(allocator, &self.segments);
152152
MemorySegmentList.destroySegment(allocator, &self.node);
153153
self.finished = true;
154154
}
@@ -509,8 +509,8 @@ fn acquireSegments(self: *Self) SegmentsSnapshot {
509509

510510
// Release the previously acquired segments lists, they will get deleted if no longer needed.
511511
fn releaseSegments(self: *Self, segments: *SegmentsSnapshot) void {
512-
segments.file_segments.release(self.allocator, .{self.allocator});
513-
segments.memory_segments.release(self.allocator, .{self.allocator});
512+
MemorySegmentList.destroySegments(self.allocator, &segments.memory_segments);
513+
FileSegmentList.destroySegments(self.allocator, &segments.file_segments);
514514
}
515515

516516
pub fn search(self: *Self, hashes: []const u32, allocator: std.mem.Allocator, deadline: Deadline) !SearchResults {

src/segment_list.zig

+25-25
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub fn SegmentList(Segment: type) type {
5050

5151
pub fn deinit(self: *Self, allocator: Allocator) void {
5252
for (self.nodes.items) |*node| {
53-
destroySegment(allocator, node);
53+
node.release(allocator, .{});
5454
}
5555
self.nodes.deinit(allocator);
5656
}
@@ -59,8 +59,26 @@ pub fn SegmentList(Segment: type) type {
5959
return Node.create(allocator, @call(.auto, Segment.init, .{ allocator, options }));
6060
}
6161

62-
pub fn destroySegment(allocator: Allocator, node: *Node) void {
63-
node.release(allocator, .{});
62+
pub fn destroySegment(allocator: Allocator, segment: *Node) void {
63+
segment.releaseWithCleanup(allocator, destroySegmentCallback, .{});
64+
}
65+
66+
pub fn destroySegments(allocator: Allocator, segments: *SharedPtr(Self)) void {
67+
// we also call cleanup on these segments, to ensure that unused segments will get deleted from disk
68+
segments.releaseWithCleanup(allocator, destroySegmentListCallback, .{allocator});
69+
}
70+
71+
fn destroySegmentListCallback(segments: *Self, allocator: Allocator) void {
72+
while (segments.nodes.items.len > 0) {
73+
var node = segments.nodes.pop();
74+
destroySegment(allocator, &node);
75+
}
76+
segments.deinit(allocator);
77+
}
78+
79+
fn destroySegmentCallback(segment: *Segment) void {
80+
segment.cleanup();
81+
segment.deinit();
6482
}
6583

6684
pub fn appendSegmentInto(self: Self, copy: *Self, node: Node) void {
@@ -190,7 +208,7 @@ pub fn SegmentListManager(Segment: type) type {
190208
}
191209

192210
pub fn deinit(self: *Self) void {
193-
self.releaseSegments(&self.segments);
211+
self.segments.release(self.allocator, .{self.allocator});
194212
}
195213

196214
pub fn count(self: Self) usize {
@@ -204,8 +222,8 @@ pub fn SegmentListManager(Segment: type) type {
204222
return self.segments.acquire();
205223
}
206224

207-
fn releaseSegments(self: *Self, segments: *SharedPtr(List)) void {
208-
segments.release(self.allocator, .{self.allocator});
225+
fn destroySegments(self: *Self, segments: *SharedPtr(List)) void {
226+
List.destroySegments(self.allocator, segments);
209227
}
210228

211229
pub fn needsMerge(self: Self) bool {
@@ -214,7 +232,7 @@ pub fn SegmentListManager(Segment: type) type {
214232

215233
pub fn prepareMerge(self: *Self) !?Update {
216234
var segments = self.acquireSegments();
217-
defer self.releaseSegments(&segments);
235+
defer self.destroySegments(&segments);
218236

219237
self.num_allowed_segments.store(self.merge_policy.calculateBudget(segments.value.nodes.items), .release);
220238
if (!self.needsMerge()) {
@@ -289,23 +307,5 @@ pub fn SegmentListManager(Segment: type) type {
289307
}
290308
self.destroySegments(&update.segments);
291309
}
292-
293-
pub fn destroySegments(self: *Self, segments: *SharedPtr(List)) void {
294-
// we also call cleanup on these segments, to ensure that unused segments will get deleted from disk
295-
segments.releaseWithCleanup(self.allocator, destroySegmentList, .{self.allocator});
296-
}
297-
298-
fn destroySegmentList(segments: *List, allocator: Allocator) void {
299-
while (segments.nodes.items.len > 0) {
300-
var node = segments.nodes.pop();
301-
node.releaseWithCleanup(allocator, destroySegment, .{});
302-
}
303-
segments.deinit(allocator);
304-
}
305-
306-
fn destroySegment(segment: *Segment) void {
307-
segment.cleanup();
308-
segment.deinit();
309-
}
310310
};
311311
}

0 commit comments

Comments
 (0)