@@ -23,14 +23,16 @@ const FileSegmentNode = FileSegment.List.List.Node;
23
23
24
24
const SegmentMerger = @import ("segment_merger.zig" ).SegmentMerger ;
25
25
26
+ const TieredMergePolicy = @import ("segment_merge_policy.zig" ).TieredMergePolicy ;
27
+
26
28
const filefmt = @import ("filefmt.zig" );
27
29
28
30
const Self = @This ();
29
31
30
32
const Options = struct {
31
33
create : bool = false ,
32
34
min_segment_size : usize = 1_000_000 ,
33
- max_segment_size : usize = 100_000_000 ,
35
+ max_segment_size : usize = 1_000_000_000 ,
34
36
};
35
37
36
38
options : Options ,
@@ -58,8 +60,6 @@ update_lock: std.Thread.Mutex = .{},
58
60
// Mutex used to control merging of in-memory segments.
59
61
memory_merge_lock : std.Thread.Mutex = .{},
60
62
61
- file_segments_to_delete : std .ArrayList (SegmentID ),
62
-
63
63
checkpoint_mutex : std.Thread.Mutex = .{},
64
64
checkpoint_condition : std.Thread.Condition = .{},
65
65
checkpoint_stop : bool = false ,
@@ -82,15 +82,28 @@ pub fn init(allocator: std.mem.Allocator, dir: std.fs.Dir, options: Options) !Se
82
82
var oplog_dir = try dir .makeOpenPath ("oplog" , .{ .iterate = true });
83
83
errdefer oplog_dir .close ();
84
84
85
+ const file_segment_merge_policy = TieredMergePolicy (FileSegment ){
86
+ .min_segment_size = options .min_segment_size ,
87
+ .max_segment_size = options .max_segment_size ,
88
+ .segments_per_level = 10 ,
89
+ .segments_per_merge = 2 , // TODO increase to 10
90
+ };
91
+
92
+ const memory_segment_merge_policy = TieredMergePolicy (MemorySegment ){
93
+ .min_segment_size = 100 ,
94
+ .max_segment_size = options .min_segment_size ,
95
+ .segments_per_level = 10 ,
96
+ .segments_per_merge = 2 , // TODO increase to 5
97
+ };
98
+
85
99
return .{
86
100
.options = options ,
87
101
.allocator = allocator ,
88
102
.data_dir = data_dir ,
89
103
.oplog_dir = oplog_dir ,
90
104
.oplog = Oplog .init (allocator , oplog_dir ),
91
- .file_segments = FileSegmentList .init (allocator ),
92
- .file_segments_to_delete = std .ArrayList (SegmentID ).init (allocator ),
93
- .memory_segments = MemorySegmentList .init (allocator ),
105
+ .file_segments = FileSegmentList .init (allocator , file_segment_merge_policy ),
106
+ .memory_segments = MemorySegmentList .init (allocator , memory_segment_merge_policy ),
94
107
};
95
108
}
96
109
@@ -123,21 +136,19 @@ fn prepareMemorySegmentMerge(self: *Self) !?MemorySegmentList.PreparedMerge {
123
136
self .segments_lock .lockShared ();
124
137
defer self .segments_lock .unlockShared ();
125
138
126
- const options = SegmentMergeOptions {
127
- .max_segment_size = self .options .min_segment_size ,
128
- };
129
-
130
- const merge = try self .memory_segments .prepareMerge (options ) orelse return null ;
139
+ const merge = try self .memory_segments .prepareMerge () orelse return null ;
131
140
errdefer self .memory_segments .destroySegment (merge .target );
132
141
133
- try merge .target .data .merge (& merge .sources .node1 .data , & merge .sources .node2 .data , & self .memory_segments );
142
+ std .debug .assert (merge .sources .num_segments == 2 );
143
+ try merge .target .data .merge (& merge .sources .start .data , & merge .sources .end .data , & self .memory_segments );
134
144
135
145
return merge ;
136
146
}
137
147
138
148
fn finishMemorySegmentMerge (self : * Self , merge : MemorySegmentList.PreparedMerge ) bool {
139
- defer self .memory_segments .destroySegment (merge .sources .node1 );
140
- defer self .memory_segments .destroySegment (merge .sources .node2 );
149
+ std .debug .assert (merge .sources .num_segments == 2 );
150
+ defer self .memory_segments .destroySegment (merge .sources .start );
151
+ defer self .memory_segments .destroySegment (merge .sources .end );
141
152
142
153
self .segments_lock .lock ();
143
154
defer self .segments_lock .unlock ();
@@ -399,18 +410,18 @@ fn prepareFileSegmentMerge(self: *Self) !?FileSegmentList.PreparedMerge {
399
410
self .segments_lock .lockShared ();
400
411
defer self .segments_lock .unlockShared ();
401
412
402
- const options = SegmentMergeOptions {
403
- .max_segment_size = self .options .max_segment_size ,
404
- };
405
-
406
- const merge = try self .file_segments .prepareMerge (options ) orelse return null ;
413
+ const merge = try self .file_segments .prepareMerge () orelse return null ;
407
414
errdefer self .file_segments .destroySegment (merge .target );
408
415
409
416
var merger = SegmentMerger (FileSegment ).init (self .allocator , & self .file_segments );
410
417
defer merger .deinit ();
411
418
412
- try merger .addSource (& merge .sources .node1 .data );
413
- try merger .addSource (& merge .sources .node2 .data );
419
+ var source_node = merge .sources .start ;
420
+ while (true ) {
421
+ try merger .addSource (& source_node .data );
422
+ if (source_node == merge .sources .end ) break ;
423
+ source_node = source_node .next orelse break ;
424
+ }
414
425
try merger .prepare ();
415
426
416
427
try merge .target .data .build (self .data_dir , & merger );
@@ -422,8 +433,6 @@ fn finishFileSegmentMerge(self: *Self, merge: FileSegmentList.PreparedMerge) !vo
422
433
self .file_segments_lock .lock ();
423
434
defer self .file_segments_lock .unlock ();
424
435
425
- try self .file_segments_to_delete .ensureUnusedCapacity (3 );
426
-
427
436
errdefer self .file_segments .destroySegment (merge .target );
428
437
errdefer merge .target .data .delete (self .data_dir );
429
438
@@ -433,12 +442,14 @@ fn finishFileSegmentMerge(self: *Self, merge: FileSegmentList.PreparedMerge) !vo
433
442
var index1 : usize = 0 ;
434
443
var index2 : usize = 0 ;
435
444
445
+ std .debug .assert (merge .sources .num_segments == 2 );
446
+
436
447
var i : usize = 0 ;
437
448
while (i < ids .items .len ) : (i += 1 ) {
438
- if (SegmentID .eq (ids .items [i ], merge .sources .node1 .data .id )) {
449
+ if (SegmentID .eq (ids .items [i ], merge .sources .start .data .id )) {
439
450
index1 = i ;
440
451
}
441
- if (SegmentID .eq (ids .items [i ], merge .sources .node2 .data .id )) {
452
+ if (SegmentID .eq (ids .items [i ], merge .sources .end .data .id )) {
442
453
index2 = i ;
443
454
}
444
455
}
@@ -451,11 +462,12 @@ fn finishFileSegmentMerge(self: *Self, merge: FileSegmentList.PreparedMerge) !vo
451
462
452
463
try filefmt .writeIndexFile (self .data_dir , ids .items );
453
464
454
- defer self .file_segments .destroySegment (merge .sources .node1 );
455
- defer self .file_segments .destroySegment (merge .sources .node2 );
465
+ std .debug .assert (merge .sources .num_segments == 2 );
466
+ defer self .file_segments .destroySegment (merge .sources .start );
467
+ defer self .file_segments .destroySegment (merge .sources .end );
456
468
457
- defer merge .sources .node1 .data .delete (self .data_dir );
458
- defer merge .sources .node2 .data .delete (self .data_dir );
469
+ defer merge .sources .start .data .delete (self .data_dir );
470
+ defer merge .sources .end .data .delete (self .data_dir );
459
471
460
472
self .segments_lock .lock ();
461
473
defer self .segments_lock .unlock ();
0 commit comments