diff --git a/db/plain_table_db_test.cc b/db/plain_table_db_test.cc index 186f4717d72..a5dbe225b87 100644 --- a/db/plain_table_db_test.cc +++ b/db/plain_table_db_test.cc @@ -302,6 +302,7 @@ class TestPlainTableReader : public PlainTableReader { EXPECT_TRUE(num_blocks_ptr != props->user_collected_properties.end()); } } + table_properties_.reset(props); } ~TestPlainTableReader() override {} @@ -396,7 +397,9 @@ TEST_P(PlainTableDBTest, Flush) { for (size_t huge_page_tlb_size = 0; huge_page_tlb_size <= 2 * 1024 * 1024; huge_page_tlb_size += 2 * 1024 * 1024) { for (EncodingType encoding_type : {kPlain, kPrefix}) { - for (int bloom_bits = 0; bloom_bits <= 117; bloom_bits += 117) { + for (int bloom = -1; bloom <= 117; bloom += 117) { + const int bloom_bits = std::max(bloom, 0); + const bool full_scan_mode = bloom < 0; for (int total_order = 0; total_order <= 1; total_order++) { for (int store_index_in_file = 0; store_index_in_file <= 1; ++store_index_in_file) { @@ -414,7 +417,7 @@ TEST_P(PlainTableDBTest, Flush) { plain_table_options.index_sparseness = 2; plain_table_options.huge_page_tlb_size = huge_page_tlb_size; plain_table_options.encoding_type = encoding_type; - plain_table_options.full_scan_mode = false; + plain_table_options.full_scan_mode = full_scan_mode; plain_table_options.store_index_in_file = store_index_in_file; options.table_factory.reset( @@ -427,7 +430,7 @@ TEST_P(PlainTableDBTest, Flush) { plain_table_options.index_sparseness = 16; plain_table_options.huge_page_tlb_size = huge_page_tlb_size; plain_table_options.encoding_type = encoding_type; - plain_table_options.full_scan_mode = false; + plain_table_options.full_scan_mode = full_scan_mode; plain_table_options.store_index_in_file = store_index_in_file; options.table_factory.reset( @@ -454,20 +457,36 @@ TEST_P(PlainTableDBTest, Flush) { auto row = ptc.begin(); auto tp = row->second; - if (!store_index_in_file) { - ASSERT_EQ(total_order ? "4" : "12", - (tp->user_collected_properties) - .at("plain_table_hash_table_size")); - ASSERT_EQ("0", (tp->user_collected_properties) - .at("plain_table_sub_index_size")); + if (full_scan_mode) { + // Does not support Get/Seek + std::unique_ptr iter(dbfull()->NewIterator(ReadOptions())); + iter->SeekToFirst(); + ASSERT_TRUE(iter->Valid()); + ASSERT_EQ("0000000000000bar", iter->key().ToString()); + ASSERT_EQ("v2", iter->value().ToString()); + iter->Next(); + ASSERT_TRUE(iter->Valid()); + ASSERT_EQ("1000000000000foo", iter->key().ToString()); + ASSERT_EQ("v3", iter->value().ToString()); + iter->Next(); + ASSERT_TRUE(!iter->Valid()); + ASSERT_TRUE(iter->status().ok()); } else { - ASSERT_EQ("0", (tp->user_collected_properties) - .at("plain_table_hash_table_size")); - ASSERT_EQ("0", (tp->user_collected_properties) - .at("plain_table_sub_index_size")); + if (!store_index_in_file) { + ASSERT_EQ(total_order ? "4" : "12", + (tp->user_collected_properties) + .at("plain_table_hash_table_size")); + ASSERT_EQ("0", (tp->user_collected_properties) + .at("plain_table_sub_index_size")); + } else { + ASSERT_EQ("0", (tp->user_collected_properties) + .at("plain_table_hash_table_size")); + ASSERT_EQ("0", (tp->user_collected_properties) + .at("plain_table_sub_index_size")); + } + ASSERT_EQ("v3", Get("1000000000000foo")); + ASSERT_EQ("v2", Get("0000000000000bar")); } - ASSERT_EQ("v3", Get("1000000000000foo")); - ASSERT_EQ("v2", Get("0000000000000bar")); } } } diff --git a/table/plain/plain_table_reader.cc b/table/plain/plain_table_reader.cc index aa8aa6ed16f..58145dda303 100644 --- a/table/plain/plain_table_reader.cc +++ b/table/plain/plain_table_reader.cc @@ -183,6 +183,8 @@ Status PlainTableReader::Open( // can be used. new_reader->full_scan_mode_ = true; } + // PopulateIndex can add to the props, so don't store them until now + new_reader->table_properties_.reset(props); if (immortal_table && new_reader->file_info_.is_mmap_mode) { new_reader->dummy_cleanable_.reset(new Cleanable()); @@ -199,6 +201,9 @@ InternalIterator* PlainTableReader::NewIterator( const ReadOptions& options, const SliceTransform* /* prefix_extractor */, Arena* arena, bool /*skip_filters*/, TableReaderCaller /*caller*/, size_t /*compaction_readahead_size*/) { + // Not necessarily used here, but make sure this has been initialized + assert(table_properties_); + bool use_prefix_seek = !IsTotalOrderMode() && !options.total_order_seek; if (arena == nullptr) { return new PlainTableIterator(this, use_prefix_seek); @@ -291,7 +296,6 @@ Status PlainTableReader::PopulateIndex(TableProperties* props, size_t index_sparseness, size_t huge_page_tlb_size) { assert(props != nullptr); - table_properties_.reset(props); BlockContents index_block_contents; Status s = ReadMetaBlock(file_info_.file.get(), nullptr /* prefetch_buffer */, @@ -351,7 +355,7 @@ Status PlainTableReader::PopulateIndex(TableProperties* props, // Allocate bloom filter here for total order mode. if (IsTotalOrderMode()) { AllocateBloom(bloom_bits_per_key, - static_cast(table_properties_->num_entries), + static_cast(props->num_entries), huge_page_tlb_size); } } else if (bloom_in_file) { diff --git a/table/plain/plain_table_reader.h b/table/plain/plain_table_reader.h index e2d0e859282..c956913a04f 100644 --- a/table/plain/plain_table_reader.h +++ b/table/plain/plain_table_reader.h @@ -165,7 +165,9 @@ class PlainTableReader: public TableReader { const ImmutableCFOptions& ioptions_; std::unique_ptr dummy_cleanable_; uint64_t file_size_; + protected: // for testing std::shared_ptr table_properties_; + private: bool IsFixedLength() const { return user_key_len_ != kPlainTableVariableLength; diff --git a/tools/sst_dump_tool.cc b/tools/sst_dump_tool.cc index fa4a431e81b..39e39e201a0 100644 --- a/tools/sst_dump_tool.cc +++ b/tools/sst_dump_tool.cc @@ -719,17 +719,19 @@ int SSTDumpTool::Run(int argc, char** argv, Options options) { total_data_block_size += table_properties->data_size; total_index_block_size += table_properties->index_size; total_filter_block_size += table_properties->filter_size; - } - if (show_properties) { - fprintf(stdout, - "Raw user collected properties\n" - "------------------------------\n"); - for (const auto& kv : table_properties->user_collected_properties) { - std::string prop_name = kv.first; - std::string prop_val = Slice(kv.second).ToString(true); - fprintf(stdout, " # %s: 0x%s\n", prop_name.c_str(), - prop_val.c_str()); + if (show_properties) { + fprintf(stdout, + "Raw user collected properties\n" + "------------------------------\n"); + for (const auto& kv : table_properties->user_collected_properties) { + std::string prop_name = kv.first; + std::string prop_val = Slice(kv.second).ToString(true); + fprintf(stdout, " # %s: 0x%s\n", prop_name.c_str(), + prop_val.c_str()); + } } + } else { + fprintf(stderr, "Reader unexpectedly returned null properties\n"); } } }