# HG changeset patch # User Sebastien Jodogne # Date 1544807260 -3600 # Node ID 8336204d95dc89540b4cd03ef90ef664f1ccc857 # Parent e3b5c07146a300fa69234eb3eba84b3d89385044 refactoring computation of disk size for recycling diff -r e3b5c07146a3 -r 8336204d95dc OrthancServer/IDatabaseWrapper.h --- 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; diff -r e3b5c07146a3 -r 8336204d95dc OrthancServer/InstallTrackAttachmentsSize.sql --- 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; diff -r e3b5c07146a3 -r 8336204d95dc OrthancServer/SQLiteDatabaseWrapper.cpp --- 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 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(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(that_.GetTotalCompressedSize())); + } + }; + + + IDatabaseWrapper::ITransaction* SQLiteDatabaseWrapper::StartTransaction() + { + return new Transaction(*this); + } + + void SQLiteDatabaseWrapper::GetAllMetadata(std::map& target, int64_t id) { diff -r e3b5c07146a3 -r 8336204d95dc OrthancServer/SQLiteDatabaseWrapper.h --- 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& target /*out*/); - virtual SQLite::ITransaction* StartTransaction() - { - return new SQLite::Transaction(db_); - } + virtual IDatabaseWrapper::ITransaction* StartTransaction(); virtual void FlushToDisk() { diff -r e3b5c07146a3 -r 8336204d95dc OrthancServer/ServerEnumerations.h --- 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, diff -r e3b5c07146a3 -r 8336204d95dc OrthancServer/ServerIndex.cpp --- 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 transaction_; + std::auto_ptr transaction_; bool isCommitted_; public: @@ -245,7 +245,10 @@ { if (!isCommitted_) { - transaction_->Commit(); + int64_t delta = (static_cast(sizeOfAddedFiles) - + static_cast(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 diff -r e3b5c07146a3 -r 8336204d95dc Plugins/Engine/OrthancPluginDatabase.cpp --- 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(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(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(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 { diff -r e3b5c07146a3 -r 8336204d95dc Plugins/Engine/OrthancPluginDatabase.h --- 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 answerStrings_; std::list answerInt32_; std::list 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) { diff -r e3b5c07146a3 -r 8336204d95dc UnitTestsSources/ServerIndexTests.cpp --- 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());