Mercurial > hg > orthanc
changeset 3019:8336204d95dc db-changes
refactoring computation of disk size for recycling
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 14 Dec 2018 18:07:40 +0100 |
parents | e3b5c07146a3 |
children | d207f6ac1f86 |
files | OrthancServer/IDatabaseWrapper.h OrthancServer/InstallTrackAttachmentsSize.sql OrthancServer/SQLiteDatabaseWrapper.cpp OrthancServer/SQLiteDatabaseWrapper.h OrthancServer/ServerEnumerations.h OrthancServer/ServerIndex.cpp Plugins/Engine/OrthancPluginDatabase.cpp Plugins/Engine/OrthancPluginDatabase.h UnitTestsSources/ServerIndexTests.cpp |
diffstat | 9 files changed, 172 insertions(+), 66 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancServer/IDatabaseWrapper.h Fri Dec 14 16:04:17 2018 +0100 +++ b/OrthancServer/IDatabaseWrapper.h Fri Dec 14 18:07:40 2018 +0100 @@ -48,6 +48,21 @@ class IDatabaseWrapper : public boost::noncopyable { public: + class ITransaction : public boost::noncopyable + { + public: + virtual ~ITransaction() + { + } + + virtual void Begin() = 0; + + virtual void Rollback() = 0; + + virtual void Commit(int64_t fileSizeDelta) = 0; + }; + + virtual ~IDatabaseWrapper() { } @@ -198,7 +213,7 @@ virtual void SetProtectedPatient(int64_t internalId, bool isProtected) = 0; - virtual SQLite::ITransaction* StartTransaction() = 0; + virtual ITransaction* StartTransaction() = 0; virtual void SetListener(IDatabaseListener& listener) = 0;
--- a/OrthancServer/InstallTrackAttachmentsSize.sql Fri Dec 14 16:04:17 2018 +0100 +++ b/OrthancServer/InstallTrackAttachmentsSize.sql Fri Dec 14 18:07:40 2018 +0100 @@ -2,7 +2,7 @@ key INTEGER PRIMARY KEY, value INTEGER); -INSERT INTO GlobalProperties VALUES (6, 1); -- GlobalProperty_DatabaseTracksSizeOfAttachments +INSERT INTO GlobalProperties VALUES (6, 1); -- GlobalProperty_GetTotalSizeIsFast INSERT INTO GlobalIntegers SELECT 0, IFNULL(SUM(compressedSize), 0) FROM AttachedFiles; INSERT INTO GlobalIntegers SELECT 1, IFNULL(SUM(uncompressedSize), 0) FROM AttachedFiles;
--- a/OrthancServer/SQLiteDatabaseWrapper.cpp Fri Dec 14 16:04:17 2018 +0100 +++ b/OrthancServer/SQLiteDatabaseWrapper.cpp Fri Dec 14 18:07:40 2018 +0100 @@ -36,6 +36,7 @@ #include "../Core/DicomFormat/DicomArray.h" #include "../Core/Logging.h" +#include "../Core/SQLite/Transaction.h" #include "EmbeddedResources.h" #include "ServerToolbox.h" @@ -373,7 +374,7 @@ // New in Orthanc 1.5.1 if (version_ == 6) { - if (!LookupGlobalProperty(tmp, GlobalProperty_DatabaseTracksSizeOfAttachments) || + if (!LookupGlobalProperty(tmp, GlobalProperty_GetTotalSizeIsFast) || tmp != "1") { LOG(INFO) << "Installing the SQLite triggers to track the size of the attachments"; @@ -542,6 +543,53 @@ } + class SQLiteDatabaseWrapper::Transaction : public IDatabaseWrapper::ITransaction + { + private: + SQLiteDatabaseWrapper& that_; + std::auto_ptr<SQLite::Transaction> transaction_; + int64_t initialDiskSize_; + + public: + Transaction(SQLiteDatabaseWrapper& that) : + that_(that), + transaction_(new SQLite::Transaction(that_.db_)) + { +#if defined(NDEBUG) + // Release mode + initialDiskSize_ = 0; +#else + // Debug mode + initialDiskSize_ = static_cast<int64_t>(that_.GetTotalCompressedSize()); +#endif + } + + virtual void Begin() + { + transaction_->Begin(); + } + + virtual void Rollback() + { + transaction_->Rollback(); + } + + virtual void Commit(int64_t fileSizeDelta /* only used in debug */) + { + transaction_->Commit(); + + assert(initialDiskSize_ + fileSizeDelta >= 0 && + initialDiskSize_ + fileSizeDelta == static_cast<int64_t>(that_.GetTotalCompressedSize())); + } + }; + + + IDatabaseWrapper::ITransaction* SQLiteDatabaseWrapper::StartTransaction() + { + return new Transaction(*this); + } + + void SQLiteDatabaseWrapper::GetAllMetadata(std::map<MetadataType, std::string>& target, int64_t id) {
--- a/OrthancServer/SQLiteDatabaseWrapper.h Fri Dec 14 16:04:17 2018 +0100 +++ b/OrthancServer/SQLiteDatabaseWrapper.h Fri Dec 14 18:07:40 2018 +0100 @@ -36,7 +36,6 @@ #include "IDatabaseWrapper.h" #include "../Core/SQLite/Connection.h" -#include "../Core/SQLite/Transaction.h" namespace Orthanc { @@ -53,6 +52,8 @@ class SQLiteDatabaseWrapper : public IDatabaseWrapper { private: + class Transaction; + IDatabaseListener* listener_; SQLite::Connection db_; Internals::SignalRemainingAncestor* signalRemainingAncestor_; @@ -100,10 +101,7 @@ virtual void GetLastChange(std::list<ServerIndexChange>& target /*out*/); - virtual SQLite::ITransaction* StartTransaction() - { - return new SQLite::Transaction(db_); - } + virtual IDatabaseWrapper::ITransaction* StartTransaction(); virtual void FlushToDisk() {
--- a/OrthancServer/ServerEnumerations.h Fri Dec 14 16:04:17 2018 +0100 +++ b/OrthancServer/ServerEnumerations.h Fri Dec 14 18:07:40 2018 +0100 @@ -93,9 +93,9 @@ GlobalProperty_FlushSleep = 2, GlobalProperty_AnonymizationSequence = 3, GlobalProperty_JobsRegistry = 5, - GlobalProperty_DatabaseTracksSizeOfAttachments = 6, // New in Orthanc 1.5.1 - GlobalProperty_Modalities = 20, // New in Orthanc 1.5.0 - GlobalProperty_Peers = 21, // New in Orthanc 1.5.0 + GlobalProperty_GetTotalSizeIsFast = 6, // New in Orthanc 1.5.2 + GlobalProperty_Modalities = 20, // New in Orthanc 1.5.0 + GlobalProperty_Peers = 21, // New in Orthanc 1.5.0 // Reserved values for internal use by the database plugins GlobalProperty_DatabasePatchLevel = 4,
--- a/OrthancServer/ServerIndex.cpp Fri Dec 14 16:04:17 2018 +0100 +++ b/OrthancServer/ServerIndex.cpp Fri Dec 14 18:07:40 2018 +0100 @@ -215,7 +215,7 @@ { private: ServerIndex& index_; - std::auto_ptr<SQLite::ITransaction> transaction_; + std::auto_ptr<IDatabaseWrapper::ITransaction> transaction_; bool isCommitted_; public: @@ -245,7 +245,10 @@ { if (!isCommitted_) { - transaction_->Commit(); + int64_t delta = (static_cast<int64_t>(sizeOfAddedFiles) - + static_cast<int64_t>(index_.listener_->GetSizeOfFilesToRemove())); + + transaction_->Commit(delta); // We can remove the files once the SQLite transaction has // been successfully committed. Some files might have to be
--- a/Plugins/Engine/OrthancPluginDatabase.cpp Fri Dec 14 16:04:17 2018 +0100 +++ b/Plugins/Engine/OrthancPluginDatabase.cpp Fri Dec 14 18:07:40 2018 +0100 @@ -47,6 +47,62 @@ namespace Orthanc { + class OrthancPluginDatabase::Transaction : public IDatabaseWrapper::ITransaction + { + private: + OrthancPluginDatabase& that_; + + void CheckSuccess(OrthancPluginErrorCode code) const + { + if (code != OrthancPluginErrorCode_Success) + { + that_.errorDictionary_.LogError(code, true); + throw OrthancException(static_cast<ErrorCode>(code)); + } + } + + public: + Transaction(OrthancPluginDatabase& that) : + that_(that) + { + } + + virtual void Begin() + { + CheckSuccess(that_.backend_.startTransaction(that_.payload_)); + } + + virtual void Rollback() + { + CheckSuccess(that_.backend_.rollbackTransaction(that_.payload_)); + } + + virtual void Commit(int64_t diskSizeDelta) + { + if (that_.fastGetTotalSize_) + { + CheckSuccess(that_.backend_.commitTransaction(that_.payload_)); + } + else + { + if (static_cast<int64_t>(that_.currentDiskSize_) + diskSizeDelta < 0) + { + throw OrthancException(ErrorCode_DatabasePlugin); + } + + uint64_t newDiskSize = (that_.currentDiskSize_ + diskSizeDelta); + + assert(newDiskSize == that_.GetTotalCompressedSize()); + + CheckSuccess(that_.backend_.commitTransaction(that_.payload_)); + + // The transaction has succeeded, we can commit the new disk size + that_.currentDiskSize_ = newDiskSize; + } + } + }; + + static FileInfo Convert(const OrthancPluginAttachment& attachment) { return FileInfo(attachment.uuid, @@ -189,6 +245,35 @@ } + void OrthancPluginDatabase::Open() + { + CheckSuccess(backend_.open(payload_)); + + { + Transaction transaction(*this); + transaction.Begin(); + + std::string tmp; + fastGetTotalSize_ = + (LookupGlobalProperty(tmp, GlobalProperty_GetTotalSizeIsFast) && + tmp == "1"); + + if (fastGetTotalSize_) + { + currentDiskSize_ = 0; // Unused + } + else + { + // This is the case of database plugins using Orthanc SDK <= 1.5.2 + LOG(WARNING) << "Consider upgrading your database index plugin for best performance"; + currentDiskSize_ = GetTotalCompressedSize(); + } + + transaction.Commit(0); + } + } + + void OrthancPluginDatabase::AddAttachment(int64_t id, const FileInfo& attachment) { @@ -786,52 +871,9 @@ } - class OrthancPluginDatabase::Transaction : public SQLite::ITransaction + IDatabaseWrapper::ITransaction* OrthancPluginDatabase::StartTransaction() { - private: - const OrthancPluginDatabaseBackend& backend_; - void* payload_; - PluginsErrorDictionary& errorDictionary_; - - void CheckSuccess(OrthancPluginErrorCode code) - { - if (code != OrthancPluginErrorCode_Success) - { - errorDictionary_.LogError(code, true); - throw OrthancException(static_cast<ErrorCode>(code)); - } - } - - public: - Transaction(const OrthancPluginDatabaseBackend& backend, - void* payload, - PluginsErrorDictionary& errorDictionary) : - backend_(backend), - payload_(payload), - errorDictionary_(errorDictionary) - { - } - - virtual void Begin() - { - CheckSuccess(backend_.startTransaction(payload_)); - } - - virtual void Rollback() - { - CheckSuccess(backend_.rollbackTransaction(payload_)); - } - - virtual void Commit() - { - CheckSuccess(backend_.commitTransaction(payload_)); - } - }; - - - SQLite::ITransaction* OrthancPluginDatabase::StartTransaction() - { - return new Transaction(backend_, payload_, errorDictionary_); + return new Transaction(*this); } @@ -892,7 +934,7 @@ { if (extensions_.upgradeDatabase != NULL) { - Transaction transaction(backend_, payload_, errorDictionary_); + Transaction transaction(*this); transaction.Begin(); OrthancPluginErrorCode code = extensions_.upgradeDatabase( @@ -901,7 +943,7 @@ if (code == OrthancPluginErrorCode_Success) { - transaction.Commit(); + transaction.Commit(0); } else {
--- a/Plugins/Engine/OrthancPluginDatabase.h Fri Dec 14 16:04:17 2018 +0100 +++ b/Plugins/Engine/OrthancPluginDatabase.h Fri Dec 14 18:07:40 2018 +0100 @@ -57,6 +57,9 @@ void* payload_; IDatabaseListener* listener_; + bool fastGetTotalSize_; + uint64_t currentDiskSize_; + std::list<std::string> answerStrings_; std::list<int32_t> answerInt32_; std::list<int64_t> answerInt64_; @@ -93,10 +96,7 @@ size_t extensionsSize, void *payload); - virtual void Open() - { - CheckSuccess(backend_.open(payload_)); - } + virtual void Open(); virtual void Close() { @@ -255,7 +255,7 @@ virtual void SetProtectedPatient(int64_t internalId, bool isProtected); - virtual SQLite::ITransaction* StartTransaction(); + virtual IDatabaseWrapper::ITransaction* StartTransaction(); virtual void SetListener(IDatabaseListener& listener) {
--- a/UnitTestsSources/ServerIndexTests.cpp Fri Dec 14 16:04:17 2018 +0100 +++ b/UnitTestsSources/ServerIndexTests.cpp Fri Dec 14 18:07:40 2018 +0100 @@ -471,7 +471,7 @@ ASSERT_EQ("6", tmp); ASSERT_TRUE(index_->LookupGlobalProperty(tmp, GlobalProperty_FlushSleep)); ASSERT_EQ("World", tmp); - ASSERT_TRUE(index_->LookupGlobalProperty(tmp, GlobalProperty_DatabaseTracksSizeOfAttachments)); + ASSERT_TRUE(index_->LookupGlobalProperty(tmp, GlobalProperty_GetTotalSizeIsFast)); ASSERT_EQ("1", tmp); ASSERT_EQ(3u, listener_->deletedFiles_.size());