Files
scylladb/sstables/random_access_reader.hh
Taras Veretilnyk 478c1eaec5 sstables: add digest_file_random_access_reader for CRC32 digest computation
Add a new reader that wraps file_random_access_reader and computes a
running CRC32 digest over the data as it is read. The digest accumulates
across sequential read_exactly() calls and is reset on seek(), since a
non-sequential read invalidates the running checksum.
2026-03-10 19:24:05 +01:00

79 lines
2.0 KiB
C++

/*
* Copyright (C) 2018-present ScyllaDB
*/
/*
* SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
*/
#pragma once
#include "exceptions.hh"
#include <memory>
#include <seastar/core/file.hh>
#include <seastar/core/fstream.hh>
#include <seastar/core/future.hh>
#include <seastar/core/gate.hh>
#include <seastar/core/iostream.hh>
#include <seastar/core/temporary_buffer.hh>
#include "seastarx.hh"
#include "sstables/checksum_utils.hh"
namespace sstables {
class random_access_reader {
std::unique_ptr <input_stream<char>> _in;
protected:
virtual input_stream<char> open_at(uint64_t pos) = 0;
void set(input_stream<char> in) {
parse_assert(!_in);
_in = std::make_unique<input_stream<char>>(std::move(in));
}
public:
virtual future <temporary_buffer<char>> read_exactly(size_t n) noexcept;
virtual future<> seek(uint64_t pos) noexcept;
bool eof() const noexcept { return _in->eof(); }
virtual future<> close() noexcept;
virtual ~random_access_reader() {}
};
class file_random_access_reader : public random_access_reader {
file _file;
size_t _buffer_size;
unsigned _read_ahead;
protected:
uint64_t _file_size;
public:
virtual input_stream<char> open_at(uint64_t pos) override;
explicit file_random_access_reader(file f, uint64_t file_size, size_t buffer_size = 8192, unsigned read_ahead = 4);
virtual future<> close() noexcept override;
};
class digest_file_random_access_reader : public file_random_access_reader {
std::optional<uint32_t> _digest;
uint64_t _pos = 0;
public:
digest_file_random_access_reader(file f, uint64_t file_size, size_t buffer_size = 8192, unsigned read_ahead = 4);
virtual future<temporary_buffer<char>> read_exactly(size_t n) noexcept override;
virtual future<> seek(uint64_t pos) noexcept override;
std::optional<uint32_t> digest() const noexcept {
if (_pos != _file_size) {
return std::nullopt;
}
return _digest;
}
};
}