DoxigAlpha

update

Function parameters

Parameters

#
self:*XxHash3
input:anytype

Type definitions in this namespace

Types

#

Source

Implementation

#
pub fn update(self: *XxHash3, input: anytype) void {
    self.total_len += input.len;
    std.debug.assert(self.buffered <= self.buffer.len);

    // Copy the input into the buffer if we haven't filled it up yet.
    const remaining = self.buffer.len - self.buffered;
    if (input.len <= remaining) {
        @memcpy(self.buffer[self.buffered..][0..input.len], input);
        self.buffered += input.len;
        return;
    }

    // Input will overflow the buffer. Fill up the buffer with some input and consume it.
    var consumable: []const u8 = input;
    if (self.buffered > 0) {
        @memcpy(self.buffer[self.buffered..], consumable[0..remaining]);
        consumable = consumable[remaining..];

        self.accumulator.consume(std.mem.bytesAsSlice(Block, &self.buffer));
        self.buffered = 0;
    }

    // The input isn't small enough to fit in the buffer. Consume it directly.
    if (consumable.len > self.buffer.len) {
        const block_count = ((consumable.len - 1) / @sizeOf(Block)) * @sizeOf(Block);
        self.accumulator.consume(std.mem.bytesAsSlice(Block, consumable[0..block_count]));
        consumable = consumable[block_count..];

        // In case we consume all remaining input, write the last block to end of the buffer
        // to populate the last_block_copy in final() similar to hashLong()'s last_block.
        @memcpy(
            self.buffer[self.buffer.len - @sizeOf(Block) .. self.buffer.len],
            (consumable.ptr - @sizeOf(Block))[0..@sizeOf(Block)],
        );
    }

    // Copy in any remaining input into the buffer.
    std.debug.assert(consumable.len <= self.buffer.len);
    @memcpy(self.buffer[0..consumable.len], consumable);
    self.buffered = consumable.len;
}