1// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file. See the AUTHORS file for names of contributors.
4
5#ifndef STORAGE_LEVELDB_TABLE_FORMAT_H_
6#define STORAGE_LEVELDB_TABLE_FORMAT_H_
7
8#include <cstdint>
9#include <string>
10
11#include "leveldb/slice.h"
12#include "leveldb/status.h"
13#include "leveldb/table_builder.h"
14
15namespace leveldb {
16
17class Block;
18class RandomAccessFile;
19struct ReadOptions;
20
21// BlockHandle is a pointer to the extent of a file that stores a data
22// block or a meta block.
23class BlockHandle {
24 public:
25 // Maximum encoding length of a BlockHandle
26 enum { kMaxEncodedLength = 10 + 10 };
27
28 BlockHandle();
29
30 // The offset of the block in the file.
31 uint64_t offset() const { return offset_; }
32 void set_offset(uint64_t offset) { offset_ = offset; }
33
34 // The size of the stored block
35 uint64_t size() const { return size_; }
36 void set_size(uint64_t size) { size_ = size; }
37
38 void EncodeTo(std::string* dst) const;
39 Status DecodeFrom(Slice* input);
40
41 private:
42 uint64_t offset_;
43 uint64_t size_;
44};
45
46// Footer encapsulates the fixed information stored at the tail
47// end of every table file.
48class Footer {
49 public:
50 // Encoded length of a Footer. Note that the serialization of a
51 // Footer will always occupy exactly this many bytes. It consists
52 // of two block handles and a magic number.
53 enum { kEncodedLength = 2 * BlockHandle::kMaxEncodedLength + 8 };
54
55 Footer() = default;
56
57 // The block handle for the metaindex block of the table
58 const BlockHandle& metaindex_handle() const { return metaindex_handle_; }
59 void set_metaindex_handle(const BlockHandle& h) { metaindex_handle_ = h; }
60
61 // The block handle for the index block of the table
62 const BlockHandle& index_handle() const { return index_handle_; }
63 void set_index_handle(const BlockHandle& h) { index_handle_ = h; }
64
65 void EncodeTo(std::string* dst) const;
66 Status DecodeFrom(Slice* input);
67
68 private:
69 BlockHandle metaindex_handle_;
70 BlockHandle index_handle_;
71};
72
73// kTableMagicNumber was picked by running
74// echo http://code.google.com/p/leveldb/ | sha1sum
75// and taking the leading 64 bits.
76static const uint64_t kTableMagicNumber = 0xdb4775248b80fb57ull;
77
78// 1-byte type + 32-bit crc
79static const size_t kBlockTrailerSize = 5;
80
81struct BlockContents {
82 Slice data; // Actual contents of data
83 bool cachable; // True iff data can be cached
84 bool heap_allocated; // True iff caller should delete[] data.data()
85};
86
87// Read the block identified by "handle" from "file". On failure
88// return non-OK. On success fill *result and return OK.
89Status ReadBlock(RandomAccessFile* file, const ReadOptions& options,
90 const BlockHandle& handle, BlockContents* result);
91
92// Implementation details follow. Clients should ignore,
93
94inline BlockHandle::BlockHandle()
95 : offset_(~static_cast<uint64_t>(0)), size_(~static_cast<uint64_t>(0)) {}
96
97} // namespace leveldb
98
99#endif // STORAGE_LEVELDB_TABLE_FORMAT_H_
100