]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
11fdf7f2 TL |
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). | |
7c673cae | 5 | |
20effc67 TL |
6 | #include "db/table_properties_collector.h" |
7 | ||
7c673cae FG |
8 | #include <map> |
9 | #include <memory> | |
10 | #include <string> | |
11 | #include <utility> | |
12 | #include <vector> | |
13 | ||
f67539c2 | 14 | #include "db/db_impl/db_impl.h" |
7c673cae | 15 | #include "db/dbformat.h" |
f67539c2 TL |
16 | #include "file/sequence_file_reader.h" |
17 | #include "file/writable_file_writer.h" | |
7c673cae | 18 | #include "options/cf_options.h" |
20effc67 | 19 | #include "rocksdb/flush_block_policy.h" |
7c673cae | 20 | #include "rocksdb/table.h" |
f67539c2 | 21 | #include "table/block_based/block_based_table_factory.h" |
7c673cae | 22 | #include "table/meta_blocks.h" |
f67539c2 | 23 | #include "table/plain/plain_table_factory.h" |
7c673cae | 24 | #include "table/table_builder.h" |
f67539c2 TL |
25 | #include "test_util/testharness.h" |
26 | #include "test_util/testutil.h" | |
7c673cae | 27 | #include "util/coding.h" |
7c673cae | 28 | |
f67539c2 | 29 | namespace ROCKSDB_NAMESPACE { |
7c673cae FG |
30 | |
31 | class TablePropertiesTest : public testing::Test, | |
32 | public testing::WithParamInterface<bool> { | |
33 | public: | |
494da23a | 34 | void SetUp() override { backward_mode_ = GetParam(); } |
7c673cae FG |
35 | |
36 | bool backward_mode_; | |
37 | }; | |
38 | ||
39 | // Utilities test functions | |
40 | namespace { | |
41 | static const uint32_t kTestColumnFamilyId = 66; | |
42 | static const std::string kTestColumnFamilyName = "test_column_fam"; | |
1e59de90 TL |
43 | static const int kTestLevel = 1; |
44 | ||
45 | void MakeBuilder( | |
46 | const Options& options, const ImmutableOptions& ioptions, | |
47 | const MutableCFOptions& moptions, | |
48 | const InternalKeyComparator& internal_comparator, | |
49 | const IntTblPropCollectorFactories* int_tbl_prop_collector_factories, | |
50 | std::unique_ptr<WritableFileWriter>* writable, | |
51 | std::unique_ptr<TableBuilder>* builder) { | |
52 | std::unique_ptr<FSWritableFile> wf(new test::StringSink); | |
11fdf7f2 | 53 | writable->reset( |
1e59de90 TL |
54 | new WritableFileWriter(std::move(wf), "" /* don't care */, EnvOptions())); |
55 | TableBuilderOptions tboptions( | |
11fdf7f2 | 56 | ioptions, moptions, internal_comparator, int_tbl_prop_collector_factories, |
1e59de90 TL |
57 | options.compression, options.compression_opts, kTestColumnFamilyId, |
58 | kTestColumnFamilyName, kTestLevel); | |
59 | builder->reset(NewTableBuilder(tboptions, writable->get())); | |
7c673cae FG |
60 | } |
61 | } // namespace | |
62 | ||
63 | // Collects keys that starts with "A" in a table. | |
1e59de90 | 64 | class RegularKeysStartWithA : public TablePropertiesCollector { |
7c673cae FG |
65 | public: |
66 | const char* Name() const override { return "RegularKeysStartWithA"; } | |
67 | ||
68 | Status Finish(UserCollectedProperties* properties) override { | |
1e59de90 TL |
69 | std::string encoded; |
70 | std::string encoded_num_puts; | |
71 | std::string encoded_num_deletes; | |
72 | std::string encoded_num_single_deletes; | |
73 | std::string encoded_num_size_changes; | |
74 | PutVarint32(&encoded, count_); | |
75 | PutVarint32(&encoded_num_puts, num_puts_); | |
76 | PutVarint32(&encoded_num_deletes, num_deletes_); | |
77 | PutVarint32(&encoded_num_single_deletes, num_single_deletes_); | |
78 | PutVarint32(&encoded_num_size_changes, num_size_changes_); | |
79 | *properties = UserCollectedProperties{ | |
80 | {"TablePropertiesTest", message_}, | |
81 | {"Count", encoded}, | |
82 | {"NumPuts", encoded_num_puts}, | |
83 | {"NumDeletes", encoded_num_deletes}, | |
84 | {"NumSingleDeletes", encoded_num_single_deletes}, | |
85 | {"NumSizeChanges", encoded_num_size_changes}, | |
86 | }; | |
87 | return Status::OK(); | |
7c673cae FG |
88 | } |
89 | ||
11fdf7f2 TL |
90 | Status AddUserKey(const Slice& user_key, const Slice& /*value*/, |
91 | EntryType type, SequenceNumber /*seq*/, | |
92 | uint64_t file_size) override { | |
7c673cae FG |
93 | // simply asssume all user keys are not empty. |
94 | if (user_key.data()[0] == 'A') { | |
95 | ++count_; | |
96 | } | |
97 | if (type == kEntryPut) { | |
98 | num_puts_++; | |
99 | } else if (type == kEntryDelete) { | |
100 | num_deletes_++; | |
101 | } else if (type == kEntrySingleDelete) { | |
102 | num_single_deletes_++; | |
103 | } | |
104 | if (file_size < file_size_) { | |
105 | message_ = "File size should not decrease."; | |
106 | } else if (file_size != file_size_) { | |
107 | num_size_changes_++; | |
108 | } | |
109 | ||
110 | return Status::OK(); | |
111 | } | |
112 | ||
494da23a | 113 | UserCollectedProperties GetReadableProperties() const override { |
7c673cae FG |
114 | return UserCollectedProperties{}; |
115 | } | |
116 | ||
117 | private: | |
118 | std::string message_ = "Rocksdb"; | |
119 | uint32_t count_ = 0; | |
120 | uint32_t num_puts_ = 0; | |
121 | uint32_t num_deletes_ = 0; | |
122 | uint32_t num_single_deletes_ = 0; | |
123 | uint32_t num_size_changes_ = 0; | |
124 | uint64_t file_size_ = 0; | |
125 | }; | |
126 | ||
127 | // Collects keys that starts with "A" in a table. Backward compatible mode | |
128 | // It is also used to test internal key table property collector | |
129 | class RegularKeysStartWithABackwardCompatible | |
130 | : public TablePropertiesCollector { | |
131 | public: | |
132 | const char* Name() const override { return "RegularKeysStartWithA"; } | |
133 | ||
134 | Status Finish(UserCollectedProperties* properties) override { | |
135 | std::string encoded; | |
136 | PutVarint32(&encoded, count_); | |
137 | *properties = UserCollectedProperties{{"TablePropertiesTest", "Rocksdb"}, | |
138 | {"Count", encoded}}; | |
139 | return Status::OK(); | |
140 | } | |
141 | ||
11fdf7f2 | 142 | Status Add(const Slice& user_key, const Slice& /*value*/) override { |
7c673cae FG |
143 | // simply asssume all user keys are not empty. |
144 | if (user_key.data()[0] == 'A') { | |
145 | ++count_; | |
146 | } | |
147 | return Status::OK(); | |
148 | } | |
149 | ||
494da23a | 150 | UserCollectedProperties GetReadableProperties() const override { |
7c673cae FG |
151 | return UserCollectedProperties{}; |
152 | } | |
153 | ||
154 | private: | |
155 | uint32_t count_ = 0; | |
156 | }; | |
157 | ||
158 | class RegularKeysStartWithAInternal : public IntTblPropCollector { | |
159 | public: | |
160 | const char* Name() const override { return "RegularKeysStartWithA"; } | |
161 | ||
162 | Status Finish(UserCollectedProperties* properties) override { | |
163 | std::string encoded; | |
164 | PutVarint32(&encoded, count_); | |
165 | *properties = UserCollectedProperties{{"TablePropertiesTest", "Rocksdb"}, | |
166 | {"Count", encoded}}; | |
167 | return Status::OK(); | |
168 | } | |
169 | ||
11fdf7f2 TL |
170 | Status InternalAdd(const Slice& user_key, const Slice& /*value*/, |
171 | uint64_t /*file_size*/) override { | |
7c673cae FG |
172 | // simply asssume all user keys are not empty. |
173 | if (user_key.data()[0] == 'A') { | |
174 | ++count_; | |
175 | } | |
176 | return Status::OK(); | |
177 | } | |
178 | ||
1e59de90 TL |
179 | void BlockAdd(uint64_t /* block_uncomp_bytes */, |
180 | uint64_t /* block_compressed_bytes_fast */, | |
181 | uint64_t /* block_compressed_bytes_slow */) override { | |
494da23a TL |
182 | // Nothing to do. |
183 | return; | |
184 | } | |
185 | ||
186 | UserCollectedProperties GetReadableProperties() const override { | |
7c673cae FG |
187 | return UserCollectedProperties{}; |
188 | } | |
189 | ||
190 | private: | |
191 | uint32_t count_ = 0; | |
192 | }; | |
193 | ||
194 | class RegularKeysStartWithAFactory : public IntTblPropCollectorFactory, | |
195 | public TablePropertiesCollectorFactory { | |
196 | public: | |
197 | explicit RegularKeysStartWithAFactory(bool backward_mode) | |
198 | : backward_mode_(backward_mode) {} | |
494da23a | 199 | TablePropertiesCollector* CreateTablePropertiesCollector( |
7c673cae FG |
200 | TablePropertiesCollectorFactory::Context context) override { |
201 | EXPECT_EQ(kTestColumnFamilyId, context.column_family_id); | |
1e59de90 | 202 | EXPECT_EQ(kTestLevel, context.level_at_creation); |
7c673cae FG |
203 | if (!backward_mode_) { |
204 | return new RegularKeysStartWithA(); | |
205 | } else { | |
206 | return new RegularKeysStartWithABackwardCompatible(); | |
207 | } | |
208 | } | |
494da23a | 209 | IntTblPropCollector* CreateIntTblPropCollector( |
1e59de90 | 210 | uint32_t /*column_family_id*/, int /* level_at_creation */) override { |
7c673cae FG |
211 | return new RegularKeysStartWithAInternal(); |
212 | } | |
213 | const char* Name() const override { return "RegularKeysStartWithA"; } | |
214 | ||
215 | bool backward_mode_; | |
216 | }; | |
217 | ||
218 | class FlushBlockEveryThreePolicy : public FlushBlockPolicy { | |
219 | public: | |
494da23a | 220 | bool Update(const Slice& /*key*/, const Slice& /*value*/) override { |
7c673cae FG |
221 | return (++count_ % 3U == 0); |
222 | } | |
223 | ||
224 | private: | |
225 | uint64_t count_ = 0; | |
226 | }; | |
227 | ||
228 | class FlushBlockEveryThreePolicyFactory : public FlushBlockPolicyFactory { | |
229 | public: | |
230 | explicit FlushBlockEveryThreePolicyFactory() {} | |
231 | ||
232 | const char* Name() const override { | |
233 | return "FlushBlockEveryThreePolicyFactory"; | |
234 | } | |
235 | ||
236 | FlushBlockPolicy* NewFlushBlockPolicy( | |
11fdf7f2 TL |
237 | const BlockBasedTableOptions& /*table_options*/, |
238 | const BlockBuilder& /*data_block_builder*/) const override { | |
7c673cae FG |
239 | return new FlushBlockEveryThreePolicy; |
240 | } | |
241 | }; | |
242 | ||
243 | extern const uint64_t kBlockBasedTableMagicNumber; | |
244 | extern const uint64_t kPlainTableMagicNumber; | |
245 | namespace { | |
246 | void TestCustomizedTablePropertiesCollector( | |
247 | bool backward_mode, uint64_t magic_number, bool test_int_tbl_prop_collector, | |
248 | const Options& options, const InternalKeyComparator& internal_comparator) { | |
249 | // make sure the entries will be inserted with order. | |
250 | std::map<std::pair<std::string, ValueType>, std::string> kvs = { | |
251 | {{"About ", kTypeValue}, "val5"}, // starts with 'A' | |
252 | {{"Abstract", kTypeValue}, "val2"}, // starts with 'A' | |
253 | {{"Around ", kTypeValue}, "val7"}, // starts with 'A' | |
254 | {{"Beyond ", kTypeValue}, "val3"}, | |
255 | {{"Builder ", kTypeValue}, "val1"}, | |
256 | {{"Love ", kTypeDeletion}, ""}, | |
257 | {{"Cancel ", kTypeValue}, "val4"}, | |
258 | {{"Find ", kTypeValue}, "val6"}, | |
259 | {{"Rocks ", kTypeDeletion}, ""}, | |
260 | {{"Foo ", kTypeSingleDeletion}, ""}, | |
261 | }; | |
262 | ||
263 | // -- Step 1: build table | |
264 | std::unique_ptr<TableBuilder> builder; | |
265 | std::unique_ptr<WritableFileWriter> writer; | |
1e59de90 | 266 | const ImmutableOptions ioptions(options); |
11fdf7f2 | 267 | const MutableCFOptions moptions(options); |
1e59de90 | 268 | IntTblPropCollectorFactories int_tbl_prop_collector_factories; |
7c673cae FG |
269 | if (test_int_tbl_prop_collector) { |
270 | int_tbl_prop_collector_factories.emplace_back( | |
271 | new RegularKeysStartWithAFactory(backward_mode)); | |
272 | } else { | |
273 | GetIntTblPropCollectorFactory(ioptions, &int_tbl_prop_collector_factories); | |
274 | } | |
11fdf7f2 | 275 | MakeBuilder(options, ioptions, moptions, internal_comparator, |
7c673cae FG |
276 | &int_tbl_prop_collector_factories, &writer, &builder); |
277 | ||
278 | SequenceNumber seqNum = 0U; | |
279 | for (const auto& kv : kvs) { | |
280 | InternalKey ikey(kv.first.first, seqNum++, kv.first.second); | |
281 | builder->Add(ikey.Encode(), kv.second); | |
282 | } | |
283 | ASSERT_OK(builder->Finish()); | |
1e59de90 | 284 | ASSERT_OK(writer->Flush()); |
7c673cae FG |
285 | |
286 | // -- Step 2: Read properties | |
1e59de90 TL |
287 | test::StringSink* fwf = |
288 | static_cast<test::StringSink*>(writer->writable_file()); | |
289 | std::unique_ptr<FSRandomAccessFile> source( | |
290 | new test::StringSource(fwf->contents())); | |
7c673cae | 291 | std::unique_ptr<RandomAccessFileReader> fake_file_reader( |
1e59de90 TL |
292 | new RandomAccessFileReader(std::move(source), "test")); |
293 | ||
294 | std::unique_ptr<TableProperties> props; | |
7c673cae | 295 | Status s = ReadTableProperties(fake_file_reader.get(), fwf->contents().size(), |
1e59de90 | 296 | magic_number, ioptions, &props); |
7c673cae FG |
297 | ASSERT_OK(s); |
298 | ||
299 | auto user_collected = props->user_collected_properties; | |
300 | ||
301 | ASSERT_NE(user_collected.find("TablePropertiesTest"), user_collected.end()); | |
302 | ASSERT_EQ("Rocksdb", user_collected.at("TablePropertiesTest")); | |
303 | ||
304 | uint32_t starts_with_A = 0; | |
305 | ASSERT_NE(user_collected.find("Count"), user_collected.end()); | |
306 | Slice key(user_collected.at("Count")); | |
307 | ASSERT_TRUE(GetVarint32(&key, &starts_with_A)); | |
308 | ASSERT_EQ(3u, starts_with_A); | |
309 | ||
310 | if (!backward_mode && !test_int_tbl_prop_collector) { | |
311 | uint32_t num_puts; | |
312 | ASSERT_NE(user_collected.find("NumPuts"), user_collected.end()); | |
313 | Slice key_puts(user_collected.at("NumPuts")); | |
314 | ASSERT_TRUE(GetVarint32(&key_puts, &num_puts)); | |
315 | ASSERT_EQ(7u, num_puts); | |
316 | ||
317 | uint32_t num_deletes; | |
318 | ASSERT_NE(user_collected.find("NumDeletes"), user_collected.end()); | |
319 | Slice key_deletes(user_collected.at("NumDeletes")); | |
320 | ASSERT_TRUE(GetVarint32(&key_deletes, &num_deletes)); | |
321 | ASSERT_EQ(2u, num_deletes); | |
322 | ||
323 | uint32_t num_single_deletes; | |
324 | ASSERT_NE(user_collected.find("NumSingleDeletes"), user_collected.end()); | |
325 | Slice key_single_deletes(user_collected.at("NumSingleDeletes")); | |
326 | ASSERT_TRUE(GetVarint32(&key_single_deletes, &num_single_deletes)); | |
327 | ASSERT_EQ(1u, num_single_deletes); | |
328 | ||
329 | uint32_t num_size_changes; | |
330 | ASSERT_NE(user_collected.find("NumSizeChanges"), user_collected.end()); | |
331 | Slice key_size_changes(user_collected.at("NumSizeChanges")); | |
332 | ASSERT_TRUE(GetVarint32(&key_size_changes, &num_size_changes)); | |
333 | ASSERT_GE(num_size_changes, 2u); | |
334 | } | |
335 | } | |
336 | } // namespace | |
337 | ||
338 | TEST_P(TablePropertiesTest, CustomizedTablePropertiesCollector) { | |
339 | // Test properties collectors with internal keys or regular keys | |
340 | // for block based table | |
1e59de90 | 341 | for (bool encode_as_internal : {true, false}) { |
7c673cae FG |
342 | Options options; |
343 | BlockBasedTableOptions table_options; | |
344 | table_options.flush_block_policy_factory = | |
345 | std::make_shared<FlushBlockEveryThreePolicyFactory>(); | |
346 | options.table_factory.reset(NewBlockBasedTableFactory(table_options)); | |
347 | ||
348 | test::PlainInternalKeyComparator ikc(options.comparator); | |
349 | std::shared_ptr<TablePropertiesCollectorFactory> collector_factory( | |
350 | new RegularKeysStartWithAFactory(backward_mode_)); | |
351 | options.table_properties_collector_factories.resize(1); | |
352 | options.table_properties_collector_factories[0] = collector_factory; | |
353 | ||
354 | TestCustomizedTablePropertiesCollector(backward_mode_, | |
355 | kBlockBasedTableMagicNumber, | |
356 | encode_as_internal, options, ikc); | |
357 | ||
358 | #ifndef ROCKSDB_LITE // PlainTable is not supported in Lite | |
359 | // test plain table | |
360 | PlainTableOptions plain_table_options; | |
361 | plain_table_options.user_key_len = 8; | |
362 | plain_table_options.bloom_bits_per_key = 8; | |
363 | plain_table_options.hash_table_ratio = 0; | |
364 | ||
365 | options.table_factory = | |
366 | std::make_shared<PlainTableFactory>(plain_table_options); | |
367 | TestCustomizedTablePropertiesCollector(backward_mode_, | |
368 | kPlainTableMagicNumber, | |
369 | encode_as_internal, options, ikc); | |
370 | #endif // !ROCKSDB_LITE | |
371 | } | |
372 | } | |
373 | ||
374 | namespace { | |
375 | void TestInternalKeyPropertiesCollector( | |
376 | bool backward_mode, uint64_t magic_number, bool sanitized, | |
377 | std::shared_ptr<TableFactory> table_factory) { | |
378 | InternalKey keys[] = { | |
379 | InternalKey("A ", 0, ValueType::kTypeValue), | |
380 | InternalKey("B ", 1, ValueType::kTypeValue), | |
381 | InternalKey("C ", 2, ValueType::kTypeValue), | |
382 | InternalKey("W ", 3, ValueType::kTypeDeletion), | |
383 | InternalKey("X ", 4, ValueType::kTypeDeletion), | |
384 | InternalKey("Y ", 5, ValueType::kTypeDeletion), | |
385 | InternalKey("Z ", 6, ValueType::kTypeDeletion), | |
386 | InternalKey("a ", 7, ValueType::kTypeSingleDeletion), | |
387 | InternalKey("b ", 8, ValueType::kTypeMerge), | |
388 | InternalKey("c ", 9, ValueType::kTypeMerge), | |
389 | }; | |
390 | ||
391 | std::unique_ptr<TableBuilder> builder; | |
392 | std::unique_ptr<WritableFileWriter> writable; | |
393 | Options options; | |
394 | test::PlainInternalKeyComparator pikc(options.comparator); | |
395 | ||
1e59de90 | 396 | IntTblPropCollectorFactories int_tbl_prop_collector_factories; |
7c673cae FG |
397 | options.table_factory = table_factory; |
398 | if (sanitized) { | |
399 | options.table_properties_collector_factories.emplace_back( | |
400 | new RegularKeysStartWithAFactory(backward_mode)); | |
401 | // with sanitization, even regular properties collector will be able to | |
402 | // handle internal keys. | |
403 | auto comparator = options.comparator; | |
404 | // HACK: Set options.info_log to avoid writing log in | |
405 | // SanitizeOptions(). | |
406 | options.info_log = std::make_shared<test::NullLogger>(); | |
1e59de90 | 407 | options = SanitizeOptions("db", // just a place holder |
7c673cae | 408 | options); |
1e59de90 | 409 | ImmutableOptions ioptions(options); |
7c673cae FG |
410 | GetIntTblPropCollectorFactory(ioptions, &int_tbl_prop_collector_factories); |
411 | options.comparator = comparator; | |
7c673cae | 412 | } |
1e59de90 | 413 | const ImmutableOptions ioptions(options); |
11fdf7f2 | 414 | MutableCFOptions moptions(options); |
7c673cae FG |
415 | |
416 | for (int iter = 0; iter < 2; ++iter) { | |
11fdf7f2 TL |
417 | MakeBuilder(options, ioptions, moptions, pikc, |
418 | &int_tbl_prop_collector_factories, &writable, &builder); | |
7c673cae FG |
419 | for (const auto& k : keys) { |
420 | builder->Add(k.Encode(), "val"); | |
421 | } | |
422 | ||
423 | ASSERT_OK(builder->Finish()); | |
1e59de90 | 424 | ASSERT_OK(writable->Flush()); |
7c673cae | 425 | |
1e59de90 TL |
426 | test::StringSink* fwf = |
427 | static_cast<test::StringSink*>(writable->writable_file()); | |
428 | std::unique_ptr<FSRandomAccessFile> source( | |
429 | new test::StringSource(fwf->contents())); | |
494da23a | 430 | std::unique_ptr<RandomAccessFileReader> reader( |
1e59de90 TL |
431 | new RandomAccessFileReader(std::move(source), "test")); |
432 | ||
433 | std::unique_ptr<TableProperties> props; | |
434 | Status s = ReadTableProperties(reader.get(), fwf->contents().size(), | |
435 | magic_number, ioptions, &props); | |
7c673cae FG |
436 | ASSERT_OK(s); |
437 | ||
7c673cae FG |
438 | auto user_collected = props->user_collected_properties; |
439 | uint64_t deleted = GetDeletedKeys(user_collected); | |
440 | ASSERT_EQ(5u, deleted); // deletes + single-deletes | |
441 | ||
442 | bool property_present; | |
443 | uint64_t merges = GetMergeOperands(user_collected, &property_present); | |
444 | ASSERT_TRUE(property_present); | |
445 | ASSERT_EQ(2u, merges); | |
446 | ||
447 | if (sanitized) { | |
448 | uint32_t starts_with_A = 0; | |
449 | ASSERT_NE(user_collected.find("Count"), user_collected.end()); | |
450 | Slice key(user_collected.at("Count")); | |
451 | ASSERT_TRUE(GetVarint32(&key, &starts_with_A)); | |
452 | ASSERT_EQ(1u, starts_with_A); | |
453 | ||
454 | if (!backward_mode) { | |
455 | uint32_t num_puts; | |
456 | ASSERT_NE(user_collected.find("NumPuts"), user_collected.end()); | |
457 | Slice key_puts(user_collected.at("NumPuts")); | |
458 | ASSERT_TRUE(GetVarint32(&key_puts, &num_puts)); | |
459 | ASSERT_EQ(3u, num_puts); | |
460 | ||
461 | uint32_t num_deletes; | |
462 | ASSERT_NE(user_collected.find("NumDeletes"), user_collected.end()); | |
463 | Slice key_deletes(user_collected.at("NumDeletes")); | |
464 | ASSERT_TRUE(GetVarint32(&key_deletes, &num_deletes)); | |
465 | ASSERT_EQ(4u, num_deletes); | |
466 | ||
467 | uint32_t num_single_deletes; | |
468 | ASSERT_NE(user_collected.find("NumSingleDeletes"), | |
469 | user_collected.end()); | |
470 | Slice key_single_deletes(user_collected.at("NumSingleDeletes")); | |
471 | ASSERT_TRUE(GetVarint32(&key_single_deletes, &num_single_deletes)); | |
472 | ASSERT_EQ(1u, num_single_deletes); | |
473 | } | |
474 | } | |
475 | } | |
476 | } | |
477 | } // namespace | |
478 | ||
479 | TEST_P(TablePropertiesTest, InternalKeyPropertiesCollector) { | |
480 | TestInternalKeyPropertiesCollector( | |
481 | backward_mode_, kBlockBasedTableMagicNumber, true /* sanitize */, | |
482 | std::make_shared<BlockBasedTableFactory>()); | |
483 | if (backward_mode_) { | |
484 | TestInternalKeyPropertiesCollector( | |
485 | backward_mode_, kBlockBasedTableMagicNumber, false /* not sanitize */, | |
486 | std::make_shared<BlockBasedTableFactory>()); | |
487 | } | |
488 | ||
489 | #ifndef ROCKSDB_LITE // PlainTable is not supported in Lite | |
490 | PlainTableOptions plain_table_options; | |
491 | plain_table_options.user_key_len = 8; | |
492 | plain_table_options.bloom_bits_per_key = 8; | |
493 | plain_table_options.hash_table_ratio = 0; | |
494 | ||
495 | TestInternalKeyPropertiesCollector( | |
496 | backward_mode_, kPlainTableMagicNumber, false /* not sanitize */, | |
497 | std::make_shared<PlainTableFactory>(plain_table_options)); | |
498 | #endif // !ROCKSDB_LITE | |
499 | } | |
500 | ||
501 | INSTANTIATE_TEST_CASE_P(InternalKeyPropertiesCollector, TablePropertiesTest, | |
502 | ::testing::Bool()); | |
503 | ||
504 | INSTANTIATE_TEST_CASE_P(CustomizedTablePropertiesCollector, TablePropertiesTest, | |
505 | ::testing::Bool()); | |
506 | ||
f67539c2 | 507 | } // namespace ROCKSDB_NAMESPACE |
7c673cae FG |
508 | |
509 | int main(int argc, char** argv) { | |
1e59de90 | 510 | ROCKSDB_NAMESPACE::port::InstallStackTraceHandler(); |
7c673cae FG |
511 | ::testing::InitGoogleTest(&argc, argv); |
512 | return RUN_ALL_TESTS(); | |
513 | } |