mock_table.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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. #pragma once
  6. #include <algorithm>
  7. #include <atomic>
  8. #include <map>
  9. #include <memory>
  10. #include <set>
  11. #include <string>
  12. #include <utility>
  13. #include "db/version_edit.h"
  14. #include "port/port.h"
  15. #include "rocksdb/comparator.h"
  16. #include "rocksdb/table.h"
  17. #include "table/internal_iterator.h"
  18. #include "table/table_builder.h"
  19. #include "table/table_reader.h"
  20. #include "test_util/testharness.h"
  21. #include "test_util/testutil.h"
  22. #include "util/kv_map.h"
  23. #include "util/mutexlock.h"
  24. namespace ROCKSDB_NAMESPACE {
  25. namespace mock {
  26. stl_wrappers::KVMap MakeMockFile(
  27. std::initializer_list<std::pair<const std::string, std::string>> l = {});
  28. struct MockTableFileSystem {
  29. port::Mutex mutex;
  30. std::map<uint32_t, stl_wrappers::KVMap> files;
  31. };
  32. class MockTableReader : public TableReader {
  33. public:
  34. explicit MockTableReader(const stl_wrappers::KVMap& table) : table_(table) {}
  35. InternalIterator* NewIterator(const ReadOptions&,
  36. const SliceTransform* prefix_extractor,
  37. Arena* arena, bool skip_filters,
  38. TableReaderCaller caller,
  39. size_t compaction_readahead_size = 0) override;
  40. Status Get(const ReadOptions& readOptions, const Slice& key,
  41. GetContext* get_context, const SliceTransform* prefix_extractor,
  42. bool skip_filters = false) override;
  43. uint64_t ApproximateOffsetOf(const Slice& /*key*/,
  44. TableReaderCaller /*caller*/) override {
  45. return 0;
  46. }
  47. uint64_t ApproximateSize(const Slice& /*start*/, const Slice& /*end*/,
  48. TableReaderCaller /*caller*/) override {
  49. return 0;
  50. }
  51. size_t ApproximateMemoryUsage() const override { return 0; }
  52. void SetupForCompaction() override {}
  53. std::shared_ptr<const TableProperties> GetTableProperties() const override;
  54. ~MockTableReader() {}
  55. private:
  56. const stl_wrappers::KVMap& table_;
  57. };
  58. class MockTableIterator : public InternalIterator {
  59. public:
  60. explicit MockTableIterator(const stl_wrappers::KVMap& table) : table_(table) {
  61. itr_ = table_.end();
  62. }
  63. bool Valid() const override { return itr_ != table_.end(); }
  64. void SeekToFirst() override { itr_ = table_.begin(); }
  65. void SeekToLast() override {
  66. itr_ = table_.end();
  67. --itr_;
  68. }
  69. void Seek(const Slice& target) override {
  70. std::string str_target(target.data(), target.size());
  71. itr_ = table_.lower_bound(str_target);
  72. }
  73. void SeekForPrev(const Slice& target) override {
  74. std::string str_target(target.data(), target.size());
  75. itr_ = table_.upper_bound(str_target);
  76. Prev();
  77. }
  78. void Next() override { ++itr_; }
  79. void Prev() override {
  80. if (itr_ == table_.begin()) {
  81. itr_ = table_.end();
  82. } else {
  83. --itr_;
  84. }
  85. }
  86. Slice key() const override { return Slice(itr_->first); }
  87. Slice value() const override { return Slice(itr_->second); }
  88. Status status() const override { return Status::OK(); }
  89. private:
  90. const stl_wrappers::KVMap& table_;
  91. stl_wrappers::KVMap::const_iterator itr_;
  92. };
  93. class MockTableBuilder : public TableBuilder {
  94. public:
  95. MockTableBuilder(uint32_t id, MockTableFileSystem* file_system)
  96. : id_(id), file_system_(file_system) {
  97. table_ = MakeMockFile({});
  98. }
  99. // REQUIRES: Either Finish() or Abandon() has been called.
  100. ~MockTableBuilder() {}
  101. // Add key,value to the table being constructed.
  102. // REQUIRES: key is after any previously added key according to comparator.
  103. // REQUIRES: Finish(), Abandon() have not been called
  104. void Add(const Slice& key, const Slice& value) override {
  105. table_.insert({key.ToString(), value.ToString()});
  106. }
  107. // Return non-ok iff some error has been detected.
  108. Status status() const override { return Status::OK(); }
  109. Status Finish() override {
  110. MutexLock lock_guard(&file_system_->mutex);
  111. file_system_->files.insert({id_, table_});
  112. return Status::OK();
  113. }
  114. void Abandon() override {}
  115. uint64_t NumEntries() const override { return table_.size(); }
  116. uint64_t FileSize() const override { return table_.size(); }
  117. TableProperties GetTableProperties() const override {
  118. return TableProperties();
  119. }
  120. // Get file checksum
  121. const std::string& GetFileChecksum() const override { return file_checksum_; }
  122. // Get file checksum function name
  123. const char* GetFileChecksumFuncName() const override {
  124. return kUnknownFileChecksumFuncName.c_str();
  125. }
  126. private:
  127. uint32_t id_;
  128. MockTableFileSystem* file_system_;
  129. stl_wrappers::KVMap table_;
  130. std::string file_checksum_ = kUnknownFileChecksum;
  131. };
  132. class MockTableFactory : public TableFactory {
  133. public:
  134. MockTableFactory();
  135. const char* Name() const override { return "MockTable"; }
  136. Status NewTableReader(
  137. const TableReaderOptions& table_reader_options,
  138. std::unique_ptr<RandomAccessFileReader>&& file, uint64_t file_size,
  139. std::unique_ptr<TableReader>* table_reader,
  140. bool prefetch_index_and_filter_in_cache = true) const override;
  141. TableBuilder* NewTableBuilder(
  142. const TableBuilderOptions& table_builder_options,
  143. uint32_t column_familly_id, WritableFileWriter* file) const override;
  144. // This function will directly create mock table instead of going through
  145. // MockTableBuilder. file_contents has to have a format of <internal_key,
  146. // value>. Those key-value pairs will then be inserted into the mock table.
  147. Status CreateMockTable(Env* env, const std::string& fname,
  148. stl_wrappers::KVMap file_contents);
  149. virtual Status SanitizeOptions(
  150. const DBOptions& /*db_opts*/,
  151. const ColumnFamilyOptions& /*cf_opts*/) const override {
  152. return Status::OK();
  153. }
  154. virtual std::string GetPrintableTableOptions() const override {
  155. return std::string();
  156. }
  157. // This function will assert that only a single file exists and that the
  158. // contents are equal to file_contents
  159. void AssertSingleFile(const stl_wrappers::KVMap& file_contents);
  160. void AssertLatestFile(const stl_wrappers::KVMap& file_contents);
  161. private:
  162. uint32_t GetAndWriteNextID(WritableFileWriter* file) const;
  163. uint32_t GetIDFromFile(RandomAccessFileReader* file) const;
  164. mutable MockTableFileSystem file_system_;
  165. mutable std::atomic<uint32_t> next_id_;
  166. };
  167. } // namespace mock
  168. } // namespace ROCKSDB_NAMESPACE