69 lines
1.9 KiB
Zig
69 lines
1.9 KiB
Zig
|
const std = @import("std");
|
||
|
const Allocator = std.mem.Allocator;
|
||
|
const bdz = @import("bdz.zig");
|
||
|
|
||
|
const c = @cImport({
|
||
|
@cInclude("cmph.h");
|
||
|
});
|
||
|
|
||
|
// pack packs cmph hashes for the given input and returns a slice ("cmph
|
||
|
// userdata") for further storage. The slice must be freed by the caller.
|
||
|
const packErr = Allocator.Error || error{Overflow};
|
||
|
pub fn pack(allocator: Allocator, input: [][*:0]const u8) packErr![]const u8 {
|
||
|
var cvector = @ptrCast([*c][*c]u8, input.ptr);
|
||
|
const len = try std.math.cast(c_uint, input.len);
|
||
|
var source = c.cmph_io_vector_adapter(cvector, len);
|
||
|
defer c.cmph_io_vector_adapter_destroy(source);
|
||
|
var config: *c.cmph_config_t = c.cmph_config_new(source) orelse return error.OutOfMemory;
|
||
|
c.cmph_config_set_algo(config, c.CMPH_BDZ);
|
||
|
c.cmph_config_set_b(config, 7);
|
||
|
var hash: *c.cmph_t = c.cmph_new(config) orelse return error.OutOfMemory;
|
||
|
c.cmph_config_destroy(config);
|
||
|
|
||
|
const size = c.cmph_packed_size(hash);
|
||
|
var buf = try allocator.alloc(u8, size);
|
||
|
c.cmph_pack(hash, &buf[0]);
|
||
|
c.cmph_destroy(hash);
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
const testing = std.testing;
|
||
|
|
||
|
const items = .{
|
||
|
"aaaaaaaaaa",
|
||
|
"bbbbbbbbbb",
|
||
|
"cccccccccc",
|
||
|
"dddddddddd",
|
||
|
"eeeeeeeeee",
|
||
|
"ffffffffff",
|
||
|
"gggggggggg",
|
||
|
"hhhhhhhhhh",
|
||
|
"iiiiiiiiii",
|
||
|
"jjjjjjjjjj",
|
||
|
};
|
||
|
const items_len = items.len;
|
||
|
|
||
|
fn samplePack(allocator: Allocator) ![]const u8 {
|
||
|
var vector = std.ArrayList([*:0]const u8).init(allocator);
|
||
|
defer vector.deinit();
|
||
|
try vector.appendSlice(&items);
|
||
|
return pack(allocator, vector.items);
|
||
|
}
|
||
|
|
||
|
test "basic pack/unpack" {
|
||
|
const buf = try samplePack(testing.allocator);
|
||
|
defer testing.allocator.free(buf);
|
||
|
try testing.expect(buf.len < 100);
|
||
|
|
||
|
var used: [items_len]bool = undefined;
|
||
|
|
||
|
inline for (items) |elem| {
|
||
|
const hashed = try bdz.search_packed(buf, elem);
|
||
|
used[hashed] = true;
|
||
|
}
|
||
|
|
||
|
for (used) |item| {
|
||
|
try testing.expect(item);
|
||
|
}
|
||
|
}
|