Skip to content

Commit 2c7f06a

Browse files
committed
MultiIndex code cleanup
1 parent 23ae58b commit 2c7f06a

File tree

1 file changed

+74
-40
lines changed

1 file changed

+74
-40
lines changed

src/MultiIndex.zig

+74-40
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,45 @@ const Self = @This();
88

99
pub const IndexRef = struct {
1010
index: Index,
11+
name: []const u8,
1112
references: usize = 0,
1213
last_used_at: i64 = std.math.minInt(i64),
1314
is_open: bool = false,
1415
lock: std.Thread.Mutex = .{},
16+
17+
pub fn deinit(self: *IndexRef, allocator: std.mem.Allocator) void {
18+
allocator.free(self.name);
19+
self.index.deinit();
20+
}
21+
22+
pub fn incRef(self: *IndexRef) void {
23+
self.lock.lock();
24+
defer self.lock.unlock();
25+
26+
self.references += 1;
27+
self.last_used_at = std.time.milliTimestamp();
28+
}
29+
30+
pub fn decRef(self: *IndexRef) bool {
31+
self.lock.lock();
32+
defer self.lock.unlock();
33+
34+
assert(self.references > 0);
35+
self.references -= 1;
36+
self.last_used_at = std.time.timestamp();
37+
38+
return self.references == 0;
39+
}
40+
41+
pub fn ensureOpen(self: *IndexRef, create: bool) !void {
42+
self.lock.lock();
43+
defer self.lock.unlock();
44+
45+
if (self.is_open) return;
46+
47+
try self.index.open(create);
48+
self.is_open = true;
49+
}
1550
};
1651

1752
lock: std.Thread.Mutex = .{},
@@ -64,13 +99,32 @@ pub fn deinit(self: *Self) void {
6499
self.indexes.deinit();
65100
}
66101

67-
pub fn releaseIndex(self: *Self, index_data: *IndexRef) void {
68-
self.lock.lock();
69-
defer self.lock.unlock();
102+
fn deleteIndexFiles(self: *Self, name: []const u8) !void {
103+
const tmp_name = try std.mem.concat(self.allocator, u8, &[_][]const u8{ name, ".delete" });
104+
defer self.allocator.free(tmp_name);
105+
try self.dir.rename(name, tmp_name);
106+
try self.dir.deleteTree(tmp_name);
107+
}
108+
109+
fn removeIndex(self: *Self, name: []const u8) void {
110+
if (self.indexes.getEntry(name)) |entry| {
111+
entry.value_ptr.deinit(self.allocator);
112+
self.indexes.removeByPtr(entry.key_ptr);
113+
}
114+
}
70115

71-
assert(index_data.references > 0);
72-
index_data.references -= 1;
73-
index_data.last_used_at = std.time.timestamp();
116+
pub fn releaseIndex(self: *Self, index_ref: *IndexRef) void {
117+
if (index_ref.decRef()) {
118+
self.lock.lock();
119+
defer self.lock.unlock();
120+
121+
index_ref.lock.lock();
122+
defer index_ref.lock.unlock();
123+
124+
if (!index_ref.is_open) {
125+
self.removeIndex(index_ref.name);
126+
}
127+
}
74128
}
75129

76130
pub fn acquireIndex(self: *Self, name: []const u8) !*IndexRef {
@@ -83,53 +137,38 @@ pub fn acquireIndex(self: *Self, name: []const u8) !*IndexRef {
83137

84138
var result = try self.indexes.getOrPutAdapted(name, self.indexes.ctx);
85139
if (result.found_existing) {
86-
result.value_ptr.references += 1;
87-
result.value_ptr.last_used_at = std.time.timestamp();
140+
result.value_ptr.incRef();
88141
return result.value_ptr;
89142
}
90-
91143
errdefer self.indexes.removeByPtr(result.key_ptr);
92144

93145
result.key_ptr.* = try self.allocator.dupe(u8, name);
94146
errdefer self.allocator.free(result.key_ptr.*);
95147

96-
result.value_ptr.index = try Index.init(self.allocator, self.dir, name, .{});
148+
result.value_ptr.* = .{
149+
.index = try Index.init(self.allocator, self.dir, name, .{}),
150+
.name = result.key_ptr.*,
151+
};
97152
errdefer result.value_ptr.index.deinit();
98153

99-
result.value_ptr.is_open = false;
100-
result.value_ptr.references = 1;
101-
result.value_ptr.last_used_at = std.time.timestamp();
154+
result.value_ptr.incRef();
102155
return result.value_ptr;
103156
}
104157

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-
115158
pub fn getIndex(self: *Self, name: []const u8) !*IndexRef {
116-
if (!isValidName(name)) {
117-
return error.InvalidIndexName;
118-
}
119-
120159
const index_ref = try self.acquireIndex(name);
121-
try ensureOpen(index_ref, false);
160+
errdefer self.releaseIndex(index_ref);
161+
162+
try index_ref.ensureOpen(false);
163+
122164
return index_ref;
123165
}
124166

125167
pub fn createIndex(self: *Self, name: []const u8) !void {
126-
if (!isValidName(name)) {
127-
return error.InvalidIndexName;
128-
}
129-
130168
const index_ref = try self.acquireIndex(name);
131-
try ensureOpen(index_ref, true);
132169
defer self.releaseIndex(index_ref);
170+
171+
try index_ref.ensureOpen(true);
133172
}
134173

135174
pub fn deleteIndex(self: *Self, name: []const u8) !void {
@@ -140,11 +179,6 @@ pub fn deleteIndex(self: *Self, name: []const u8) !void {
140179
self.lock.lock();
141180
defer self.lock.unlock();
142181

143-
if (self.indexes.getEntry(name)) |entry| {
144-
self.allocator.free(entry.key_ptr.*);
145-
entry.value_ptr.index.deinit();
146-
self.indexes.removeByPtr(entry.key_ptr);
147-
}
148-
149-
try self.dir.deleteTree(name);
182+
self.removeIndex(name);
183+
try self.deleteIndexFiles(name);
150184
}

0 commit comments

Comments
 (0)