try to get secondary index to work
This commit is contained in:
127
src/index_codec.zig
Normal file
127
src/index_codec.zig
Normal file
@@ -0,0 +1,127 @@
|
||||
/// Secondary index entry encoding
|
||||
/// Index entries store pointers to primary keys, not full items
|
||||
const std = @import("std");
|
||||
|
||||
/// Encode a primary key reference for storage in an index entry
|
||||
/// Format: [pk_len:varint][pk:bytes][sk_len:varint][sk:bytes]?
|
||||
/// Returns owned slice that caller must free
|
||||
pub fn encodePrimaryKeyRef(
|
||||
allocator: std.mem.Allocator,
|
||||
pk_value: []const u8,
|
||||
sk_value: ?[]const u8,
|
||||
) ![]u8 {
|
||||
var buf = std.ArrayList(u8).init(allocator);
|
||||
errdefer buf.deinit();
|
||||
const writer = buf.writer();
|
||||
|
||||
// Encode partition key
|
||||
try encodeVarint(writer, pk_value.len);
|
||||
try writer.writeAll(pk_value);
|
||||
|
||||
// Encode sort key if present
|
||||
if (sk_value) |sk| {
|
||||
try encodeVarint(writer, sk.len);
|
||||
try writer.writeAll(sk);
|
||||
}
|
||||
|
||||
return buf.toOwnedSlice();
|
||||
}
|
||||
|
||||
/// Decode a primary key reference from an index entry
|
||||
/// Returns struct with owned slices that caller must free
|
||||
pub fn decodePrimaryKeyRef(allocator: std.mem.Allocator, data: []const u8) !PrimaryKeyRef {
|
||||
var decoder = BinaryDecoder.init(data);
|
||||
|
||||
// Decode partition key
|
||||
const pk_len = try decoder.readVarint();
|
||||
const pk = try decoder.readBytes(pk_len);
|
||||
const owned_pk = try allocator.dupe(u8, pk);
|
||||
errdefer allocator.free(owned_pk);
|
||||
|
||||
// Decode sort key if present
|
||||
var owned_sk: ?[]u8 = null;
|
||||
if (decoder.hasMore()) {
|
||||
const sk_len = try decoder.readVarint();
|
||||
const sk = try decoder.readBytes(sk_len);
|
||||
owned_sk = try allocator.dupe(u8, sk);
|
||||
}
|
||||
|
||||
return PrimaryKeyRef{
|
||||
.pk = owned_pk,
|
||||
.sk = owned_sk,
|
||||
};
|
||||
}
|
||||
|
||||
pub const PrimaryKeyRef = struct {
|
||||
pk: []u8,
|
||||
sk: ?[]u8,
|
||||
|
||||
pub fn deinit(self: *PrimaryKeyRef, allocator: std.mem.Allocator) void {
|
||||
allocator.free(self.pk);
|
||||
if (self.sk) |sk| allocator.free(sk);
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Binary Decoder Helper
|
||||
// ============================================================================
|
||||
|
||||
const BinaryDecoder = struct {
|
||||
data: []const u8,
|
||||
pos: usize,
|
||||
|
||||
pub fn init(data: []const u8) BinaryDecoder {
|
||||
return .{ .data = data, .pos = 0 };
|
||||
}
|
||||
|
||||
pub fn readBytes(self: *BinaryDecoder, len: usize) ![]const u8 {
|
||||
if (self.pos + len > self.data.len) return error.UnexpectedEndOfData;
|
||||
const bytes = self.data[self.pos .. self.pos + len];
|
||||
self.pos += len;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
pub fn readVarint(self: *BinaryDecoder) !usize {
|
||||
var result: usize = 0;
|
||||
var shift: u6 = 0;
|
||||
|
||||
while (self.pos < self.data.len) {
|
||||
const byte = self.data[self.pos];
|
||||
self.pos += 1;
|
||||
|
||||
result |= @as(usize, byte & 0x7F) << shift;
|
||||
|
||||
if ((byte & 0x80) == 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
shift += 7;
|
||||
if (shift >= 64) return error.VarintOverflow;
|
||||
}
|
||||
|
||||
return error.UnexpectedEndOfData;
|
||||
}
|
||||
|
||||
pub fn hasMore(self: *BinaryDecoder) bool {
|
||||
return self.pos < self.data.len;
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Varint encoding (consistent with key_codec and item_codec)
|
||||
// ============================================================================
|
||||
|
||||
fn encodeVarint(writer: anytype, value: usize) !void {
|
||||
var v = value;
|
||||
while (true) {
|
||||
const byte = @as(u8, @intCast(v & 0x7F));
|
||||
v >>= 7;
|
||||
|
||||
if (v == 0) {
|
||||
try writer.writeByte(byte);
|
||||
return;
|
||||
} else {
|
||||
try writer.writeByte(byte | 0x80);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user