Skip to content

Commit aaf382b

Browse files
committed
Missing file
1 parent 2bcdece commit aaf382b

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

src/MemorySegment.zig

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
const std = @import("std");
2+
const log = std.log;
3+
4+
const common = @import("common.zig");
5+
const Item = common.Item;
6+
const SearchResults = common.SearchResults;
7+
const SegmentID = common.SegmentID;
8+
9+
const Change = @import("change.zig").Change;
10+
11+
const Deadline = @import("utils/Deadline.zig");
12+
13+
const segment_list = @import("segment_list.zig");
14+
pub const List = segment_list.SegmentList(Self);
15+
16+
const SegmentMerger = @import("segment_merger.zig").SegmentMerger;
17+
18+
const Self = @This();
19+
20+
allocator: std.mem.Allocator,
21+
id: SegmentID = .{ .version = 0, .included_merges = 0 },
22+
max_commit_id: u64 = 0,
23+
docs: std.AutoHashMap(u32, bool),
24+
items: std.ArrayList(Item),
25+
frozen: bool = false,
26+
27+
pub fn init(allocator: std.mem.Allocator) Self {
28+
return .{
29+
.allocator = allocator,
30+
.docs = std.AutoHashMap(u32, bool).init(allocator),
31+
.items = std.ArrayList(Item).init(allocator),
32+
};
33+
}
34+
35+
pub fn deinit(self: *Self) void {
36+
self.docs.deinit();
37+
self.items.deinit();
38+
}
39+
40+
pub fn search(self: *Self, sorted_hashes: []const u32, results: *SearchResults) !void {
41+
var items = self.items.items;
42+
for (sorted_hashes) |hash| {
43+
const matches = std.sort.equalRange(Item, Item{ .hash = hash, .id = 0 }, items, {}, Item.cmpByHash);
44+
for (matches[0]..matches[1]) |i| {
45+
try results.incr(items[i].id, self.id.version);
46+
}
47+
items = items[matches[1]..];
48+
}
49+
}
50+
51+
pub fn canBeMerged(self: Self) bool {
52+
return !self.frozen;
53+
}
54+
55+
pub fn getSize(self: Self) usize {
56+
return self.items.items.len;
57+
}
58+
59+
pub fn build(self: *Self, changes: []const Change) !void {
60+
var num_docs: u32 = 0;
61+
var num_items: usize = 0;
62+
for (changes) |change| {
63+
switch (change) {
64+
.insert => |op| {
65+
num_docs += 1;
66+
num_items += op.hashes.len;
67+
},
68+
.delete => {
69+
num_docs += 1;
70+
},
71+
}
72+
}
73+
74+
try self.docs.ensureTotalCapacity(num_docs);
75+
try self.items.ensureTotalCapacity(num_items);
76+
77+
var i = changes.len;
78+
while (i > 0) {
79+
i -= 1;
80+
const change = changes[i];
81+
switch (change) {
82+
.insert => |op| {
83+
const result = self.docs.getOrPutAssumeCapacity(op.id);
84+
if (!result.found_existing) {
85+
result.value_ptr.* = true;
86+
var items = self.items.addManyAsSliceAssumeCapacity(op.hashes.len);
87+
for (op.hashes, 0..) |hash, j| {
88+
items[j] = .{ .hash = hash, .id = op.id };
89+
}
90+
}
91+
},
92+
.delete => |op| {
93+
const result = self.docs.getOrPutAssumeCapacity(op.id);
94+
if (!result.found_existing) {
95+
result.value_ptr.* = false;
96+
}
97+
},
98+
}
99+
}
100+
101+
std.sort.pdq(Item, self.items.items, {}, Item.cmp);
102+
}
103+
104+
pub fn merge(self: *Self, source1: *Self, source2: *Self, collection: *List) !void {
105+
var merger = SegmentMerger(Self).init(self.allocator, collection);
106+
defer merger.deinit();
107+
108+
try merger.addSource(source1);
109+
try merger.addSource(source2);
110+
try merger.prepare();
111+
112+
self.id = merger.segment.id;
113+
self.max_commit_id = merger.segment.max_commit_id;
114+
115+
self.docs.deinit();
116+
self.docs = merger.segment.docs.move();
117+
118+
self.items.clearRetainingCapacity();
119+
try self.items.ensureTotalCapacity(merger.estimated_size);
120+
while (true) {
121+
const item = try merger.read() orelse break;
122+
try self.items.append(item);
123+
merger.advance();
124+
}
125+
}
126+
127+
pub fn reader(self: *const Self) Reader {
128+
return .{
129+
.segment = self,
130+
.index = 0,
131+
};
132+
}
133+
134+
pub const Reader = struct {
135+
segment: *const Self,
136+
index: usize,
137+
138+
pub fn close(self: *Reader) void {
139+
_ = self;
140+
}
141+
142+
pub fn read(self: *Reader) !?Item {
143+
if (self.index < self.segment.items.items.len) {
144+
return self.segment.items.items[self.index];
145+
} else {
146+
return null;
147+
}
148+
}
149+
150+
pub fn advance(self: *Reader) void {
151+
if (self.index < self.segment.items.items.len) {
152+
self.index += 1;
153+
}
154+
}
155+
};

0 commit comments

Comments
 (0)