Skip to documentation
SLOP

tiny.sql.search.vbyte

Reference tiny.sql search vbyte

Defined in search.

API (17)

Actions

Public operations.

Types and contracts

Public types and contracts.

Values and defaults

Public values and defaults.

No direct callersNo direct callssearchvbyte
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallssearch.vbytedecodesearch.vbyte.DecoderinitValidatedsearch.vbytecontrolByteCountprivate sourcelib.sql.src.search.vbytecontrolDataByteCountsearch.vbyte.Decoderinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.sql.src.search.posting.SegmentDecoderresetsearch.vbyte.Decoderinitsearch.vbytecontrolByteCountsearch.vbyte.DecoderinitValidated
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallssearch.vbyte.DecodernextBlocksearch.vbytedecodeprivate sourcelib.sql.src.search.vbytereadValuesearch.vbyte.Decodernext
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.sql.src.search.posting.SegmentDecoderloadBlocksearch.vbyte.Decodernextsearch.vbyte.DecodernextBlock
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.sql.src.search.postingstreamPostingSegmentPayloadsearch.vbyteencodesearch.vbytevalueByteCountprivate sourcelib.sql.src.search.vbytewriteValuesearch.vbyte.Encoderappend
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.sql.src.search.postingstreamPostingSegmentPayloadsearch.vbyteencodesearch.vbyte.Encoderfinish
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.sql.src.search.postingstreamPostingSegmentPayloadsearch.vbyteencodesearch.vbytecontrolByteCountsearch.vbyte.Encoderinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.sql.src.search.postingsegmentPayloadCountprivate sourcelib.sql.src.search.postingstreamPostingSegmentPayloadSizetest sourcelib.sql.src.search.postingtest: search Stream VByte segment rej...search.vbyte.Decoderinitsearch.vbyte.DecoderinitValidated+2 moresearch.vbytecontrolByteCount
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.sql.src.search.vbytetest: Stream VByte 8afe869 format fix...test sourcelib.sql.src.search.vbytetest: Stream VByte preserves byte-wid...test sourcelib.sql.src.search.vbytetest: Stream VByte rejects malformed ...search.vbyte.Decoderinitsearch.vbyte.Decodernextsearch.vbytedecode
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.sql.src.search.vbytetest: Stream VByte 8afe869 format fix...test sourcelib.sql.src.search.vbytetest: Stream VByte preserves byte-wid...test sourcelib.sql.src.search.vbytetest: Stream VByte rejects malformed ...search.vbyte.Encoderappendsearch.vbyte.Encoderfinishsearch.vbyte.Encoderinitsearch.vbyteencodedSizesearch.vbyteencode
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallssearch.vbyteencodesearch.vbytecontrolByteCountsearch.vbytevalueByteCountsearch.vbyteencodedSize
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.sql.src.search.postingstreamPostingSegmentPayloadSizesearch.vbyte.Encoderappendsearch.vbyteencodedSizeprivate sourcelib.sql.src.search.vbytewriteValuesearch.vbytevalueByteCount
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/sql/src/search/root.zig:9

zig
pub const vbyte = @import("vbyte.zig");

Source: lib/sql/src/search/vbyte.zig

zig
const std = @import("std");pub const upstream_revision = "8afe8693964b33abb06b3b6b48fad4d33693a241";pub const upstream_source = "https://github.com/fast-pack/streamvbyte";pub const Error = error{    InvalidSearchIndex,    OutputTooSmall,};pub const Decoder = struct {    input: []const u8 = &.{},    value_count: usize = 0,    value_index: usize = 0,    data_offset: usize = 0,    pub fn init(input: []const u8, value_count: usize) Error!Decoder {        const control_count = controlByteCount(value_count);        if (input.len < control_count) return error.InvalidSearchIndex;        _ = std.math.mul(usize, value_count, 4) catch return error.InvalidSearchIndex;        var data_count: usize = 0;        const full_control_count = value_count / 4;        for (input[0..full_control_count]) |control| data_count += controlDataByteCount(control);        const remaining = value_count % 4;        if (remaining != 0) {            const control = input[full_control_count];            if (control >> @intCast(remaining * 2) != 0) return error.InvalidSearchIndex;            for (0..remaining) |index| data_count += @as(usize, (control >> @intCast(index * 2)) & 0x3) + 1;        }        const encoded_count = std.math.add(usize, control_count, data_count) catch return error.InvalidSearchIndex;        if (encoded_count != input.len) return error.InvalidSearchIndex;        return initValidated(input, value_count);    }    pub fn initValidated(input: []const u8, value_count: usize) Decoder {        return .{            .input = input,            .value_count = value_count,            .data_offset = controlByteCount(value_count),        };    }    pub fn next(self: *Decoder) Error!?u32 {        if (self.value_index >= self.value_count) return null;        const control = self.input[self.value_index / 4];        const shift: u3 = @intCast((self.value_index % 4) * 2);        const code = (control >> shift) & 0x3;        const value = try readValue(self.input, &self.data_offset, code);        self.value_index += 1;        return value;    }    pub fn nextBlock(self: *Decoder, output: *[4]u32, count: usize) Error!void {        if (count == 0 or count > 4 or self.value_index % 4 != 0 or count > self.value_count - self.value_index) return error.InvalidSearchIndex;        const control = self.input[self.value_index / 4];        if (control == 0) {            const end = std.math.add(usize, self.data_offset, count) catch return error.InvalidSearchIndex;            if (end > self.input.len) return error.InvalidSearchIndex;            for (0..count) |index| output[index] = self.input[self.data_offset + index];            self.data_offset = end;            self.value_index += count;            return;        }        for (0..count) |index| output[index] = (try self.next()) orelse return error.InvalidSearchIndex;    }};pub const Encoder = struct {    output: []u8,    value_count: usize,    value_index: usize = 0,    data_offset: usize,    pub fn init(output: []u8, value_count: usize) Error!Encoder {        const control_count = controlByteCount(value_count);        if (output.len < control_count) return error.OutputTooSmall;        @memset(output[0..control_count], 0);        return .{            .output = output,            .value_count = value_count,            .data_offset = control_count,        };    }    pub fn append(self: *Encoder, value: u32) Error!void {        if (self.value_index >= self.value_count) return error.InvalidSearchIndex;        const byte_count = valueByteCount(value);        const end = std.math.add(usize, self.data_offset, byte_count) catch return error.OutputTooSmall;        if (end > self.output.len) return error.OutputTooSmall;        const shift: u3 = @intCast((self.value_index % 4) * 2);        self.output[self.value_index / 4] |= @as(u8, @intCast(byte_count - 1)) << shift;        writeValue(self.output[self.data_offset..end], value);        self.data_offset = end;        self.value_index += 1;    }    pub fn finish(self: *const Encoder) Error!void {        if (self.value_index != self.value_count or self.data_offset != self.output.len) return error.InvalidSearchIndex;    }};pub fn controlByteCount(value_count: usize) usize {    return value_count / 4 + @intFromBool(value_count % 4 != 0);}pub fn encodedSize(values: []const u32) ?usize {    var size = controlByteCount(values.len);    for (values) |value| size = std.math.add(usize, size, valueByteCount(value)) catch return null;    return size;}pub fn encode(target: []u8, values: []const u32) Error![]const u8 {    const encoded_size = encodedSize(values) orelse return error.InvalidSearchIndex;    if (target.len < encoded_size) return error.OutputTooSmall;    var encoder = try Encoder.init(target[0..encoded_size], values.len);    for (values) |value| try encoder.append(value);    try encoder.finish();    return target[0..encoded_size];}pub fn decode(target: []u32, input: []const u8) Error!void {    var decoder = try Decoder.init(input, target.len);    for (target) |*value| value.* = (try decoder.next()) orelse return error.InvalidSearchIndex;    if (try decoder.next() != null) return error.InvalidSearchIndex;}pub fn valueByteCount(value: u32) usize {    return 1 + @as(usize, @intFromBool(value > 0xff)) + @as(usize, @intFromBool(value > 0xffff)) + @as(usize, @intFromBool(value > 0xff_ffff));}fn controlDataByteCount(control: u8) usize {    return 4 + @as(usize, control & 0x3) + @as(usize, (control >> 2) & 0x3) + @as(usize, (control >> 4) & 0x3) + @as(usize, control >> 6);}fn writeValue(target: []u8, value: u32) void {    std.debug.assert(target.len == valueByteCount(value));    switch (target.len) {        1 => target[0] = @truncate(value),        2 => std.mem.writeInt(u16, target[0..2], @truncate(value), .little),        3 => {            target[0] = @truncate(value);            target[1] = @truncate(value >> 8);            target[2] = @truncate(value >> 16);        },        4 => std.mem.writeInt(u32, target[0..4], value, .little),        else => unreachable,    }}fn readValue(input: []const u8, offset: *usize, code: u8) Error!u32 {    const byte_count = @as(usize, code) + 1;    const end = std.math.add(usize, offset.*, byte_count) catch return error.InvalidSearchIndex;    if (end > input.len) return error.InvalidSearchIndex;    const value: u32 = switch (byte_count) {        1 => input[offset.*],        2 => std.mem.readInt(u16, input[offset.*..][0..2], .little),        3 => @as(u32, input[offset.*]) | (@as(u32, input[offset.* + 1]) << 8) | (@as(u32, input[offset.* + 2]) << 16),        4 => std.mem.readInt(u32, input[offset.*..][0..4], .little),        else => unreachable,    };    offset.* = end;    return value;}test "Stream VByte 8afe869 format fixture is exact" {    const values = [_]u32{ 0, 100, 200, 300, 400, 500, 600, 700 };    const expected = [_]u8{ 0x40, 0x55, 0x00, 0x64, 0xc8, 0x2c, 0x01, 0x90, 0x01, 0xf4, 0x01, 0x58, 0x02, 0xbc, 0x02 };    var encoded: [expected.len]u8 = undefined;    _ = try encode(&encoded, &values);    try std.testing.expectEqualSlices(u8, &expected, &encoded);    var decoded: [values.len]u32 = undefined;    try decode(&decoded, &encoded);    try std.testing.expectEqualSlices(u32, &values, &decoded);}test "Stream VByte preserves byte-width boundaries" {    var empty_encoded: [0]u8 = .{};    var empty_decoded: [0]u32 = .{};    try std.testing.expectEqual(@as(usize, 0), (try encode(&empty_encoded, &empty_decoded)).len);    try decode(&empty_decoded, &empty_encoded);    const values = [_]u32{ 0, 0xff, 0x100, 0xffff, 0x1_0000, 0xff_ffff, 0x100_0000, std.math.maxInt(u32) };    var encoded: [22]u8 = undefined;    _ = try encode(&encoded, &values);    var decoded: [values.len]u32 = undefined;    try decode(&decoded, &encoded);    try std.testing.expectEqualSlices(u32, &values, &decoded);}test "Stream VByte rejects malformed streams" {    const values = [_]u32{ 1, 0x100, 3 };    var encoded: [5]u8 = undefined;    _ = try encode(&encoded, &values);    var decoded: [values.len]u32 = undefined;    try std.testing.expectError(error.InvalidSearchIndex, decode(&decoded, encoded[0 .. encoded.len - 1]));    var trailing: [encoded.len + 1]u8 = undefined;    @memcpy(trailing[0..encoded.len], &encoded);    trailing[encoded.len] = 0;    try std.testing.expectError(error.InvalidSearchIndex, decode(&decoded, &trailing));    var noncanonical = encoded;    noncanonical[0] |= 0xc0;    try std.testing.expectError(error.InvalidSearchIndex, decode(&decoded, &noncanonical));    var too_small: [encoded.len - 1]u8 = undefined;    try std.testing.expectError(error.OutputTooSmall, encode(&too_small, &values));}

Complete caller list for search.vbyte.controlByteCount

7 direct callers.

Audit

Definitions18
Public names18
Members10
Version26.7.0
Revisiondaab053ee433