mock_table.h 5.8 KB
Newer Older
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
S
Siying Dong 已提交
2 3 4
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).
5
#pragma once
6

7
#include <algorithm>
I
Igor Canadi 已提交
8
#include <atomic>
9
#include <map>
10 11
#include <memory>
#include <set>
12
#include <string>
13
#include <utility>
14

15
#include "util/kv_map.h"
16
#include "port/port.h"
A
Andres Notzli 已提交
17
#include "rocksdb/comparator.h"
18
#include "rocksdb/table.h"
S
sdong 已提交
19
#include "table/internal_iterator.h"
20
#include "table/table_builder.h"
21
#include "table/table_reader.h"
22 23 24 25 26
#include "util/mutexlock.h"
#include "util/testharness.h"
#include "util/testutil.h"

namespace rocksdb {
I
Igor Canadi 已提交
27
namespace mock {
28

29 30
stl_wrappers::KVMap MakeMockFile(
    std::initializer_list<std::pair<const std::string, std::string>> l = {});
31 32 33

struct MockTableFileSystem {
  port::Mutex mutex;
34
  std::map<uint32_t, stl_wrappers::KVMap> files;
35 36 37 38
};

class MockTableReader : public TableReader {
 public:
39
  explicit MockTableReader(const stl_wrappers::KVMap& table) : table_(table) {}
40

41
  InternalIterator* NewIterator(const ReadOptions&,
42 43
                                const SliceTransform* prefix_extractor,
                                Arena* arena = nullptr,
44
                                bool skip_filters = false) override;
45

46 47
  Status Get(const ReadOptions& readOptions, const Slice& key,
             GetContext* get_context, const SliceTransform* prefix_extractor,
48
             bool skip_filters = false) override;
49

A
Andrew Kryczka 已提交
50
  uint64_t ApproximateOffsetOf(const Slice& /*key*/) override { return 0; }
51 52 53 54 55 56 57 58 59 60

  virtual size_t ApproximateMemoryUsage() const override { return 0; }

  void SetupForCompaction() override {}

  std::shared_ptr<const TableProperties> GetTableProperties() const override;

  ~MockTableReader() {}

 private:
61
  const stl_wrappers::KVMap& table_;
62 63
};

S
sdong 已提交
64
class MockTableIterator : public InternalIterator {
65
 public:
66
  explicit MockTableIterator(const stl_wrappers::KVMap& table) : table_(table) {
67 68 69
    itr_ = table_.end();
  }

I
Igor Sugak 已提交
70
  bool Valid() const override { return itr_ != table_.end(); }
71

I
Igor Sugak 已提交
72
  void SeekToFirst() override { itr_ = table_.begin(); }
73

I
Igor Sugak 已提交
74
  void SeekToLast() override {
75 76 77 78
    itr_ = table_.end();
    --itr_;
  }

I
Igor Sugak 已提交
79
  void Seek(const Slice& target) override {
80 81 82 83
    std::string str_target(target.data(), target.size());
    itr_ = table_.lower_bound(str_target);
  }

A
Aaron Gao 已提交
84 85 86 87 88 89
  void SeekForPrev(const Slice& target) override {
    std::string str_target(target.data(), target.size());
    itr_ = table_.upper_bound(str_target);
    Prev();
  }

I
Igor Sugak 已提交
90
  void Next() override { ++itr_; }
91

I
Igor Sugak 已提交
92
  void Prev() override {
93 94 95 96 97 98 99
    if (itr_ == table_.begin()) {
      itr_ = table_.end();
    } else {
      --itr_;
    }
  }

I
Igor Sugak 已提交
100
  Slice key() const override { return Slice(itr_->first); }
101

I
Igor Sugak 已提交
102
  Slice value() const override { return Slice(itr_->second); }
103

I
Igor Sugak 已提交
104
  Status status() const override { return Status::OK(); }
105 106

 private:
107 108
  const stl_wrappers::KVMap& table_;
  stl_wrappers::KVMap::const_iterator itr_;
109 110 111 112
};

class MockTableBuilder : public TableBuilder {
 public:
113
  MockTableBuilder(uint32_t id, MockTableFileSystem* file_system)
114 115 116
      : id_(id), file_system_(file_system) {
    table_ = MakeMockFile({});
  }
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142

  // REQUIRES: Either Finish() or Abandon() has been called.
  ~MockTableBuilder() {}

  // Add key,value to the table being constructed.
  // REQUIRES: key is after any previously added key according to comparator.
  // REQUIRES: Finish(), Abandon() have not been called
  void Add(const Slice& key, const Slice& value) override {
    table_.insert({key.ToString(), value.ToString()});
  }

  // Return non-ok iff some error has been detected.
  Status status() const override { return Status::OK(); }

  Status Finish() override {
    MutexLock lock_guard(&file_system_->mutex);
    file_system_->files.insert({id_, table_});
    return Status::OK();
  }

  void Abandon() override {}

  uint64_t NumEntries() const override { return table_.size(); }

  uint64_t FileSize() const override { return table_.size(); }

143 144 145 146
  TableProperties GetTableProperties() const override {
    return TableProperties();
  }

147 148 149
 private:
  uint32_t id_;
  MockTableFileSystem* file_system_;
150
  stl_wrappers::KVMap table_;
151 152 153 154 155 156
};

class MockTableFactory : public TableFactory {
 public:
  MockTableFactory();
  const char* Name() const override { return "MockTable"; }
157 158 159 160 161
  Status NewTableReader(
      const TableReaderOptions& table_reader_options,
      unique_ptr<RandomAccessFileReader>&& file, uint64_t file_size,
      unique_ptr<TableReader>* table_reader,
      bool prefetch_index_and_filter_in_cache = true) const override;
162 163
  TableBuilder* NewTableBuilder(
      const TableBuilderOptions& table_builder_options,
164
      uint32_t column_familly_id, WritableFileWriter* file) const override;
165

I
Igor Canadi 已提交
166
  // This function will directly create mock table instead of going through
167 168
  // MockTableBuilder. file_contents has to have a format of <internal_key,
  // value>. Those key-value pairs will then be inserted into the mock table.
I
Igor Canadi 已提交
169
  Status CreateMockTable(Env* env, const std::string& fname,
170
                         stl_wrappers::KVMap file_contents);
I
Igor Canadi 已提交
171

I
Igor Sugak 已提交
172
  virtual Status SanitizeOptions(
A
Andrew Kryczka 已提交
173 174
      const DBOptions& /*db_opts*/,
      const ColumnFamilyOptions& /*cf_opts*/) const override {
175 176 177 178 179 180 181 182 183
    return Status::OK();
  }

  virtual std::string GetPrintableTableOptions() const override {
    return std::string();
  }

  // This function will assert that only a single file exists and that the
  // contents are equal to file_contents
184 185
  void AssertSingleFile(const stl_wrappers::KVMap& file_contents);
  void AssertLatestFile(const stl_wrappers::KVMap& file_contents);
186 187

 private:
D
Dmitri Smirnov 已提交
188
  uint32_t GetAndWriteNextID(WritableFileWriter* file) const;
189
  uint32_t GetIDFromFile(RandomAccessFileReader* file) const;
190 191 192 193 194

  mutable MockTableFileSystem file_system_;
  mutable std::atomic<uint32_t> next_id_;
};

I
Igor Canadi 已提交
195
}  // namespace mock
196
}  // namespace rocksdb