Mercurial > hg > orthanc
changeset 278:771f12042be9
more efficient determination of storage size for recycling
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sun, 09 Dec 2012 21:51:57 +0100 |
parents | 58f969933720 |
children | eb5fb5501569 |
files | OrthancServer/ServerIndex.cpp OrthancServer/ServerIndex.h |
diffstat | 2 files changed, 69 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancServer/ServerIndex.cpp Sun Dec 09 15:03:17 2012 +0100 +++ b/OrthancServer/ServerIndex.cpp Sun Dec 09 21:51:57 2012 +0100 @@ -60,12 +60,13 @@ ResourceType remainingType_; std::string remainingPublicId_; std::list<std::string> pendingFilesToRemove_; + uint64_t sizeOfFilesToRemove_; public: ServerIndexListener(ServerContext& context) : - context_(context), - hasRemainingLevel_(false) + context_(context) { + Reset(); assert(ResourceType_Patient < ResourceType_Study && ResourceType_Study < ResourceType_Series && ResourceType_Series < ResourceType_Instance); @@ -73,10 +74,16 @@ void Reset() { + sizeOfFilesToRemove_ = 0; hasRemainingLevel_ = false; pendingFilesToRemove_.clear(); } + uint64_t GetSizeOfFilesToRemove() + { + return sizeOfFilesToRemove_; + } + void CommitFilesToRemove() { for (std::list<std::string>::iterator @@ -112,6 +119,7 @@ { assert(Toolbox::IsUuid(info.GetUuid())); pendingFilesToRemove_.push_back(info.GetUuid()); + sizeOfFilesToRemove_ += info.GetCompressedSize(); } bool HasRemainingLevel() const @@ -134,6 +142,49 @@ } + class ServerIndex::Transaction + { + private: + ServerIndex& index_; + std::auto_ptr<SQLite::Transaction> transaction_; + bool isCommitted_; + + public: + Transaction(ServerIndex& index) : + index_(index), + isCommitted_(false) + { + assert(index_.currentStorageSize_ == index_.db_->GetTotalCompressedSize()); + + index_.listener_->Reset(); + transaction_.reset(index_.db_->StartTransaction()); + transaction_->Begin(); + } + + void Commit(uint64_t sizeOfAddedFiles) + { + if (!isCommitted_) + { + transaction_->Commit(); + + // We can remove the files once the SQLite transaction has + // been successfully committed. Some files might have to be + // deleted because of recycling. + index_.listener_->CommitFilesToRemove(); + + index_.currentStorageSize_ += sizeOfAddedFiles; + + assert(index_.currentStorageSize_ >= index_.listener_->GetSizeOfFilesToRemove()); + index_.currentStorageSize_ -= index_.listener_->GetSizeOfFilesToRemove(); + + assert(index_.currentStorageSize_ == index_.db_->GetTotalCompressedSize()); + + isCommitted_ = true; + } + } + }; + + bool ServerIndex::DeleteResource(Json::Value& target, const std::string& uuid, ResourceType expectedType) @@ -141,8 +192,7 @@ boost::mutex::scoped_lock lock(mutex_); listener_->Reset(); - std::auto_ptr<SQLite::Transaction> t(db_->StartTransaction()); - t->Begin(); + Transaction t(*this); int64_t id; ResourceType type; @@ -169,11 +219,7 @@ target["RemainingAncestor"] = Json::nullValue; } - t->Commit(); - - // We can remove the files once the SQLite transaction has been - // successfully committed - listener_->CommitFilesToRemove(); + t.Commit(0); return true; } @@ -220,6 +266,8 @@ db_.reset(new DatabaseWrapper(p.string() + "/index", *listener_)); } + currentStorageSize_ = db_->GetTotalCompressedSize(); + // Initial recycling if the parameters have changed since the last // execution of Orthanc StandaloneRecycling(); @@ -259,8 +307,7 @@ try { - std::auto_ptr<SQLite::Transaction> t(db_->StartTransaction()); - t->Begin(); + Transaction t(*this); int64_t patient, study, series, instance; ResourceType type; @@ -369,12 +416,7 @@ db_->LogChange(ChangeType_CompletedSeries, series, ResourceType_Series); } - t->Commit(); - - // We can remove the files once the SQLite transaction has been - // successfully committed. Some files might have to be deleted - // because of recycling. - listener_->CommitFilesToRemove(); + t.Commit(instanceSize); return StoreStatus_Success; } @@ -395,7 +437,8 @@ boost::mutex::scoped_lock lock(mutex_); target = Json::objectValue; - uint64_t cs = db_->GetTotalCompressedSize(); + uint64_t cs = currentStorageSize_; + assert(cs == db_->GetTotalCompressedSize()); uint64_t us = db_->GetTotalUncompressedSize(); target["TotalDiskSpace"] = boost::lexical_cast<std::string>(cs); target["TotalUncompressedSize"] = boost::lexical_cast<std::string>(us); @@ -768,7 +811,9 @@ { if (maximumStorageSize_ != 0) { - uint64_t currentSize = db_->GetTotalCompressedSize(); + uint64_t currentSize = currentStorageSize_ - listener_->GetSizeOfFilesToRemove(); + assert(db_->GetTotalCompressedSize() == currentSize); + if (currentSize + instanceSize > maximumStorageSize_) { return true; @@ -871,11 +916,9 @@ void ServerIndex::StandaloneRecycling() { // WARNING: No mutex here, do not include this as a public method - std::auto_ptr<SQLite::Transaction> t(db_->StartTransaction()); - t->Begin(); + Transaction t(*this); Recycle(0, ""); - t->Commit(); - listener_->CommitFilesToRemove(); + t.Commit(0); }
--- a/OrthancServer/ServerIndex.h Sun Dec 09 15:03:17 2012 +0100 +++ b/OrthancServer/ServerIndex.h Sun Dec 09 21:51:57 2012 +0100 @@ -51,17 +51,18 @@ class ServerIndexListener; } - - class ServerIndex : public boost::noncopyable { private: + class Transaction; + boost::mutex mutex_; boost::thread flushThread_; std::auto_ptr<Internals::ServerIndexListener> listener_; std::auto_ptr<DatabaseWrapper> db_; + uint64_t currentStorageSize_; uint64_t maximumStorageSize_; unsigned int maximumPatients_;