From ab22cf349e974f13c2085cb24def737960e314d2 Mon Sep 17 00:00:00 2001 From: Dmitri Smirnov Date: Thu, 9 Aug 2018 14:21:35 -0700 Subject: [PATCH] Implement Env::NumFileLinks (#4221) Summary: Although delete scheduler implementation allows for the interface not to be supported, the delete_scheduler_test does not allow for that. Address compiler warnings Make sst_dump_test use test directory structure as the current execution directory may not be writiable. Pull Request resolved: https://github.com/facebook/rocksdb/pull/4221 Differential Revision: D9210152 Pulled By: siying fbshipit-source-id: 381a74511e969ecb8089d5c4b4df87dc30c8df63 --- port/win/env_win.cc | 32 ++++++++++++++ port/win/env_win.h | 6 +++ tools/db_stress.cc | 8 ++++ tools/sst_dump_test.cc | 94 ++++++++++++++++++++---------------------- 4 files changed, 91 insertions(+), 49 deletions(-) diff --git a/port/win/env_win.cc b/port/win/env_win.cc index 4ee200626..043443920 100644 --- a/port/win/env_win.cc +++ b/port/win/env_win.cc @@ -716,6 +716,34 @@ Status WinEnvIO::LinkFile(const std::string& src, return result; } +Status WinEnvIO::NumFileLinks(const std::string& fname, + uint64_t* count) { + Status s; + HANDLE handle = ::CreateFileA(fname.c_str(), 0, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL); + + if (INVALID_HANDLE_VALUE == handle) { + auto lastError = GetLastError(); + s = IOErrorFromWindowsError( + "NumFileLinks: " + fname, lastError); + return s; + } + UniqueCloseHandlePtr handle_guard(handle, CloseHandleFunc); + FILE_STANDARD_INFO standard_info; + if (0 != GetFileInformationByHandleEx(handle, FileStandardInfo, + &standard_info, sizeof(standard_info))) { + *count = standard_info.NumberOfLinks; + } else { + auto lastError = GetLastError(); + s = IOErrorFromWindowsError("GetFileInformationByHandleEx: " + fname, lastError); + } + return s; +} + Status WinEnvIO::AreFilesSame(const std::string& first, const std::string& second, bool* res) { // For MinGW builds @@ -1325,6 +1353,10 @@ Status WinEnv::LinkFile(const std::string& src, return winenv_io_.LinkFile(src, target); } +Status WinEnv::NumFileLinks(const std::string& fname, uint64_t* count) { + return winenv_io_.NumFileLinks(fname, count); +} + Status WinEnv::AreFilesSame(const std::string& first, const std::string& second, bool* res) { return winenv_io_.AreFilesSame(first, second, res); diff --git a/port/win/env_win.h b/port/win/env_win.h index 8968490c2..08c1534f3 100644 --- a/port/win/env_win.h +++ b/port/win/env_win.h @@ -144,6 +144,9 @@ public: virtual Status LinkFile(const std::string& src, const std::string& target); + virtual Status NumFileLinks(const std::string& /*fname*/, + uint64_t* /*count*/); + virtual Status AreFilesSame(const std::string& first, const std::string& second, bool* res); @@ -268,6 +271,9 @@ public: Status LinkFile(const std::string& src, const std::string& target) override; + Status NumFileLinks(const std::string& fname, + uint64_t* count) override; + Status AreFilesSame(const std::string& first, const std::string& second, bool* res) override; diff --git a/tools/db_stress.cc b/tools/db_stress.cc index d93ad5dbe..d4ee4c2d8 100644 --- a/tools/db_stress.cc +++ b/tools/db_stress.cc @@ -588,6 +588,11 @@ enum RepFactory StringToRepFactory(const char* ctype) { return kSkipList; } +#ifdef _MSC_VER +#pragma warning(push) +// truncation of constant value on static_cast +#pragma warning(disable: 4309) +#endif bool GetNextPrefix(const rocksdb::Slice& src, std::string* v) { std::string ret = src.ToString(); for (int i = static_cast(ret.size()) - 1; i >= 0; i--) { @@ -604,6 +609,9 @@ bool GetNextPrefix(const rocksdb::Slice& src, std::string* v) { *v = ret; return true; } +#ifdef _MSC_VER +#pragma warning(pop) +#endif } // namespace static enum RepFactory FLAGS_rep_factory; diff --git a/tools/sst_dump_test.cc b/tools/sst_dump_test.cc index eaf35916e..88e6260e6 100644 --- a/tools/sst_dump_test.cc +++ b/tools/sst_dump_test.cc @@ -53,11 +53,12 @@ void createSST(const std::string& file_name, rocksdb::InternalKeyComparator ikc(opts.comparator); unique_ptr tb; - env->NewWritableFile(file_name, &file, env_options); + ASSERT_OK(env->NewWritableFile(file_name, &file, env_options)); + opts.table_factory = tf; std::vector > int_tbl_prop_collector_factories; - unique_ptr file_writer( + std::unique_ptr file_writer( new WritableFileWriter(std::move(file), EnvOptions())); std::string column_family_name; int unknown_level = -1; @@ -90,30 +91,45 @@ void cleanup(const std::string& file_name) { // Test for sst dump tool "raw" mode class SSTDumpToolTest : public testing::Test { - public: + std::string testDir_; +public: BlockBasedTableOptions table_options_; - SSTDumpToolTest() {} + SSTDumpToolTest() { + testDir_ = test::TmpDir(); + } ~SSTDumpToolTest() {} + + std::string MakeFilePath(const std::string& file_name) const { + std::string path(testDir_); + path.append("/").append(file_name); + return path; + } + + template + void PopulateCommandArgs(const std::string& file_path, const char* command, + char* (&usage)[N]) const { + for (int i = 0; i < N; ++i) { + usage[i] = new char[optLength]; + } + snprintf(usage[0], optLength, "./sst_dump"); + snprintf(usage[1], optLength, "%s", command); + snprintf(usage[2], optLength, "--file=%s", file_path.c_str()); + } }; TEST_F(SSTDumpToolTest, EmptyFilter) { - std::string file_name = "rocksdb_sst_test.sst"; - createSST(file_name, table_options_); + std::string file_path = MakeFilePath("rocksdb_sst_test.sst"); + createSST(file_path, table_options_); char* usage[3]; - for (int i = 0; i < 3; i++) { - usage[i] = new char[optLength]; - } - snprintf(usage[0], optLength, "./sst_dump"); - snprintf(usage[1], optLength, "--command=raw"); - snprintf(usage[2], optLength, "--file=rocksdb_sst_test.sst"); + PopulateCommandArgs(file_path, "--command=raw", usage); rocksdb::SSTDumpTool tool; ASSERT_TRUE(!tool.Run(3, usage)); - cleanup(file_name); + cleanup(file_path); for (int i = 0; i < 3; i++) { delete[] usage[i]; } @@ -121,21 +137,16 @@ TEST_F(SSTDumpToolTest, EmptyFilter) { TEST_F(SSTDumpToolTest, FilterBlock) { table_options_.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, true)); - std::string file_name = "rocksdb_sst_test.sst"; - createSST(file_name, table_options_); + std::string file_path = MakeFilePath("rocksdb_sst_test.sst"); + createSST(file_path, table_options_); char* usage[3]; - for (int i = 0; i < 3; i++) { - usage[i] = new char[optLength]; - } - snprintf(usage[0], optLength, "./sst_dump"); - snprintf(usage[1], optLength, "--command=raw"); - snprintf(usage[2], optLength, "--file=rocksdb_sst_test.sst"); + PopulateCommandArgs(file_path, "--command=raw", usage); rocksdb::SSTDumpTool tool; ASSERT_TRUE(!tool.Run(3, usage)); - cleanup(file_name); + cleanup(file_path); for (int i = 0; i < 3; i++) { delete[] usage[i]; } @@ -143,21 +154,16 @@ TEST_F(SSTDumpToolTest, FilterBlock) { TEST_F(SSTDumpToolTest, FullFilterBlock) { table_options_.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, false)); - std::string file_name = "rocksdb_sst_test.sst"; - createSST(file_name, table_options_); + std::string file_path = MakeFilePath("rocksdb_sst_test.sst"); + createSST(file_path, table_options_); char* usage[3]; - for (int i = 0; i < 3; i++) { - usage[i] = new char[optLength]; - } - snprintf(usage[0], optLength, "./sst_dump"); - snprintf(usage[1], optLength, "--command=raw"); - snprintf(usage[2], optLength, "--file=rocksdb_sst_test.sst"); + PopulateCommandArgs(file_path, "--command=raw", usage); rocksdb::SSTDumpTool tool; ASSERT_TRUE(!tool.Run(3, usage)); - cleanup(file_name); + cleanup(file_path); for (int i = 0; i < 3; i++) { delete[] usage[i]; } @@ -165,21 +171,16 @@ TEST_F(SSTDumpToolTest, FullFilterBlock) { TEST_F(SSTDumpToolTest, GetProperties) { table_options_.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, false)); - std::string file_name = "rocksdb_sst_test.sst"; - createSST(file_name, table_options_); + std::string file_path = MakeFilePath("rocksdb_sst_test.sst"); + createSST(file_path, table_options_); char* usage[3]; - for (int i = 0; i < 3; i++) { - usage[i] = new char[optLength]; - } - snprintf(usage[0], optLength, "./sst_dump"); - snprintf(usage[1], optLength, "--show_properties"); - snprintf(usage[2], optLength, "--file=rocksdb_sst_test.sst"); + PopulateCommandArgs(file_path, "--show_properties", usage); rocksdb::SSTDumpTool tool; ASSERT_TRUE(!tool.Run(3, usage)); - cleanup(file_name); + cleanup(file_path); for (int i = 0; i < 3; i++) { delete[] usage[i]; } @@ -187,21 +188,16 @@ TEST_F(SSTDumpToolTest, GetProperties) { TEST_F(SSTDumpToolTest, CompressedSizes) { table_options_.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, false)); - std::string file_name = "rocksdb_sst_test.sst"; - createSST(file_name, table_options_); + std::string file_path = MakeFilePath("rocksdb_sst_test.sst"); + createSST(file_path, table_options_); char* usage[3]; - for (int i = 0; i < 3; i++) { - usage[i] = new char[optLength]; - } + PopulateCommandArgs(file_path, "--command=recompress", usage); - snprintf(usage[0], optLength, "./sst_dump"); - snprintf(usage[1], optLength, "--command=recompress"); - snprintf(usage[2], optLength, "--file=rocksdb_sst_test.sst"); rocksdb::SSTDumpTool tool; ASSERT_TRUE(!tool.Run(3, usage)); - cleanup(file_name); + cleanup(file_path); for (int i = 0; i < 3; i++) { delete[] usage[i]; }