1 //  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 //
6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
9 
10 #pragma once
11 #include <memory>
12 #include "db/range_tombstone_fragmenter.h"
13 #include "rocksdb/slice_transform.h"
14 #include "table/get_context.h"
15 #include "table/internal_iterator.h"
16 #include "table/multiget_context.h"
17 #include "table/table_reader_caller.h"
18 
19 namespace ROCKSDB_NAMESPACE {
20 
21 class Iterator;
22 struct ParsedInternalKey;
23 class Slice;
24 class Arena;
25 struct ReadOptions;
26 struct TableProperties;
27 class GetContext;
28 class MultiGetContext;
29 
30 // A Table (also referred to as SST) is a sorted map from strings to strings.
31 // Tables are immutable and persistent.  A Table may be safely accessed from
32 // multiple threads without external synchronization. Table readers are used
33 // for reading various types of table formats supported by rocksdb including
34 // BlockBasedTable, PlainTable and CuckooTable format.
35 class TableReader {
36  public:
~TableReader()37   virtual ~TableReader() {}
38 
39   // Returns a new iterator over the table contents.
40   // The result of NewIterator() is initially invalid (caller must
41   // call one of the Seek methods on the iterator before using it).
42   // arena: If not null, the arena needs to be used to allocate the Iterator.
43   //        When destroying the iterator, the caller will not call "delete"
44   //        but Iterator::~Iterator() directly. The destructor needs to destroy
45   //        all the states but those allocated in arena.
46   // skip_filters: disables checking the bloom filters even if they exist. This
47   //               option is effective only for block-based table format.
48   // compaction_readahead_size: its value will only be used if caller =
49   // kCompaction
50   virtual InternalIterator* NewIterator(
51       const ReadOptions&, const SliceTransform* prefix_extractor, Arena* arena,
52       bool skip_filters, TableReaderCaller caller,
53       size_t compaction_readahead_size = 0) = 0;
54 
NewRangeTombstoneIterator(const ReadOptions &)55   virtual FragmentedRangeTombstoneIterator* NewRangeTombstoneIterator(
56       const ReadOptions& /*read_options*/) {
57     return nullptr;
58   }
59 
60   // Given a key, return an approximate byte offset in the file where
61   // the data for that key begins (or would begin if the key were
62   // present in the file).  The returned value is in terms of file
63   // bytes, and so includes effects like compression of the underlying data.
64   // E.g., the approximate offset of the last key in the table will
65   // be close to the file length.
66   virtual uint64_t ApproximateOffsetOf(const Slice& key,
67                                        TableReaderCaller caller) = 0;
68 
69   // Given start and end keys, return the approximate data size in the file
70   // between the keys. The returned value is in terms of file bytes, and so
71   // includes effects like compression of the underlying data.
72   virtual uint64_t ApproximateSize(const Slice& start, const Slice& end,
73                                    TableReaderCaller caller) = 0;
74 
75   // Set up the table for Compaction. Might change some parameters with
76   // posix_fadvise
77   virtual void SetupForCompaction() = 0;
78 
79   virtual std::shared_ptr<const TableProperties> GetTableProperties() const = 0;
80 
81   // Prepare work that can be done before the real Get()
Prepare(const Slice &)82   virtual void Prepare(const Slice& /*target*/) {}
83 
84   // Report an approximation of how much memory has been used.
85   virtual size_t ApproximateMemoryUsage() const = 0;
86 
87   // Calls get_context->SaveValue() repeatedly, starting with
88   // the entry found after a call to Seek(key), until it returns false.
89   // May not make such a call if filter policy says that key is not present.
90   //
91   // get_context->MarkKeyMayExist needs to be called when it is configured to be
92   // memory only and the key is not found in the block cache.
93   //
94   // readOptions is the options for the read
95   // key is the key to search for
96   // skip_filters: disables checking the bloom filters even if they exist. This
97   //               option is effective only for block-based table format.
98   virtual Status Get(const ReadOptions& readOptions, const Slice& key,
99                      GetContext* get_context,
100                      const SliceTransform* prefix_extractor,
101                      bool skip_filters = false) = 0;
102 
103   virtual void MultiGet(const ReadOptions& readOptions,
104                         const MultiGetContext::Range* mget_range,
105                         const SliceTransform* prefix_extractor,
106                         bool skip_filters = false) {
107     for (auto iter = mget_range->begin(); iter != mget_range->end(); ++iter) {
108       *iter->s = Get(readOptions, iter->ikey, iter->get_context,
109                      prefix_extractor, skip_filters);
110     }
111   }
112 
113   // Prefetch data corresponding to a give range of keys
114   // Typically this functionality is required for table implementations that
115   // persists the data on a non volatile storage medium like disk/SSD
116   virtual Status Prefetch(const Slice* begin = nullptr,
117                           const Slice* end = nullptr) {
118     (void) begin;
119     (void) end;
120     // Default implementation is NOOP.
121     // The child class should implement functionality when applicable
122     return Status::OK();
123   }
124 
125   // convert db file to a human readable form
DumpTable(WritableFile *)126   virtual Status DumpTable(WritableFile* /*out_file*/) {
127     return Status::NotSupported("DumpTable() not supported");
128   }
129 
130   // check whether there is corruption in this db file
VerifyChecksum(const ReadOptions &,TableReaderCaller)131   virtual Status VerifyChecksum(const ReadOptions& /*read_options*/,
132                                 TableReaderCaller /*caller*/) {
133     return Status::NotSupported("VerifyChecksum() not supported");
134   }
135 };
136 
137 }  // namespace ROCKSDB_NAMESPACE
138