# HG changeset patch # User Sebastien Jodogne # Date 1354884215 -3600 # Node ID 4bc02e2254ecb5548f9e65afbf1c932d1e275776 # Parent a08dca15790e4c2abf1d4eb77fb9e9dbf608c0ce preparing ServerIndex for recycling diff -r a08dca15790e -r 4bc02e2254ec Core/Enumerations.h --- a/Core/Enumerations.h Fri Dec 07 13:19:42 2012 +0100 +++ b/Core/Enumerations.h Fri Dec 07 13:43:35 2012 +0100 @@ -55,7 +55,8 @@ ErrorCode_BadFileFormat, ErrorCode_Timeout, ErrorCode_UnknownResource, - ErrorCode_IncompatibleDatabaseVersion + ErrorCode_IncompatibleDatabaseVersion, + ErrorCode_FullStorage }; enum PixelFormat diff -r a08dca15790e -r 4bc02e2254ec Core/OrthancException.cpp --- a/Core/OrthancException.cpp Fri Dec 07 13:19:42 2012 +0100 +++ b/Core/OrthancException.cpp Fri Dec 07 13:43:35 2012 +0100 @@ -93,6 +93,9 @@ case ErrorCode_IncompatibleDatabaseVersion: return "Incompatible version of the database"; + case ErrorCode_FullStorage: + return "The file storage is full"; + case ErrorCode_Custom: default: return "???"; diff -r a08dca15790e -r 4bc02e2254ec OrthancServer/DatabaseWrapper.cpp --- a/OrthancServer/DatabaseWrapper.cpp Fri Dec 07 13:19:42 2012 +0100 +++ b/OrthancServer/DatabaseWrapper.cpp Fri Dec 07 13:43:35 2012 +0100 @@ -795,6 +795,26 @@ } } + bool DatabaseWrapper::SelectPatientToRecycle(int64_t& internalId, + int64_t patientIdToAvoid) + { + SQLite::Statement s(db_, SQLITE_FROM_HERE, + "SELECT patientId FROM PatientRecyclingOrder " + "WHERE patientId != ? ORDER BY seq ASC LIMIT 1"); + s.BindInt(0, patientIdToAvoid); + + if (!s.Step()) + { + // No patient remaining or all the patients are protected + return false; + } + else + { + internalId = s.ColumnInt(0); + return true; + } + } + bool DatabaseWrapper::IsProtectedPatient(int64_t internalId) { SQLite::Statement s(db_, SQLITE_FROM_HERE, diff -r a08dca15790e -r 4bc02e2254ec OrthancServer/DatabaseWrapper.h --- a/OrthancServer/DatabaseWrapper.h Fri Dec 07 13:19:42 2012 +0100 +++ b/OrthancServer/DatabaseWrapper.h Fri Dec 07 13:43:35 2012 +0100 @@ -181,6 +181,9 @@ bool SelectPatientToRecycle(int64_t& internalId); + bool SelectPatientToRecycle(int64_t& internalId, + int64_t patientIdToAvoid); + bool IsProtectedPatient(int64_t internalId); void SetProtectedPatient(int64_t internalId, diff -r a08dca15790e -r 4bc02e2254ec OrthancServer/ServerIndex.cpp --- a/OrthancServer/ServerIndex.cpp Fri Dec 07 13:19:42 2012 +0100 +++ b/OrthancServer/ServerIndex.cpp Fri Dec 07 13:43:35 2012 +0100 @@ -139,7 +139,6 @@ ResourceType expectedType) { boost::mutex::scoped_lock lock(mutex_); - listener_->Reset(); std::auto_ptr t(db_->StartTransaction()); @@ -248,6 +247,7 @@ const std::string& remoteAet) { boost::mutex::scoped_lock lock(mutex_); + listener_->Reset(); DicomInstanceHasher hasher(dicomSummary); @@ -267,6 +267,16 @@ return StoreStatus_AlreadyStored; } + // Ensure there is enough room in the storage for the new instance + uint64_t instanceSize = 0; + for (Attachments::const_iterator it = attachments.begin(); + it != attachments.end(); it++) + { + instanceSize += it->GetCompressedSize(); + } + + Recycle(instanceSize, hasher.HashPatient()); + // Create the instance instance = db_->CreateResource(hasher.HashInstance(), ResourceType_Instance); @@ -355,11 +365,17 @@ 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(); + return StoreStatus_Success; } catch (OrthancException& e) { - LOG(ERROR) << "EXCEPTION2 [" << e.What() << "]" << " " << db_->GetErrorMessage(); + LOG(ERROR) << "EXCEPTION [" << e.What() << "]" + << " (SQLite status: " << db_->GetErrorMessage() << ")"; } return StoreStatus_Failure; @@ -740,4 +756,23 @@ db_->GetLastExportedResource(target); return true; } + + + bool ServerIndex::IsRecyclingNeeded(uint64_t instanceSize) + { + return false; + } + + + void ServerIndex::Recycle(uint64_t instanceSize, + const std::string& newPatientId) + { + if (!IsRecyclingNeeded(instanceSize)) + { + return; + } + + + //throw OrthancException(ErrorCode_FullStorage); + } } diff -r a08dca15790e -r 4bc02e2254ec OrthancServer/ServerIndex.h --- a/OrthancServer/ServerIndex.h Fri Dec 07 13:19:42 2012 +0100 +++ b/OrthancServer/ServerIndex.h Fri Dec 07 13:43:35 2012 +0100 @@ -67,6 +67,11 @@ SeriesStatus GetSeriesStatus(int id); + bool IsRecyclingNeeded(uint64_t instanceSize); + + void Recycle(uint64_t instanceSize, + const std::string& newPatientId); + public: typedef std::list Attachments; diff -r a08dca15790e -r 4bc02e2254ec UnitTests/ServerIndex.cpp --- a/UnitTests/ServerIndex.cpp Fri Dec 07 13:19:42 2012 +0100 +++ b/UnitTests/ServerIndex.cpp Fri Dec 07 13:43:35 2012 +0100 @@ -369,10 +369,12 @@ int64_t p; ASSERT_TRUE(index.SelectPatientToRecycle(p)); ASSERT_EQ(p, patients[0]); index.DeleteResource(p); + ASSERT_TRUE(index.SelectPatientToRecycle(p, patients[1])); ASSERT_EQ(p, patients[4]); ASSERT_TRUE(index.SelectPatientToRecycle(p)); ASSERT_EQ(p, patients[1]); index.DeleteResource(p); ASSERT_TRUE(index.SelectPatientToRecycle(p)); ASSERT_EQ(p, patients[4]); index.DeleteResource(p); + ASSERT_FALSE(index.SelectPatientToRecycle(p, patients[2])); ASSERT_TRUE(index.SelectPatientToRecycle(p)); ASSERT_EQ(p, patients[2]); index.DeleteResource(p); // "patients[3]" is still protected @@ -384,6 +386,8 @@ index.SetProtectedPatient(patients[3], false); ASSERT_EQ(1u, index.GetTableRecordCount("PatientRecyclingOrder")); + ASSERT_FALSE(index.SelectPatientToRecycle(p, patients[3])); + ASSERT_TRUE(index.SelectPatientToRecycle(p, patients[2])); ASSERT_TRUE(index.SelectPatientToRecycle(p)); ASSERT_EQ(p, patients[3]); index.DeleteResource(p);