Skip to content

Commit 23ae58b

Browse files
committed
Open indexes outside of the main MultiIndex lock
1 parent 2be9078 commit 23ae58b

File tree

3 files changed

+37
-24
lines changed

3 files changed

+37
-24
lines changed

src/Index.zig

+4-5
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ const metrics = @import("metrics.zig");
3535
const Self = @This();
3636

3737
const Options = struct {
38-
create: bool = false,
3938
min_segment_size: usize = 500_000,
4039
max_segment_size: usize = 500_000_000,
4140
};
@@ -151,13 +150,13 @@ fn loadSegment(self: *Self, info: SegmentInfo) !FileSegmentNode {
151150
return node;
152151
}
153152

154-
fn loadSegments(self: *Self) !u64 {
153+
fn loadSegments(self: *Self, create: bool) !u64 {
155154
self.segments_lock.lock();
156155
defer self.segments_lock.unlock();
157156

158157
const segment_ids = filefmt.readManifestFile(self.dir, self.allocator) catch |err| {
159158
if (err == error.FileNotFound) {
160-
if (self.options.create) {
159+
if (create) {
161160
try self.updateManifestFile(self.file_segments.segments.value);
162161
return 0;
163162
}
@@ -362,8 +361,8 @@ fn stopMemorySegmentMergeThread(self: *Self) void {
362361
self.memory_segment_merge_thread = null;
363362
}
364363

365-
pub fn open(self: *Self) !void {
366-
const last_commit_id = try self.loadSegments();
364+
pub fn open(self: *Self, create: bool) !void {
365+
const last_commit_id = try self.loadSegments(create);
367366

368367
// start these threads after loading file segments, but before replaying oplog to memory segments
369368
try self.startFileSegmentMergeThread();

src/MultiIndex.zig

+20-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ pub const IndexRef = struct {
1010
index: Index,
1111
references: usize = 0,
1212
last_used_at: i64 = std.math.minInt(i64),
13+
is_open: bool = false,
14+
lock: std.Thread.Mutex = .{},
1315
};
1416

1517
lock: std.Thread.Mutex = .{},
@@ -71,7 +73,7 @@ pub fn releaseIndex(self: *Self, index_data: *IndexRef) void {
7173
index_data.last_used_at = std.time.timestamp();
7274
}
7375

74-
pub fn acquireIndex(self: *Self, name: []const u8, create: bool) !*IndexRef {
76+
pub fn acquireIndex(self: *Self, name: []const u8) !*IndexRef {
7577
if (!isValidName(name)) {
7678
return error.InvalidIndexName;
7779
}
@@ -91,30 +93,42 @@ pub fn acquireIndex(self: *Self, name: []const u8, create: bool) !*IndexRef {
9193
result.key_ptr.* = try self.allocator.dupe(u8, name);
9294
errdefer self.allocator.free(result.key_ptr.*);
9395

94-
result.value_ptr.index = try Index.init(self.allocator, self.dir, name, .{ .create = create });
96+
result.value_ptr.index = try Index.init(self.allocator, self.dir, name, .{});
9597
errdefer result.value_ptr.index.deinit();
9698

97-
try result.value_ptr.index.open();
98-
99+
result.value_ptr.is_open = false;
99100
result.value_ptr.references = 1;
100101
result.value_ptr.last_used_at = std.time.timestamp();
101102
return result.value_ptr;
102103
}
103104

105+
fn ensureOpen(index_ref: *IndexRef, create: bool) !void {
106+
index_ref.lock.lock();
107+
defer index_ref.lock.unlock();
108+
109+
if (index_ref.is_open) return;
110+
111+
try index_ref.index.open(create);
112+
index_ref.is_open = true;
113+
}
114+
104115
pub fn getIndex(self: *Self, name: []const u8) !*IndexRef {
105116
if (!isValidName(name)) {
106117
return error.InvalidIndexName;
107118
}
108119

109-
return try self.acquireIndex(name, false);
120+
const index_ref = try self.acquireIndex(name);
121+
try ensureOpen(index_ref, false);
122+
return index_ref;
110123
}
111124

112125
pub fn createIndex(self: *Self, name: []const u8) !void {
113126
if (!isValidName(name)) {
114127
return error.InvalidIndexName;
115128
}
116129

117-
const index_ref = try self.acquireIndex(name, true);
130+
const index_ref = try self.acquireIndex(name);
131+
try ensureOpen(index_ref, true);
118132
defer self.releaseIndex(index_ref);
119133
}
120134

src/index_tests.zig

+13-13
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,18 @@ test "index does not exist" {
2222
var index = try Index.init(std.testing.allocator, tmp_dir.dir, "idx", .{});
2323
defer index.deinit();
2424

25-
const result = index.open();
25+
const result = index.open(false);
2626
try std.testing.expectError(error.IndexNotFound, result);
2727
}
2828

2929
test "index create, update and search" {
3030
var tmp_dir = std.testing.tmpDir(.{});
3131
defer tmp_dir.cleanup();
3232

33-
var index = try Index.init(std.testing.allocator, tmp_dir.dir, "idx", .{ .create = true });
33+
var index = try Index.init(std.testing.allocator, tmp_dir.dir, "idx", .{});
3434
defer index.deinit();
3535

36-
try index.open();
36+
try index.open(true);
3737

3838
var hashes: [100]u32 = undefined;
3939

@@ -69,10 +69,10 @@ test "index create, update, reopen and search" {
6969
var hashes: [100]u32 = undefined;
7070

7171
{
72-
var index = try Index.init(std.testing.allocator, tmp_dir.dir, "idx", .{ .create = true });
72+
var index = try Index.init(std.testing.allocator, tmp_dir.dir, "idx", .{});
7373
defer index.deinit();
7474

75-
try index.open();
75+
try index.open(true);
7676

7777
try index.update(&[_]Change{.{ .insert = .{
7878
.id = 1,
@@ -81,10 +81,10 @@ test "index create, update, reopen and search" {
8181
}
8282

8383
{
84-
var index = try Index.init(std.testing.allocator, tmp_dir.dir, "idx", .{ .create = false });
84+
var index = try Index.init(std.testing.allocator, tmp_dir.dir, "idx", .{});
8585
defer index.deinit();
8686

87-
try index.open();
87+
try index.open(false);
8888

8989
var results = try index.search(generateRandomHashes(&hashes, 1), std.testing.allocator, .{});
9090
defer results.deinit();
@@ -105,10 +105,10 @@ test "index many updates" {
105105
var hashes: [100]u32 = undefined;
106106

107107
{
108-
var index = try Index.init(std.testing.allocator, tmp_dir.dir, "idx", .{ .create = true });
108+
var index = try Index.init(std.testing.allocator, tmp_dir.dir, "idx", .{});
109109
defer index.deinit();
110110

111-
try index.open();
111+
try index.open(true);
112112

113113
for (0..100) |i| {
114114
try index.update(&[_]Change{.{ .insert = .{
@@ -118,10 +118,10 @@ test "index many updates" {
118118
}
119119
}
120120

121-
var index = try Index.init(std.testing.allocator, tmp_dir.dir, "idx", .{ .create = false });
121+
var index = try Index.init(std.testing.allocator, tmp_dir.dir, "idx", .{});
122122
defer index.deinit();
123123

124-
try index.open();
124+
try index.open(false);
125125

126126
{
127127
var results = try index.search(generateRandomHashes(&hashes, 0), std.testing.allocator, .{});
@@ -146,10 +146,10 @@ test "index, multiple fingerprints with the same hashes" {
146146
var tmp_dir = std.testing.tmpDir(.{});
147147
defer tmp_dir.cleanup();
148148

149-
var index = try Index.init(std.testing.allocator, tmp_dir.dir, "idx", .{ .create = true });
149+
var index = try Index.init(std.testing.allocator, tmp_dir.dir, "idx", .{});
150150
defer index.deinit();
151151

152-
try index.open();
152+
try index.open(true);
153153

154154
var hashes: [100]u32 = undefined;
155155

0 commit comments

Comments
 (0)