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