diff --git a/arcanist/linter/LocaleDependenceLinter.php b/arcanist/linter/LocaleDependenceLinter.php --- a/arcanist/linter/LocaleDependenceLinter.php +++ b/arcanist/linter/LocaleDependenceLinter.php @@ -14,7 +14,10 @@ "atoi", ], "src/core_read.cpp" => ["is_digit"], - "src/dbwrapper.cpp" => ["vsnprintf"], + "src/dbwrapper.cpp" => [ + "stoul", + "vsnprintf" + ], "src/httprpc.cpp" => ["trim"], "src/init.cpp" => ["atoi"], "src/netbase.cpp" => ["to_lower"], diff --git a/src/dbwrapper.h b/src/dbwrapper.h --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -196,6 +196,9 @@ //! the database itself leveldb::DB *pdb; + //! the name of this database + std::string m_name; + //! a key used for optional XOR-obfuscation of the database std::vector obfuscate_key; @@ -281,6 +284,9 @@ bool WriteBatch(CDBBatch &batch, bool fSync = false); + // Get an estimate of LevelDB memory usage (in bytes). + size_t DynamicMemoryUsage() const; + // not available for LevelDB; provide for compatibility with BDB bool Flush() { return true; } diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -93,7 +93,8 @@ } CDBWrapper::CDBWrapper(const fs::path &path, size_t nCacheSize, bool fMemory, - bool fWipe, bool obfuscate) { + bool fWipe, bool obfuscate) + : m_name(fs::basename(path)) { penv = nullptr; readoptions.verify_checksums = true; iteroptions.verify_checksums = true; @@ -159,12 +160,34 @@ } bool CDBWrapper::WriteBatch(CDBBatch &batch, bool fSync) { + const bool log_memory = LogAcceptCategory(BCLog::LEVELDB); + double mem_before = 0; + if (log_memory) { + mem_before = DynamicMemoryUsage() / 1024.0 / 1024; + } leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch); dbwrapper_private::HandleError(status); + if (log_memory) { + double mem_after = DynamicMemoryUsage() / 1024.0 / 1024; + LogPrint( + BCLog::LEVELDB, + "WriteBatch memory usage: db=%s, before=%.1fMiB, after=%.1fMiB\n", + m_name, mem_before, mem_after); + } return true; } +size_t CDBWrapper::DynamicMemoryUsage() const { + std::string memory; + if (!pdb->GetProperty("leveldb.approximate-memory-usage", &memory)) { + LogPrint(BCLog::LEVELDB, + "Failed to get approximate-memory-usage property\n"); + return 0; + } + return stoul(memory); +} + // Prefixed with null character to avoid collisions with other keys // // We must use a string constructor which specifies length so that we copy past