index/db/commands: fold duplicated index logic into single definitions
Cleanup pass over the secondary-index feature. add_doc is now the one entry-commit path. create_index and build_all_indexes each hand-rolled build -> check_unique -> reserve -> insert, and had already drifted on whether multikey is set before or after the unique check; add_doc gained an enforce_unique flag so the rebuild path keeps its tolerate-and-warn behavior. reserve_for and insert_entries are now the only way the engine touches Index.entries. One definition each for: prefix comparison and the prefix binary searches (prefix_order + std.sort), the cartesian-product odometer (advance_choice), the spec pair list (write_spec builds on spec_pairs, so the log format and the listIndexes reply share one schema), the _id clause parser (plan_id reuses analyze_clause), key-pattern direction (index.descending, which desc_dir already disagreed with on non-numeric values), option truthiness (query.truthy), the E11000 message, and index-removal-by-name (Collection.find_index/remove_index). Key-pattern matching moved out of the dispatcher into index.find_by_key_pattern. Dead or redundant: ParallelArraysError, the unread `dropped` counter, insert_entries' discarded gpa, a third pass computing multikey, the has_id/is_id_index flag pair, Plan.key_len (always lookup_keys[0].len, now a method), first_match_consumed (now stages = stages[1..]). Cheaper hot paths: remove_id compacts in one pass instead of an orderedRemove per hit; Plan.search skips the sort/dedupe when neither multikey nor multiple lookup keys can produce a repeat; the _id fast path reuses one scratch key buffer (bson.write_serialized_value); the plan loop uses the bound collection instead of re-resolving it through two hash lookups per candidate. Behavior is unchanged except that dropping plan_id's fixed 16-clause buffer enables the _id fast path on filters that previously exceeded it.
This commit is contained in:
11
src/bson.zig
11
src/bson.zig
@@ -458,11 +458,18 @@ fn write_array(items: []const Value, gpa: std.mem.Allocator, out: *std.ArrayList
|
||||
pub fn serialize_value(gpa: std.mem.Allocator, v: Value) ![]u8 {
|
||||
var out: std.ArrayListUnmanaged(u8) = .empty;
|
||||
errdefer out.deinit(gpa);
|
||||
try out.append(gpa, v.type_tag());
|
||||
try write_value(v, gpa, &out);
|
||||
try write_serialized_value(v, gpa, &out);
|
||||
return out.toOwnedSlice(gpa);
|
||||
}
|
||||
|
||||
/// Append the serialized-key bytes of `v` (type tag + payload) to `out`. The
|
||||
/// appending form of serialize_value, for callers reusing one scratch buffer
|
||||
/// across many keys.
|
||||
pub fn write_serialized_value(v: Value, gpa: std.mem.Allocator, out: *std.ArrayListUnmanaged(u8)) !void {
|
||||
try out.append(gpa, v.type_tag());
|
||||
try write_value(v, gpa, out);
|
||||
}
|
||||
|
||||
/// Deep-copy a value into `arena`, so the copy is self-contained.
|
||||
pub fn copy_value(arena: std.mem.Allocator, v: Value) std.mem.Allocator.Error!Value {
|
||||
return switch (v) {
|
||||
|
||||
Reference in New Issue
Block a user