@@ -136,8 +136,8 @@ pub fn deinit(self: *Self) void {
136
136
self .stopMemorySegmentMergeThread ();
137
137
self .stopFileSegmentMergeThread ();
138
138
139
- self .memory_segments .deinit (self . allocator );
140
- self .file_segments .deinit (self . allocator );
139
+ self .memory_segments .deinit ();
140
+ self .file_segments .deinit ();
141
141
142
142
self .oplog .deinit ();
143
143
self .oplog_dir .close ();
@@ -245,7 +245,7 @@ fn loadSegments(self: *Self) !void {
245
245
const segment_ids = filefmt .readIndexFile (self .data_dir , self .allocator ) catch | err | {
246
246
if (err == error .FileNotFound ) {
247
247
if (self .options .create ) {
248
- try filefmt . writeIndexFile (self .data_dir , &[ _ ] SegmentId {} );
248
+ try self . updateIndexFile (self .file_segments . segments . value );
249
249
return ;
250
250
}
251
251
return error .IndexNotFound ;
@@ -254,15 +254,12 @@ fn loadSegments(self: *Self) !void {
254
254
};
255
255
defer self .allocator .free (segment_ids );
256
256
257
- var segments = try FileSegmentList .createShared (self .allocator , segment_ids .len );
258
- defer segments .release (self .allocator , .{self .allocator });
257
+ try self .file_segments .segments .value .nodes .ensureTotalCapacity (self .allocator , segment_ids .len );
259
258
260
259
for (segment_ids ) | segment_id | {
261
260
const node = try self .loadSegment (segment_id );
262
- segments .value .nodes .appendAssumeCapacity (node );
261
+ self . file_segments . segments .value .nodes .appendAssumeCapacity (node );
263
262
}
264
-
265
- self .file_segments .segments .swap (& segments );
266
263
}
267
264
268
265
fn doCheckpoint (self : * Self ) ! bool {
@@ -299,7 +296,7 @@ fn doCheckpoint(self: *Self) !bool {
299
296
300
297
file_segments_update .appendSegment (target );
301
298
302
- try self .writeIndexFile (file_segments_update .segments .value );
299
+ try self .updateIndexFile (file_segments_update .segments .value );
303
300
304
301
// commit updated lists
305
302
@@ -343,16 +340,29 @@ fn stopCheckpointThread(self: *Self) void {
343
340
self .checkpoint_thread = null ;
344
341
}
345
342
346
- fn writeIndexFile (self : * Self , segments : * FileSegmentList ) ! void {
343
+ fn updateIndexFile (self : * Self , segments : * FileSegmentList ) ! void {
347
344
var ids = try segments .getIds (self .allocator );
348
345
defer ids .deinit (self .allocator );
349
346
350
347
try filefmt .writeIndexFile (self .data_dir , ids .items );
351
348
}
352
349
350
+ fn maybeMergeFileSegments (self : * Self ) ! bool {
351
+ var upd = try self .file_segments .prepareMerge () orelse return false ;
352
+ defer self .file_segments .cleanupAfterUpdate (& upd );
353
+
354
+ try self .updateIndexFile (upd .segments .value );
355
+
356
+ self .segments_lock .lock ();
357
+ defer self .segments_lock .unlock ();
358
+
359
+ self .file_segments .commitUpdate (& upd );
360
+ return true ;
361
+ }
362
+
353
363
fn fileSegmentMergeThreadFn (self : * Self ) void {
354
364
while (! self .stopping .load (.acquire )) {
355
- if (self .file_segments . merge ( & self . segments_lock , writeIndexFile , self )) | successful | {
365
+ if (self .maybeMergeFileSegments ( )) | successful | {
356
366
if (successful ) {
357
367
continue ;
358
368
}
@@ -380,56 +390,20 @@ fn stopFileSegmentMergeThread(self: *Self) void {
380
390
self .file_segment_merge_thread = null ;
381
391
}
382
392
383
- fn prepareFileSegmentMerge (self : * Self ) ! ? FileSegmentList.PreparedMerge {
384
- self .segments_lock . lockShared () ;
385
- defer self .segments_lock . unlockShared ( );
393
+ fn maybeMergeMemorySegments (self : * Self ) ! bool {
394
+ var upd = try self .memory_segments . prepareMerge () orelse return false ;
395
+ defer self .memory_segments . cleanupAfterUpdate ( & upd );
386
396
387
- return try self .file_segments .prepareMerge ();
388
- }
389
-
390
- fn maybeMergeFileSegments (self : * Self ) ! bool {
391
- var merge = try self .prepareFileSegmentMerge () orelse return false ;
392
- defer merge .merger .deinit ();
393
- errdefer self .file_segments .destroySegment (merge .target );
394
-
395
- // We are reading segment data without holding any lock here,
396
- // but it's OK, because are the only ones modifying segments.
397
- // The only other place with write access to the segment list is
398
- // the checkpoint thread, which is only ever adding new segments.
399
- try merge .target .data .build (self .data_dir , & merge .merger );
400
- errdefer merge .target .data .delete (self .data_dir );
401
-
402
- // By acquiring file_segments_lock, we make sure that the file_segments list
403
- // can't be modified by other threads.
404
- self .file_segments_lock .lock ();
405
- defer self .file_segments_lock .unlock ();
406
-
407
- var ids = try self .file_segments .getIdsAfterAppliedMerge (merge , self .allocator );
408
- defer ids .deinit ();
409
-
410
- try filefmt .writeIndexFile (self .data_dir , ids .items );
411
-
412
- // We want to do this outside of segments_lock to avoid blocking searches more than necessary
413
- defer self .file_segments .cleanupAfterMerge (merge , .{self .data_dir });
414
-
415
- // This lock allows to modify the file_segments list, it's blocking all other threads.
416
397
self .segments_lock .lock ();
417
398
defer self .segments_lock .unlock ();
418
399
419
- self .file_segments .applyMerge (merge );
420
-
421
- log .info ("committed merge segment {}:{}" , .{ merge .target .data .id .version , merge .target .data .id .included_merges });
400
+ self .memory_segments .commitUpdate (& upd );
422
401
return true ;
423
402
}
424
403
425
- fn memorySegmentMergePreCommit (self : * Self , segments : * MemorySegmentList ) ! void {
426
- _ = self ;
427
- _ = segments ;
428
- }
429
-
430
404
fn memorySegmentMergeThreadFn (self : * Self ) void {
431
405
while (! self .stopping .load (.acquire )) {
432
- if (self .memory_segments . merge ( & self . segments_lock , memorySegmentMergePreCommit , self )) | successful | {
406
+ if (self .maybeMergeMemorySegments ( )) | successful | {
433
407
if (successful ) {
434
408
self .checkpoint_event .set ();
435
409
continue ;
0 commit comments