@@ -24,6 +24,7 @@ const FileSegment = @import("FileSegment.zig");
24
24
const FileSegmentList = SegmentList (FileSegment );
25
25
const FileSegmentNode = FileSegmentList .Node ;
26
26
27
+ const IndexReader = @import ("IndexReader.zig" );
27
28
const SharedPtr = @import ("utils/shared_ptr.zig" ).SharedPtr ;
28
29
29
30
const SegmentMerger = @import ("segment_merger.zig" ).SegmentMerger ;
@@ -180,8 +181,8 @@ fn loadSegments(self: *Self, create: bool) !u64 {
180
181
}
181
182
182
183
fn doCheckpoint (self : * Self ) ! bool {
183
- var snapshot = self .acquireSegments ();
184
- defer self .releaseSegments (& snapshot );
184
+ var snapshot = self .acquireReader ();
185
+ defer self .releaseReader (& snapshot );
185
186
186
187
const source = snapshot .memory_segments .value .getFirst () orelse return false ;
187
188
if (source .value .getSize () < self .options .min_segment_size ) {
@@ -432,117 +433,26 @@ pub fn updateInternal(self: *Self, changes: []const Change, commit_id: ?u64) !vo
432
433
}
433
434
}
434
435
435
- const SegmentsSnapshot = struct {
436
- file_segments : SharedPtr (FileSegmentList ),
437
- memory_segments : SharedPtr (MemorySegmentList ),
438
- };
439
-
440
- // Get the current segments lists and make sure they won't get deleted.
441
- fn acquireSegments (self : * Self ) SegmentsSnapshot {
436
+ pub fn acquireReader (self : * Self ) IndexReader {
442
437
self .segments_lock .lockShared ();
443
438
defer self .segments_lock .unlockShared ();
444
439
445
- return . {
440
+ return IndexReader {
446
441
.file_segments = self .file_segments .segments .acquire (),
447
442
.memory_segments = self .memory_segments .segments .acquire (),
448
443
};
449
444
}
450
445
451
- // Release the previously acquired segments lists, they will get deleted if no longer needed.
452
- fn releaseSegments (self : * Self , segments : * SegmentsSnapshot ) void {
453
- MemorySegmentList .destroySegments (self .allocator , & segments .memory_segments );
454
- FileSegmentList .destroySegments (self .allocator , & segments .file_segments );
446
+ pub fn releaseReader (self : * Self , reader : * IndexReader ) void {
447
+ MemorySegmentList .destroySegments (self .allocator , & reader .memory_segments );
448
+ FileSegmentList .destroySegments (self .allocator , & reader .file_segments );
455
449
}
456
450
457
- const segment_lists = [_ ][]const u8 {
458
- "file_segments" ,
459
- "memory_segments" ,
460
- };
461
-
462
451
pub fn search (self : * Self , hashes : []const u32 , allocator : std.mem.Allocator , deadline : Deadline ) ! SearchResults {
463
- const sorted_hashes = try allocator .dupe (u32 , hashes );
464
- defer allocator .free (sorted_hashes );
465
- std .sort .pdq (u32 , sorted_hashes , {}, std .sort .asc (u32 ));
466
-
467
- var results = SearchResults .init (allocator );
468
- errdefer results .deinit ();
469
-
470
- var snapshot = self .acquireSegments ();
471
- defer self .releaseSegments (& snapshot ); // FIXME this possibly deletes orphaned segments, do it in a separate thread
472
-
473
- inline for (segment_lists ) | n | {
474
- const segments = @field (snapshot , n );
475
- try segments .value .search (sorted_hashes , & results , deadline );
476
- }
477
-
478
- results .sort ();
479
-
480
- return results ;
481
- }
482
-
483
- pub fn getDocInfo (self : * Self , doc_id : u32 ) ! ? DocInfo {
484
- var snapshot = self .acquireSegments ();
485
- defer self .releaseSegments (& snapshot ); // FIXME this possibly deletes orphaned segments, do it in a separate thread
486
-
487
- var result : ? DocInfo = null ;
488
- inline for (segment_lists ) | n | {
489
- const segments = @field (snapshot , n );
490
- if (segments .value .getDocInfo (doc_id )) | res | {
491
- result = res ;
492
- }
493
- }
494
- if (result ) | res | {
495
- if (! res .deleted ) {
496
- return res ;
497
- }
498
- }
499
- return null ;
500
- }
452
+ var reader = self .acquireReader ();
453
+ defer self .releaseReader (& reader );
501
454
502
- pub const IndexInfo = struct {
503
- version : u64 ,
504
- attributes : std .StringHashMapUnmanaged (u64 ),
505
-
506
- pub fn deinit (self : * IndexInfo , allocator : std.mem.Allocator ) void {
507
- self .attributes .deinit (allocator );
508
- }
509
- };
510
-
511
- pub fn getInfo (self : * Self , allocator : std.mem.Allocator ) ! IndexInfo {
512
- var snapshot = self .acquireSegments ();
513
- defer self .releaseSegments (& snapshot ); // FIXME this possibly deletes orphaned segments, do it in a separate thread
514
-
515
- var attributes : std .StringHashMapUnmanaged (u64 ) = .{};
516
- errdefer {
517
- var iter = attributes .iterator ();
518
- while (iter .next ()) | e | {
519
- allocator .free (e .key_ptr .* );
520
- }
521
- attributes .deinit (allocator );
522
- }
523
-
524
- var version : u64 = 0 ;
525
- inline for (segment_lists ) | n | {
526
- const segments = @field (snapshot , n );
527
- for (segments .value .nodes .items ) | node | {
528
- var iter = node .value .attributes .iterator ();
529
- while (iter .next ()) | entry | {
530
- const result = try attributes .getOrPut (allocator , entry .key_ptr .* );
531
- if (! result .found_existing ) {
532
- errdefer attributes .removeByPtr (entry .key_ptr );
533
- result .key_ptr .* = try allocator .dupe (u8 , entry .key_ptr .* );
534
- }
535
- result .value_ptr .* = entry .value_ptr .* ;
536
- }
537
- std .debug .assert (node .value .info .version > version );
538
- version = node .value .info .version ;
539
- }
540
- }
541
-
542
- return .{
543
- .version = version ,
544
- .attributes = attributes ,
545
- };
455
+ return reader .search (hashes , allocator , deadline );
546
456
}
547
457
548
458
test {
0 commit comments