#pragma once
#include <string>
#include <stdint.h>
#include "rocksdb/slice.h"
#include "rocksdb/status.h"
#include "rocksdb/options.h"
#include "rocksdb/table.h"
#include "options/cf_options.h"
#include "port/port.h"
#include "table/persistent_cache_options.h"
namespace rocksdb {
class Block;
class RandomAccessFile;
struct ReadOptions;
extern bool ShouldReportDetailedTime(Env* env, Statistics* stats);
const int kMagicNumberLengthByte = 8;
class BlockHandle {
public:
BlockHandle();
BlockHandle(uint64_t offset, uint64_t size);
uint64_t offset() const { return offset_; }
void set_offset(uint64_t _offset) { offset_ = _offset; }
uint64_t size() const { return size_; }
void set_size(uint64_t _size) { size_ = _size; }
void EncodeTo(std::string* dst) const;
Status DecodeFrom(Slice* input);
std::string ToString(bool hex = true) const;
bool IsNull() const {
return offset_ == 0 && size_ == 0;
}
static const BlockHandle& NullBlockHandle() {
return kNullBlockHandle;
}
enum { kMaxEncodedLength = 10 + 10 };
private:
uint64_t offset_;
uint64_t size_;
static const BlockHandle kNullBlockHandle;
};
inline uint32_t GetCompressFormatForVersion(CompressionType compression_type,
uint32_t version) {
assert(compression_type != kSnappyCompression &&
compression_type != kXpressCompression &&
compression_type != kNoCompression);
return version >= 2 ? 2 : 1;
}
inline bool BlockBasedTableSupportedVersion(uint32_t version) {
return version <= 2;
}
class Footer {
public:
Footer() : Footer(kInvalidTableMagicNumber, 0) {}
Footer(uint64_t table_magic_number, uint32_t version);
uint32_t version() const { return version_; }
ChecksumType checksum() const { return checksum_; }
void set_checksum(const ChecksumType c) { checksum_ = c; }
const BlockHandle& metaindex_handle() const { return metaindex_handle_; }
void set_metaindex_handle(const BlockHandle& h) { metaindex_handle_ = h; }
const BlockHandle& index_handle() const { return index_handle_; }
void set_index_handle(const BlockHandle& h) { index_handle_ = h; }
uint64_t table_magic_number() const { return table_magic_number_; }
void EncodeTo(std::string* dst) const;
Status DecodeFrom(Slice* input);
enum {
kVersion0EncodedLength = 2 * BlockHandle::kMaxEncodedLength + 8,
kNewVersionsEncodedLength = 1 + 2 * BlockHandle::kMaxEncodedLength + 4 + 8,
kMinEncodedLength = kVersion0EncodedLength,
kMaxEncodedLength = kNewVersionsEncodedLength,
};
static const uint64_t kInvalidTableMagicNumber = 0;
std::string ToString() const;
private:
void set_table_magic_number(uint64_t magic_number) {
assert(!HasInitializedTableMagicNumber());
table_magic_number_ = magic_number;
}
bool HasInitializedTableMagicNumber() const {
return (table_magic_number_ != kInvalidTableMagicNumber);
}
uint32_t version_;
ChecksumType checksum_;
BlockHandle metaindex_handle_;
BlockHandle index_handle_;
uint64_t table_magic_number_ = 0;
};
Status ReadFooterFromFile(RandomAccessFileReader* file, uint64_t file_size,
Footer* footer,
uint64_t enforce_table_magic_number = 0);
static const size_t kBlockTrailerSize = 5;
struct BlockContents {
Slice data; bool cachable; CompressionType compression_type;
std::unique_ptr<char[]> allocation;
BlockContents() : cachable(false), compression_type(kNoCompression) {}
BlockContents(const Slice& _data, bool _cachable,
CompressionType _compression_type)
: data(_data), cachable(_cachable), compression_type(_compression_type) {}
BlockContents(std::unique_ptr<char[]>&& _data, size_t _size, bool _cachable,
CompressionType _compression_type)
: data(_data.get(), _size),
cachable(_cachable),
compression_type(_compression_type),
allocation(std::move(_data)) {}
BlockContents(BlockContents&& other) ROCKSDB_NOEXCEPT { *this = std::move(other); }
BlockContents& operator=(BlockContents&& other) {
data = std::move(other.data);
cachable = other.cachable;
compression_type = other.compression_type;
allocation = std::move(other.allocation);
return *this;
}
};
extern Status ReadBlockContents(
RandomAccessFileReader* file, const Footer& footer,
const ReadOptions& options, const BlockHandle& handle,
BlockContents* contents, const ImmutableCFOptions &ioptions,
bool do_uncompress = true, const Slice& compression_dict = Slice(),
const PersistentCacheOptions& cache_options = PersistentCacheOptions());
extern Status UncompressBlockContents(const char* data, size_t n,
BlockContents* contents,
uint32_t compress_format_version,
const Slice& compression_dict,
const ImmutableCFOptions &ioptions);
extern Status UncompressBlockContentsForCompressionType(
const char* data, size_t n, BlockContents* contents,
uint32_t compress_format_version, const Slice& compression_dict,
CompressionType compression_type, const ImmutableCFOptions &ioptions);
inline BlockHandle::BlockHandle()
: BlockHandle(~static_cast<uint64_t>(0),
~static_cast<uint64_t>(0)) {
}
inline BlockHandle::BlockHandle(uint64_t _offset, uint64_t _size)
: offset_(_offset), size_(_size) {}
}