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).
6 #include "table/mock_table.h"
8 #include "db/dbformat.h"
10 #include "rocksdb/table_properties.h"
11 #include "table/get_context.h"
12 #include "util/coding.h"
13 #include "util/file_reader_writer.h"
20 const InternalKeyComparator
icmp_(BytewiseComparator());
24 stl_wrappers::KVMap
MakeMockFile(
25 std::initializer_list
<std::pair
<const std::string
, std::string
>> l
) {
26 return stl_wrappers::KVMap(l
, stl_wrappers::LessOfComparator(&icmp_
));
29 InternalIterator
* MockTableReader::NewIterator(
30 const ReadOptions
&, const SliceTransform
* /* prefix_extractor */,
31 Arena
* /*arena*/, bool /*skip_filters*/, bool /*for_compaction*/) {
32 return new MockTableIterator(table_
);
35 Status
MockTableReader::Get(const ReadOptions
&, const Slice
& key
,
36 GetContext
* get_context
,
37 const SliceTransform
* /*prefix_extractor*/,
38 bool /*skip_filters*/) {
39 std::unique_ptr
<MockTableIterator
> iter(new MockTableIterator(table_
));
40 for (iter
->Seek(key
); iter
->Valid(); iter
->Next()) {
41 ParsedInternalKey parsed_key
;
42 if (!ParseInternalKey(iter
->key(), &parsed_key
)) {
43 return Status::Corruption(Slice());
46 bool dont_care
__attribute__((__unused__
));
47 if (!get_context
->SaveValue(parsed_key
, iter
->value(), &dont_care
)) {
54 std::shared_ptr
<const TableProperties
> MockTableReader::GetTableProperties()
56 return std::shared_ptr
<const TableProperties
>(new TableProperties());
59 MockTableFactory::MockTableFactory() : next_id_(1) {}
61 Status
MockTableFactory::NewTableReader(
62 const TableReaderOptions
& /*table_reader_options*/,
63 std::unique_ptr
<RandomAccessFileReader
>&& file
, uint64_t /*file_size*/,
64 std::unique_ptr
<TableReader
>* table_reader
,
65 bool /*prefetch_index_and_filter_in_cache*/) const {
66 uint32_t id
= GetIDFromFile(file
.get());
68 MutexLock
lock_guard(&file_system_
.mutex
);
70 auto it
= file_system_
.files
.find(id
);
71 if (it
== file_system_
.files
.end()) {
72 return Status::IOError("Mock file not found");
75 table_reader
->reset(new MockTableReader(it
->second
));
80 TableBuilder
* MockTableFactory::NewTableBuilder(
81 const TableBuilderOptions
& /*table_builder_options*/,
82 uint32_t /*column_family_id*/, WritableFileWriter
* file
) const {
83 uint32_t id
= GetAndWriteNextID(file
);
85 return new MockTableBuilder(id
, &file_system_
);
88 Status
MockTableFactory::CreateMockTable(Env
* env
, const std::string
& fname
,
89 stl_wrappers::KVMap file_contents
) {
90 std::unique_ptr
<WritableFile
> file
;
91 auto s
= env
->NewWritableFile(fname
, &file
, EnvOptions());
96 WritableFileWriter
file_writer(std::move(file
), fname
, EnvOptions());
98 uint32_t id
= GetAndWriteNextID(&file_writer
);
99 file_system_
.files
.insert({id
, std::move(file_contents
)});
103 uint32_t MockTableFactory::GetAndWriteNextID(WritableFileWriter
* file
) const {
104 uint32_t next_id
= next_id_
.fetch_add(1);
106 EncodeFixed32(buf
, next_id
);
107 file
->Append(Slice(buf
, 4));
111 uint32_t MockTableFactory::GetIDFromFile(RandomAccessFileReader
* file
) const {
114 file
->Read(0, 4, &result
, buf
);
115 assert(result
.size() == 4);
116 return DecodeFixed32(buf
);
119 void MockTableFactory::AssertSingleFile(
120 const stl_wrappers::KVMap
& file_contents
) {
121 ASSERT_EQ(file_system_
.files
.size(), 1U);
122 ASSERT_EQ(file_contents
, file_system_
.files
.begin()->second
);
125 void MockTableFactory::AssertLatestFile(
126 const stl_wrappers::KVMap
& file_contents
) {
127 ASSERT_GE(file_system_
.files
.size(), 1U);
128 auto latest
= file_system_
.files
.end();
131 if (file_contents
!= latest
->second
) {
132 std::cout
<< "Wrong content! Content of latest file:" << std::endl
;
133 for (const auto& kv
: latest
->second
) {
134 ParsedInternalKey ikey
;
135 std::string key
, value
;
136 std::tie(key
, value
) = kv
;
137 ParseInternalKey(Slice(key
), &ikey
);
138 std::cout
<< ikey
.DebugString(false) << " -> " << value
<< std::endl
;
145 } // namespace rocksdb