@@ -22,51 +22,25 @@ pub const Declaration = struct {
2222 range : offsets.Range ,
2323};
2424
25- pub const empty : TrigramStore = .{
26- .has_filter = false ,
27- .filter_buckets = .empty ,
28- .trigram_to_declarations = .empty ,
29- .declarations = .empty ,
30- .names = .empty ,
31- };
32-
3325has_filter : bool ,
3426filter_buckets : std .ArrayListUnmanaged (CuckooFilter .Bucket ),
3527trigram_to_declarations : std .AutoArrayHashMapUnmanaged (Trigram , std .ArrayListUnmanaged (Declaration .Index )),
3628declarations : std .MultiArrayList (Declaration ),
3729names : std .ArrayListUnmanaged (u8 ),
3830
39- pub fn deinit (store : * TrigramStore , allocator : std.mem.Allocator ) void {
40- store .filter_buckets .deinit (allocator );
41- for (store .trigram_to_declarations .values ()) | * list | {
42- list .deinit (allocator );
43- }
44- store .trigram_to_declarations .deinit (allocator );
45- store .declarations .deinit (allocator );
46- store .names .deinit (allocator );
47- store .* = undefined ;
48- }
49-
50- fn clearRetainingCapacity (store : * TrigramStore ) void {
51- store .filter_buckets .clearRetainingCapacity ();
52- store .has_filter = false ;
53- for (store .trigram_to_declarations .values ()) | * list | {
54- list .clearRetainingCapacity ();
55- }
56- store .declarations .clearRetainingCapacity ();
57- store .names .clearRetainingCapacity ();
58- }
59-
60- pub fn fill (
61- store : * TrigramStore ,
31+ pub fn init (
6232 allocator : std.mem.Allocator ,
63- source : [: 0 ] const u8 ,
33+ tree : Ast ,
6434 encoding : offsets.Encoding ,
65- ) error {OutOfMemory }! void {
66- store .clearRetainingCapacity ();
67-
68- var tree = try Ast .parse (allocator , source , .zig );
69- defer tree .deinit (allocator );
35+ ) error {OutOfMemory }! TrigramStore {
36+ var store : TrigramStore = .{
37+ .has_filter = false ,
38+ .filter_buckets = .empty ,
39+ .trigram_to_declarations = .empty ,
40+ .declarations = .empty ,
41+ .names = .empty ,
42+ };
43+ errdefer store .deinit (allocator );
7044
7145 const Context = struct {
7246 allocator : std.mem.Allocator ,
@@ -126,15 +100,61 @@ pub fn fill(
126100 }
127101 };
128102
129- var context = Context {
103+ var context : Context = . {
130104 .allocator = allocator ,
131- .store = store ,
105+ .store = & store ,
132106 .in_function = false ,
133107 .encoding = encoding ,
134108 };
135109 try ast .iterateChildren (tree , .root , & context , Context .Error , Context .callback );
136110
137- try store .finalize (allocator );
111+ const lists = store .trigram_to_declarations .values ();
112+ var index : usize = 0 ;
113+ while (index < lists .len ) {
114+ if (lists [index ].items .len == 0 ) {
115+ lists [index ].deinit (allocator );
116+ store .trigram_to_declarations .swapRemoveAt (index );
117+ } else {
118+ index += 1 ;
119+ }
120+ }
121+
122+ const trigrams = store .trigram_to_declarations .keys ();
123+
124+ if (trigrams .len > 0 ) {
125+ var prng = std .Random .DefaultPrng .init (0 );
126+
127+ const filter_capacity = CuckooFilter .capacityForCount (store .trigram_to_declarations .count ()) catch unreachable ;
128+ try store .filter_buckets .ensureTotalCapacityPrecise (allocator , filter_capacity );
129+ store .filter_buckets .items .len = filter_capacity ;
130+
131+ const filter : CuckooFilter = .{ .buckets = store .filter_buckets .items };
132+ filter .reset ();
133+ store .has_filter = true ;
134+
135+ for (trigrams ) | trigram | {
136+ filter .append (prng .random (), trigram ) catch | err | switch (err ) {
137+ error .EvictionFailed = > {
138+ // NOTE: This should generally be quite rare.
139+ store .has_filter = false ;
140+ break ;
141+ },
142+ };
143+ }
144+ }
145+
146+ return store ;
147+ }
148+
149+ pub fn deinit (store : * TrigramStore , allocator : std.mem.Allocator ) void {
150+ store .filter_buckets .deinit (allocator );
151+ for (store .trigram_to_declarations .values ()) | * list | {
152+ list .deinit (allocator );
153+ }
154+ store .trigram_to_declarations .deinit (allocator );
155+ store .declarations .deinit (allocator );
156+ store .names .deinit (allocator );
157+ store .* = undefined ;
138158}
139159
140160/// Caller must not submit name.len < 3.
@@ -167,53 +187,15 @@ fn appendDeclaration(
167187 }
168188}
169189
170- /// Must be called before any queries are executed.
171- fn finalize (store : * TrigramStore , allocator : std.mem.Allocator ) error {OutOfMemory }! void {
172- {
173- const lists = store .trigram_to_declarations .values ();
174- var index : usize = 0 ;
175- while (index < lists .len ) {
176- if (lists [index ].items .len == 0 ) {
177- lists [index ].deinit (allocator );
178- store .trigram_to_declarations .swapRemoveAt (index );
179- } else {
180- index += 1 ;
181- }
182- }
183- }
184-
185- const trigrams = store .trigram_to_declarations .keys ();
186-
187- if (trigrams .len > 0 ) {
188- var prng = std .Random .DefaultPrng .init (0 );
189-
190- const filter_capacity = CuckooFilter .capacityForCount (store .trigram_to_declarations .count ()) catch unreachable ;
191- try store .filter_buckets .ensureTotalCapacityPrecise (allocator , filter_capacity );
192- store .filter_buckets .items .len = filter_capacity ;
193-
194- const filter : CuckooFilter = .{ .buckets = store .filter_buckets .items };
195- filter .reset ();
196- store .has_filter = true ;
197-
198- for (trigrams ) | trigram | {
199- filter .append (prng .random (), trigram ) catch | err | switch (err ) {
200- error .EvictionFailed = > {
201- // NOTE: This should generally be quite rare.
202- store .has_filter = false ;
203- break ;
204- },
205- };
206- }
207- }
208- }
209-
190+ /// Asserts query.len >= 3. Asserts declaration_buffer.items.len == 0.
210191pub fn declarationsForQuery (
211192 store : * const TrigramStore ,
212193 allocator : std.mem.Allocator ,
213194 query : []const u8 ,
214195 declaration_buffer : * std .ArrayListUnmanaged (Declaration.Index ),
215196) error {OutOfMemory }! void {
216197 assert (query .len >= 3 );
198+ assert (declaration_buffer .items .len == 0 );
217199
218200 const filter : CuckooFilter = .{ .buckets = store .filter_buckets .items };
219201
@@ -226,14 +208,9 @@ pub fn declarationsForQuery(
226208 }
227209 }
228210
229- const first = (store .trigram_to_declarations .get (query [0.. 3].* ) orelse {
230- declaration_buffer .clearRetainingCapacity ();
231- return ;
232- }).items ;
211+ const first = (store .trigram_to_declarations .get (query [0.. 3].* ) orelse return ).items ;
233212
234- declaration_buffer .clearRetainingCapacity ();
235- try declaration_buffer .ensureTotalCapacity (allocator , first .len * 2 );
236- declaration_buffer .items .len = first .len * 2 ;
213+ try declaration_buffer .resize (allocator , first .len * 2 );
237214
238215 var len = first .len ;
239216 @memcpy (declaration_buffer .items [0.. len ], first );
@@ -242,18 +219,18 @@ pub fn declarationsForQuery(
242219 const trigram = query [index .. ][0.. 3].* ;
243220 const old_len = len ;
244221 len = mergeIntersection (
245- (store .trigram_to_declarations .get (trigram [0.. 3].* ) orelse return {
222+ (store .trigram_to_declarations .get (trigram [0.. 3].* ) orelse {
246223 declaration_buffer .clearRetainingCapacity ();
247224 return ;
248225 }).items ,
249226 declaration_buffer .items [0.. len ],
250227 declaration_buffer .items [len .. ],
251228 );
252229 @memcpy (declaration_buffer .items [0.. len ], declaration_buffer .items [old_len .. ][0.. len ]);
253- declaration_buffer .items . len = len * 2 ;
230+ declaration_buffer .shrinkRetainingCapacity ( len * 2 ) ;
254231 }
255232
256- declaration_buffer .items . len = declaration_buffer .items .len / 2 ;
233+ declaration_buffer .shrinkRetainingCapacity ( declaration_buffer .items .len / 2 ) ;
257234}
258235
259236/// Asserts `@min(a.len, b.len) <= out.len`.
0 commit comments