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 15 namespace leveldb { 16 17 class Block; 18 class RandomAccessFile; 19 struct ReadOptions; 20 21 // BlockHandle is a pointer to the extent of a file that stores a data 22 // block or a meta block. 23 class 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. offset()31 uint64_t offset() const { return offset_; } set_offset(uint64_t offset)32 void set_offset(uint64_t offset) { offset_ = offset; } 33 34 // The size of the stored block size()35 uint64_t size() const { return size_; } set_size(uint64_t 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. 48 class 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 metaindex_handle()58 const BlockHandle& metaindex_handle() const { return metaindex_handle_; } set_metaindex_handle(const BlockHandle & h)59 void set_metaindex_handle(const BlockHandle& h) { metaindex_handle_ = h; } 60 61 // The block handle for the index block of the table index_handle()62 const BlockHandle& index_handle() const { return index_handle_; } set_index_handle(const BlockHandle & h)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. 76 static const uint64_t kTableMagicNumber = 0xdb4775248b80fb57ull; 77 78 // 1-byte type + 32-bit crc 79 static const size_t kBlockTrailerSize = 5; 80 81 struct 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. 89 Status ReadBlock(RandomAccessFile* file, const ReadOptions& options, 90 const BlockHandle& handle, BlockContents* result); 91 92 // Implementation details follow. Clients should ignore, 93 BlockHandle()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