deltaDecompress
This commit is contained in:
parent
ca67bf56e7
commit
0b0e917086
@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
// delta compresses an incrementing sorted array of integers using delta
|
// compresses a strictly incrementing sorted slice of integers using delta
|
||||||
// compression. Sorting is in-place.
|
// compression. Compression is in-place.
|
||||||
pub fn deltaCompress(comptime T: type, elems: []T) error{NotSorted}!void {
|
pub fn deltaCompress(comptime T: type, elems: []T) error{NotSorted}!void {
|
||||||
if (elems.len == 0) {
|
if (elems.len <= 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var prev: T = elems[0];
|
var prev: T = elems[0];
|
||||||
@ -24,14 +24,28 @@ pub fn deltaCompress(comptime T: type, elems: []T) error{NotSorted}!void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// decompresses a slice compressed by deltaCompress. In-place.
|
||||||
|
pub fn deltaDecompress(comptime T: type, elems: []T) error{Overflow}!void {
|
||||||
|
if (elems.len <= 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var i: usize = 1;
|
||||||
|
while (i < elems.len) : (i += 1) {
|
||||||
|
const x = try std.math.add(T, elems[i - 1], 1);
|
||||||
|
elems[i] = try std.math.add(T, elems[i], x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
|
||||||
test "delta compression positive tests" {
|
test "delta compress/decompress" {
|
||||||
const tests = [_]struct { input: []const u8, want: []const u8 }{
|
const tests = [_]struct { input: []const u8, want: []const u8 }{
|
||||||
.{ .input = &[_]u8{}, .want = &[_]u8{} },
|
.{ .input = &[_]u8{}, .want = &[_]u8{} },
|
||||||
.{ .input = &[_]u8{0}, .want = &[_]u8{0} },
|
.{ .input = &[_]u8{0}, .want = &[_]u8{0} },
|
||||||
.{ .input = &[_]u8{10}, .want = &[_]u8{10} },
|
.{ .input = &[_]u8{10}, .want = &[_]u8{10} },
|
||||||
.{ .input = &[_]u8{ 0, 1, 2 }, .want = &[_]u8{ 0, 0, 0 } },
|
.{ .input = &[_]u8{ 0, 1, 2 }, .want = &[_]u8{ 0, 0, 0 } },
|
||||||
|
.{ .input = &[_]u8{ 10, 20, 30, 255 }, .want = &[_]u8{ 10, 9, 9, 224 } },
|
||||||
.{ .input = &[_]u8{ 0, 254, 255 }, .want = &[_]u8{ 0, 253, 0 } },
|
.{ .input = &[_]u8{ 0, 254, 255 }, .want = &[_]u8{ 0, 253, 0 } },
|
||||||
};
|
};
|
||||||
for (tests) |t| {
|
for (tests) |t| {
|
||||||
@ -44,6 +58,9 @@ test "delta compression positive tests" {
|
|||||||
|
|
||||||
try deltaCompress(u8, arr.items);
|
try deltaCompress(u8, arr.items);
|
||||||
try testing.expectEqualSlices(u8, arr.items, t.want);
|
try testing.expectEqualSlices(u8, arr.items, t.want);
|
||||||
|
|
||||||
|
try deltaDecompress(u8, arr.items);
|
||||||
|
try testing.expectEqualSlices(u8, arr.items, t.input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +77,18 @@ test "delta compression negative tests" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "delta decompress overflow" {
|
||||||
|
for ([_][]const u8{
|
||||||
|
&[_]u8{ 255, 0 },
|
||||||
|
&[_]u8{ 0, 128, 127 },
|
||||||
|
}) |t| {
|
||||||
|
var arr = try std.ArrayList(u8).initCapacity(testing.allocator, t.len);
|
||||||
|
defer arr.deinit();
|
||||||
|
try arr.appendSlice(t);
|
||||||
|
try testing.expectError(error.Overflow, deltaDecompress(u8, arr.items));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Represents a variable length integer that we read from a byte stream along
|
// Represents a variable length integer that we read from a byte stream along
|
||||||
// with how many bytes were read to decode it.
|
// with how many bytes were read to decode it.
|
||||||
pub const Varint = struct {
|
pub const Varint = struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user