mock_table.h 6.1 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
stl_wrappers::KVMap MakeMockFile(
    std::vector<std::pair<const std::string, std::string>> l);
33 34 35

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

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

43
  InternalIterator* NewIterator(const ReadOptions&,
44 45
                                const SliceTransform* prefix_extractor,
                                Arena* arena = nullptr,
46 47
                                bool skip_filters = false,
                                bool for_compaction = false) override;
48

49 50
  Status Get(const ReadOptions& readOptions, const Slice& key,
             GetContext* get_context, const SliceTransform* prefix_extractor,
51
             bool skip_filters = false) override;
52

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

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

  void SetupForCompaction() override {}

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

  ~MockTableReader() {}

 private:
64
  const stl_wrappers::KVMap& table_;
65 66
};

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

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

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

I
Igor Sugak 已提交
77
  void SeekToLast() override {
78 79 80 81
    itr_ = table_.end();
    --itr_;
  }

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

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

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

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

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

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

I
Igor Sugak 已提交
107
  Status status() const override { return Status::OK(); }
108 109

 private:
110 111
  const stl_wrappers::KVMap& table_;
  stl_wrappers::KVMap::const_iterator itr_;
112 113 114 115
};

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

  // 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(); }

146 147 148 149
  TableProperties GetTableProperties() const override {
    return TableProperties();
  }

150 151 152
 private:
  uint32_t id_;
  MockTableFileSystem* file_system_;
153
  stl_wrappers::KVMap table_;
154 155 156 157 158 159
};

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

I
Igor Canadi 已提交
169
  // This function will directly create mock table instead of going through
170 171
  // 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 已提交
172
  Status CreateMockTable(Env* env, const std::string& fname,
173
                         stl_wrappers::KVMap file_contents);
I
Igor Canadi 已提交
174

I
Igor Sugak 已提交
175
  virtual Status SanitizeOptions(
A
Andrew Kryczka 已提交
176 177
      const DBOptions& /*db_opts*/,
      const ColumnFamilyOptions& /*cf_opts*/) const override {
178 179 180 181 182 183 184 185 186
    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
187 188
  void AssertSingleFile(const stl_wrappers::KVMap& file_contents);
  void AssertLatestFile(const stl_wrappers::KVMap& file_contents);
189 190 191 192 193 194
  stl_wrappers::KVMap output() {
    assert(!file_system_.files.empty());
    auto latest = file_system_.files.end();
    --latest;
    return latest->second;
  }
195 196

 private:
D
Dmitri Smirnov 已提交
197
  uint32_t GetAndWriteNextID(WritableFileWriter* file) const;
198
  uint32_t GetIDFromFile(RandomAccessFileReader* file) const;
199 200 201 202 203

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

I
Igor Canadi 已提交
204
}  // namespace mock
205
}  // namespace rocksdb