@@ -175,6 +175,7 @@ pub fn SegmentListManager(Segment: type) type {
175
175
segments : SharedPtr (List ),
176
176
merge_policy : MergePolicy ,
177
177
num_allowed_segments : std .atomic .Value (usize ),
178
+ update_lock : std.Thread.Mutex ,
178
179
179
180
pub fn init (allocator : Allocator , merge_policy : MergePolicy ) ! Self {
180
181
const segments = try SharedPtr (List ).create (allocator , List .initEmpty ());
@@ -183,6 +184,7 @@ pub fn SegmentListManager(Segment: type) type {
183
184
.segments = segments ,
184
185
.merge_policy = merge_policy ,
185
186
.num_allowed_segments = std .atomic .Value (usize ).init (0 ),
187
+ .update_lock = .{},
186
188
};
187
189
}
188
190
@@ -216,7 +218,7 @@ pub fn SegmentListManager(Segment: type) type {
216
218
return self .segments .value .nodes .items .len > self .num_allowed_segments .load (.acquire );
217
219
}
218
220
219
- pub fn merge (self : * Self , lock : * std.Thread.RwLock ) ! bool {
221
+ pub fn merge (self : * Self , lock : * std.Thread.RwLock , preCommitFn : anytype , ctx : anytype ) ! bool {
220
222
var segments = self .acquireSegments (lock );
221
223
defer self .releaseSegments (& segments );
222
224
@@ -240,25 +242,34 @@ pub fn SegmentListManager(Segment: type) type {
240
242
241
243
try target .value .merge (& merger );
242
244
243
- lock .lock ();
244
- defer lock .unlock ();
245
+ self . update_lock .lock ();
246
+ defer self . update_lock .unlock ();
245
247
246
- var new_segments = try List .init (self .allocator , self .segments .value .nodes .items .len );
247
- errdefer new_segments .deinit (self .allocator );
248
+ var new_segments = try SharedPtr (List ).create (self .allocator , undefined );
249
+ defer new_segments .release (self .allocator , .{self .allocator });
250
+
251
+ new_segments .value .* = try List .init (self .allocator , self .segments .value .nodes .items .len );
252
+ defer new_segments .value .deinit (self .allocator );
248
253
249
254
var inserted_merged = false ;
250
255
for (self .segments .value .nodes .items ) | node | {
251
256
if (target .value .id .contains (node .value .id )) {
252
257
if (! inserted_merged ) {
253
- new_segments .nodes .appendAssumeCapacity (target );
258
+ new_segments .value . nodes .appendAssumeCapacity (target );
254
259
inserted_merged = true ;
255
260
}
256
261
} else {
257
- new_segments .nodes .appendAssumeCapacity (node .acquire ());
262
+ new_segments .value . nodes .appendAssumeCapacity (node .acquire ());
258
263
}
259
264
}
260
265
261
- try self .swap (new_segments );
266
+ try @call (.auto , preCommitFn , .{ ctx , new_segments .value });
267
+
268
+ lock .lock ();
269
+ defer lock .unlock ();
270
+
271
+ self .segments .swap (& new_segments );
272
+
262
273
return true ;
263
274
}
264
275
};
0 commit comments