Skip to content

Commit 7f43f78

Browse files
committed
std.compress.zstd: keep frame state between blocks
1 parent 13e08ea commit 7f43f78

File tree

1 file changed

+32
-42
lines changed

1 file changed

+32
-42
lines changed

lib/std/compress/zstd/Decompress.zig

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const State = union(enum) {
2323
frame: Frame,
2424
checksum: ?u32,
2525
decompressed_size: usize,
26+
decode: Frame.Zstandard.Decode,
2627
};
2728
};
2829

@@ -138,6 +139,7 @@ fn initFrame(d: *Decompress, window_size_max: usize, magic: Frame.Magic) !void {
138139
.frame = try Frame.init(header, window_size_max, d.verify_checksum),
139140
.checksum = null,
140141
.decompressed_size = 0,
142+
.decode = .init,
141143
} };
142144
},
143145
.skippable => {
@@ -168,16 +170,13 @@ fn readInFrame(d: *Decompress, w: *Writer, limit: Limit, state: *State.InFrame)
168170
bytes_written = block_size;
169171
},
170172
.compressed => {
171-
var literal_fse_buffer: [zstd.table_size_max.literal]Table.Fse = undefined;
172-
var match_fse_buffer: [zstd.table_size_max.match]Table.Fse = undefined;
173-
var offset_fse_buffer: [zstd.table_size_max.offset]Table.Fse = undefined;
174173
var literals_buffer: [zstd.block_size_max]u8 = undefined;
175174
var sequence_buffer: [zstd.block_size_max]u8 = undefined;
176-
var decode: Frame.Zstandard.Decode = .init(&literal_fse_buffer, &match_fse_buffer, &offset_fse_buffer, window_len);
177175
var remaining: Limit = .limited(block_size);
178176
const literals = try LiteralsSection.decode(in, &remaining, &literals_buffer);
179177
const sequences_header = try SequencesSection.Header.decode(in, &remaining);
180178

179+
const decode = &state.decode;
181180
try decode.prepare(in, &remaining, literals, sequences_header);
182181

183182
{
@@ -370,16 +369,15 @@ pub const Frame = struct {
370369
};
371370

372371
pub const Decode = struct {
373-
window_len: u32,
374372
repeat_offsets: [3]u32,
375373

376374
offset: StateData(8),
377375
match: StateData(9),
378376
literal: StateData(9),
379377

380-
offset_fse_buffer: []Table.Fse,
381-
match_fse_buffer: []Table.Fse,
382-
literal_fse_buffer: []Table.Fse,
378+
literal_fse_buffer: [zstd.table_size_max.literal]Table.Fse,
379+
match_fse_buffer: [zstd.table_size_max.match]Table.Fse,
380+
offset_fse_buffer: [zstd.table_size_max.offset]Table.Fse,
383381

384382
fse_tables_undefined: bool,
385383

@@ -401,38 +399,30 @@ pub const Frame = struct {
401399
};
402400
}
403401

404-
pub fn init(
405-
literal_fse_buffer: []Table.Fse,
406-
match_fse_buffer: []Table.Fse,
407-
offset_fse_buffer: []Table.Fse,
408-
window_len: u32,
409-
) Decode {
410-
return .{
411-
.window_len = window_len,
412-
.repeat_offsets = .{
413-
zstd.start_repeated_offset_1,
414-
zstd.start_repeated_offset_2,
415-
zstd.start_repeated_offset_3,
416-
},
402+
const init: Decode = .{
403+
.repeat_offsets = .{
404+
zstd.start_repeated_offset_1,
405+
zstd.start_repeated_offset_2,
406+
zstd.start_repeated_offset_3,
407+
},
417408

418-
.offset = undefined,
419-
.match = undefined,
420-
.literal = undefined,
409+
.offset = undefined,
410+
.match = undefined,
411+
.literal = undefined,
421412

422-
.literal_fse_buffer = literal_fse_buffer,
423-
.match_fse_buffer = match_fse_buffer,
424-
.offset_fse_buffer = offset_fse_buffer,
413+
.literal_fse_buffer = undefined,
414+
.match_fse_buffer = undefined,
415+
.offset_fse_buffer = undefined,
425416

426-
.fse_tables_undefined = true,
417+
.fse_tables_undefined = true,
427418

428-
.literal_written_count = 0,
429-
.literal_header = undefined,
430-
.literal_streams = undefined,
431-
.literal_stream_reader = undefined,
432-
.literal_stream_index = undefined,
433-
.huffman_tree = null,
434-
};
435-
}
419+
.literal_written_count = 0,
420+
.literal_header = undefined,
421+
.literal_streams = undefined,
422+
.literal_stream_reader = undefined,
423+
.literal_stream_index = undefined,
424+
.huffman_tree = null,
425+
};
436426

437427
pub const PrepareError = error{
438428
/// the (reversed) literal bitstream's first byte does not have any bits set
@@ -514,12 +504,12 @@ pub const Frame = struct {
514504
return self.repeat_offsets[0];
515505
}
516506

517-
const DataType = enum { offset, match, literal };
507+
const WhichFse = enum { offset, match, literal };
518508

519509
/// TODO: don't use `@field`
520510
fn updateState(
521511
self: *Decode,
522-
comptime choice: DataType,
512+
comptime choice: WhichFse,
523513
bit_reader: *ReverseBitReader,
524514
) error{ MalformedFseBits, EndOfStream }!void {
525515
switch (@field(self, @tagName(choice)).table) {
@@ -549,7 +539,7 @@ pub const Frame = struct {
549539
self: *Decode,
550540
in: *Reader,
551541
remaining: *Limit,
552-
comptime choice: DataType,
542+
comptime choice: WhichFse,
553543
mode: SequencesSection.Header.Mode,
554544
) !void {
555545
const field_name = @tagName(choice);
@@ -576,10 +566,10 @@ pub const Frame = struct {
576566
&bit_reader,
577567
@field(zstd.table_symbol_count_max, field_name),
578568
@field(zstd.table_accuracy_log_max, field_name),
579-
@field(self, field_name ++ "_fse_buffer"),
569+
&@field(self, field_name ++ "_fse_buffer"),
580570
);
581571
@field(self, field_name).table = .{
582-
.fse = @field(self, field_name ++ "_fse_buffer")[0..table_size],
572+
.fse = (&@field(self, field_name ++ "_fse_buffer"))[0..table_size],
583573
};
584574
@field(self, field_name).accuracy_log = std.math.log2_int_ceil(usize, table_size);
585575
in.toss(bit_reader.index);
@@ -762,7 +752,7 @@ pub const Frame = struct {
762752
}
763753

764754
/// TODO: don't use `@field`
765-
fn getCode(self: *Decode, comptime choice: DataType) u32 {
755+
fn getCode(self: *Decode, comptime choice: WhichFse) u32 {
766756
return switch (@field(self, @tagName(choice)).table) {
767757
.rle => |value| value,
768758
.fse => |table| table[@field(self, @tagName(choice)).state].symbol,

0 commit comments

Comments
 (0)