Mercurial > hg > orthanc
comparison OrthancServer/Sources/ServerIndex.cpp @ 4584:b25941dcdbbe db-changes
ITransactionContext to uncouple ServerIndex from database wrapper
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 09 Mar 2021 16:18:24 +0100 |
parents | 42a846166fa3 |
children | f0bdd99f3d81 |
comparison
equal
deleted
inserted
replaced
4583:42a846166fa3 | 4584:b25941dcdbbe |
---|---|
75 pos ++; | 75 pos ++; |
76 } | 76 } |
77 } | 77 } |
78 | 78 |
79 | 79 |
80 class ServerIndex::Listener : public IDatabaseListener | 80 class ServerIndex::Listener : public IDatabaseListener, |
81 public ServerIndex::ITransactionContext | |
81 { | 82 { |
82 private: | 83 private: |
83 struct FileToRemove | 84 struct FileToRemove |
84 { | 85 { |
85 private: | 86 private: |
211 const std::string& publicId) ORTHANC_OVERRIDE | 212 const std::string& publicId) ORTHANC_OVERRIDE |
212 { | 213 { |
213 SignalChange(ServerIndexChange(ChangeType_Deleted, type, publicId)); | 214 SignalChange(ServerIndexChange(ChangeType_Deleted, type, publicId)); |
214 } | 215 } |
215 | 216 |
216 void SignalChange(const ServerIndexChange& change) | 217 virtual void SignalChange(const ServerIndexChange& change) ORTHANC_OVERRIDE |
217 { | 218 { |
218 LOG(TRACE) << "Change related to resource " << change.GetPublicId() << " of type " | 219 LOG(TRACE) << "Change related to resource " << change.GetPublicId() << " of type " |
219 << EnumerationToString(change.GetResourceType()) << ": " | 220 << EnumerationToString(change.GetResourceType()) << ": " |
220 << EnumerationToString(change.GetChangeType()); | 221 << EnumerationToString(change.GetChangeType()); |
221 | 222 |
227 { | 228 { |
228 context_.SignalChange(change); | 229 context_.SignalChange(change); |
229 } | 230 } |
230 } | 231 } |
231 | 232 |
232 void SignalAttachmentsAdded(uint64_t compressedSize) | 233 virtual void SignalAttachmentsAdded(uint64_t compressedSize) ORTHANC_OVERRIDE |
233 { | 234 { |
234 sizeOfAddedAttachments_ += compressedSize; | 235 sizeOfAddedAttachments_ += compressedSize; |
235 } | 236 } |
236 | 237 |
237 bool HasRemainingLevel() const | 238 bool HasRemainingLevel() const |
252 } | 253 } |
253 | 254 |
254 uint64_t GetSizeOfAddedAttachments() const | 255 uint64_t GetSizeOfAddedAttachments() const |
255 { | 256 { |
256 return sizeOfAddedAttachments_; | 257 return sizeOfAddedAttachments_; |
258 } | |
259 | |
260 virtual bool LookupRemainingLevel(std::string& remainingPublicId /* out */, | |
261 ResourceType& remainingLevel /* out */) ORTHANC_OVERRIDE | |
262 { | |
263 if (HasRemainingLevel()) | |
264 { | |
265 remainingPublicId = GetRemainingPublicId(); | |
266 remainingLevel = GetRemainingType(); | |
267 return true; | |
268 } | |
269 else | |
270 { | |
271 return false; | |
272 } | |
273 }; | |
274 | |
275 virtual void MarkAsUnstable(int64_t id, | |
276 Orthanc::ResourceType type, | |
277 const std::string& publicId) ORTHANC_OVERRIDE | |
278 { | |
279 context_.GetIndex().MarkAsUnstable(id, type, publicId); | |
280 } | |
281 | |
282 virtual bool IsUnstableResource(int64_t id) ORTHANC_OVERRIDE | |
283 { | |
284 return context_.GetIndex().IsUnstableResource(id); | |
257 } | 285 } |
258 }; | 286 }; |
259 | 287 |
260 | 288 |
261 class ServerIndex::Transaction | 289 class ServerIndex::Transaction |
508 if (changeType <= ChangeType_INTERNAL_LastLogged) | 536 if (changeType <= ChangeType_INTERNAL_LastLogged) |
509 { | 537 { |
510 db_.LogChange(internalId, change); | 538 db_.LogChange(internalId, change); |
511 } | 539 } |
512 | 540 |
513 listener_.SignalChange(change); | 541 GetTransactionContext().SignalChange(change); |
514 } | 542 } |
515 | 543 |
516 | 544 |
517 bool ServerIndex::IsUnstableResource(int64_t id) | 545 bool ServerIndex::IsUnstableResource(int64_t id) |
518 { | 546 { |
547 boost::mutex::scoped_lock lock(monitoringMutex_); | |
519 return unstableResources_.Contains(id); | 548 return unstableResources_.Contains(id); |
520 } | 549 } |
521 | 550 |
522 | 551 |
523 ServerIndex::ServerIndex(ServerContext& context, | 552 ServerIndex::ServerIndex(ServerContext& context, |
1077 * global mutex protecting the database. | 1106 * global mutex protecting the database. |
1078 **/ | 1107 **/ |
1079 | 1108 |
1080 Transaction transaction(*this, TransactionType_ReadOnly); // TODO - Only if not "TransactionType_Implicit" | 1109 Transaction transaction(*this, TransactionType_ReadOnly); // TODO - Only if not "TransactionType_Implicit" |
1081 { | 1110 { |
1082 ReadOnlyTransaction t(db_); | 1111 ReadOnlyTransaction t(db_, *listener_); |
1083 readOperations->Apply(t); | 1112 readOperations->Apply(t); |
1084 } | 1113 } |
1085 transaction.Commit(); | 1114 transaction.Commit(); |
1086 } | 1115 } |
1087 else | 1116 else |
1151 ResourceType level) | 1180 ResourceType level) |
1152 { | 1181 { |
1153 class Operations : public ReadOnlyOperationsT4<bool&, Json::Value&, const std::string&, ResourceType> | 1182 class Operations : public ReadOnlyOperationsT4<bool&, Json::Value&, const std::string&, ResourceType> |
1154 { | 1183 { |
1155 private: | 1184 private: |
1156 ServerIndex& index_; // TODO - REMOVE | |
1157 | |
1158 static bool LookupStringMetadata(std::string& result, | 1185 static bool LookupStringMetadata(std::string& result, |
1159 const std::map<MetadataType, std::string>& metadata, | 1186 const std::map<MetadataType, std::string>& metadata, |
1160 MetadataType type) | 1187 MetadataType type) |
1161 { | 1188 { |
1162 std::map<MetadataType, std::string>::const_iterator found = metadata.find(type); | 1189 std::map<MetadataType, std::string>::const_iterator found = metadata.find(type); |
1194 } | 1221 } |
1195 } | 1222 } |
1196 | 1223 |
1197 | 1224 |
1198 public: | 1225 public: |
1199 explicit Operations(ServerIndex& index) : | |
1200 index_(index) | |
1201 { | |
1202 } | |
1203 | |
1204 virtual void ApplyTuple(ReadOnlyTransaction& transaction, | 1226 virtual void ApplyTuple(ReadOnlyTransaction& transaction, |
1205 const Tuple& tuple) ORTHANC_OVERRIDE | 1227 const Tuple& tuple) ORTHANC_OVERRIDE |
1206 { | 1228 { |
1207 // Lookup for the requested resource | 1229 // Lookup for the requested resource |
1208 int64_t internalId; // unused | 1230 int64_t internalId; // unused |
1367 | 1389 |
1368 if (type == ResourceType_Patient || | 1390 if (type == ResourceType_Patient || |
1369 type == ResourceType_Study || | 1391 type == ResourceType_Study || |
1370 type == ResourceType_Series) | 1392 type == ResourceType_Series) |
1371 { | 1393 { |
1372 target["IsStable"] = !index_.IsUnstableResource(internalId); | 1394 target["IsStable"] = !transaction.GetTransactionContext().IsUnstableResource(internalId); |
1373 | 1395 |
1374 if (LookupStringMetadata(tmp, metadata, MetadataType_LastUpdate)) | 1396 if (LookupStringMetadata(tmp, metadata, MetadataType_LastUpdate)) |
1375 { | 1397 { |
1376 target["LastUpdate"] = tmp; | 1398 target["LastUpdate"] = tmp; |
1377 } | 1399 } |
1381 } | 1403 } |
1382 } | 1404 } |
1383 }; | 1405 }; |
1384 | 1406 |
1385 bool found; | 1407 bool found; |
1386 Operations operations(*this); | 1408 Operations operations; |
1387 operations.Apply(*this, found, target, publicId, level); | 1409 operations.Apply(*this, found, target, publicId, level); |
1388 return found; | 1410 return found; |
1389 } | 1411 } |
1390 | 1412 |
1391 | 1413 |
2409 else | 2431 else |
2410 { | 2432 { |
2411 found_ = true; | 2433 found_ = true; |
2412 transaction.DeleteResource(id); | 2434 transaction.DeleteResource(id); |
2413 | 2435 |
2414 if (transaction.GetListener().HasRemainingLevel()) | 2436 std::string remainingPublicId; |
2415 { | 2437 ResourceType remainingLevel; |
2416 ResourceType remainingType = transaction.GetListener().GetRemainingType(); | 2438 if (transaction.GetTransactionContext().LookupRemainingLevel(remainingPublicId, remainingLevel)) |
2417 const std::string& remainingUuid = transaction.GetListener().GetRemainingPublicId(); | 2439 { |
2418 | |
2419 target_["RemainingAncestor"] = Json::Value(Json::objectValue); | 2440 target_["RemainingAncestor"] = Json::Value(Json::objectValue); |
2420 target_["RemainingAncestor"]["Path"] = GetBasePath(remainingType, remainingUuid); | 2441 target_["RemainingAncestor"]["Path"] = GetBasePath(remainingLevel, remainingPublicId); |
2421 target_["RemainingAncestor"]["Type"] = EnumerationToString(remainingType); | 2442 target_["RemainingAncestor"]["Type"] = EnumerationToString(remainingLevel); |
2422 target_["RemainingAncestor"]["ID"] = remainingUuid; | 2443 target_["RemainingAncestor"]["ID"] = remainingPublicId; |
2423 } | 2444 } |
2424 else | 2445 else |
2425 { | 2446 { |
2426 target_["RemainingAncestor"] = Json::nullValue; | 2447 target_["RemainingAncestor"] = Json::nullValue; |
2427 } | 2448 } |
3095 class Operations : public IReadWriteOperations | 3116 class Operations : public IReadWriteOperations |
3096 { | 3117 { |
3097 private: | 3118 private: |
3098 StoreStatus storeStatus_; | 3119 StoreStatus storeStatus_; |
3099 std::map<MetadataType, std::string>& instanceMetadata_; | 3120 std::map<MetadataType, std::string>& instanceMetadata_; |
3100 ServerIndex& index_; | |
3101 const DicomMap& dicomSummary_; | 3121 const DicomMap& dicomSummary_; |
3102 const Attachments& attachments_; | 3122 const Attachments& attachments_; |
3103 const MetadataMap& metadata_; | 3123 const MetadataMap& metadata_; |
3104 const DicomInstanceOrigin& origin_; | 3124 const DicomInstanceOrigin& origin_; |
3105 bool overwrite_; | 3125 bool overwrite_; |
3184 return false; | 3204 return false; |
3185 } | 3205 } |
3186 | 3206 |
3187 public: | 3207 public: |
3188 Operations(std::map<MetadataType, std::string>& instanceMetadata, | 3208 Operations(std::map<MetadataType, std::string>& instanceMetadata, |
3189 ServerIndex& index, | |
3190 const DicomMap& dicomSummary, | 3209 const DicomMap& dicomSummary, |
3191 const Attachments& attachments, | 3210 const Attachments& attachments, |
3192 const MetadataMap& metadata, | 3211 const MetadataMap& metadata, |
3193 const DicomInstanceOrigin& origin, | 3212 const DicomInstanceOrigin& origin, |
3194 bool overwrite, | 3213 bool overwrite, |
3198 uint64_t pixelDataOffset, | 3217 uint64_t pixelDataOffset, |
3199 uint64_t maximumStorageSize, | 3218 uint64_t maximumStorageSize, |
3200 unsigned int maximumPatientCount) : | 3219 unsigned int maximumPatientCount) : |
3201 storeStatus_(StoreStatus_Failure), | 3220 storeStatus_(StoreStatus_Failure), |
3202 instanceMetadata_(instanceMetadata), | 3221 instanceMetadata_(instanceMetadata), |
3203 index_(index), | |
3204 dicomSummary_(dicomSummary), | 3222 dicomSummary_(dicomSummary), |
3205 attachments_(attachments), | 3223 attachments_(attachments), |
3206 metadata_(metadata), | 3224 metadata_(metadata), |
3207 origin_(origin), | 3225 origin_(origin), |
3208 overwrite_(overwrite), | 3226 overwrite_(overwrite), |
3475 transaction.LogChange(status.seriesId_, ChangeType_NewChildInstance, ResourceType_Series, hashSeries_); | 3493 transaction.LogChange(status.seriesId_, ChangeType_NewChildInstance, ResourceType_Series, hashSeries_); |
3476 transaction.LogChange(status.studyId_, ChangeType_NewChildInstance, ResourceType_Study, hashStudy_); | 3494 transaction.LogChange(status.studyId_, ChangeType_NewChildInstance, ResourceType_Study, hashStudy_); |
3477 transaction.LogChange(status.patientId_, ChangeType_NewChildInstance, ResourceType_Patient, hashPatient_); | 3495 transaction.LogChange(status.patientId_, ChangeType_NewChildInstance, ResourceType_Patient, hashPatient_); |
3478 | 3496 |
3479 // Mark the parent resources of this instance as unstable | 3497 // Mark the parent resources of this instance as unstable |
3480 index_.MarkAsUnstable(status.seriesId_, ResourceType_Series, hashSeries_); | 3498 transaction.GetTransactionContext().MarkAsUnstable(status.seriesId_, ResourceType_Series, hashSeries_); |
3481 index_.MarkAsUnstable(status.studyId_, ResourceType_Study, hashStudy_); | 3499 transaction.GetTransactionContext().MarkAsUnstable(status.studyId_, ResourceType_Study, hashStudy_); |
3482 index_.MarkAsUnstable(status.patientId_, ResourceType_Patient, hashPatient_); | 3500 transaction.GetTransactionContext().MarkAsUnstable(status.patientId_, ResourceType_Patient, hashPatient_); |
3483 | 3501 transaction.GetTransactionContext().SignalAttachmentsAdded(instanceSize); |
3484 transaction.GetListener().SignalAttachmentsAdded(instanceSize); | |
3485 | 3502 |
3486 storeStatus_ = StoreStatus_Success; | 3503 storeStatus_ = StoreStatus_Success; |
3487 } | 3504 } |
3488 catch (OrthancException& e) | 3505 catch (OrthancException& e) |
3489 { | 3506 { |
3501 boost::mutex::scoped_lock lock(monitoringMutex_); | 3518 boost::mutex::scoped_lock lock(monitoringMutex_); |
3502 maximumStorageSize = maximumStorageSize_; | 3519 maximumStorageSize = maximumStorageSize_; |
3503 maximumPatients = maximumPatients_; | 3520 maximumPatients = maximumPatients_; |
3504 } | 3521 } |
3505 | 3522 |
3506 Operations operations(instanceMetadata, *this, dicomSummary, attachments, metadata, origin, | 3523 Operations operations(instanceMetadata, dicomSummary, attachments, metadata, origin, |
3507 overwrite, hasTransferSyntax, transferSyntax, hasPixelDataOffset, | 3524 overwrite, hasTransferSyntax, transferSyntax, hasPixelDataOffset, |
3508 pixelDataOffset, maximumStorageSize, maximumPatients); | 3525 pixelDataOffset, maximumStorageSize, maximumPatients); |
3509 Apply(operations); | 3526 Apply(operations); |
3510 return operations.GetStoreStatus(); | 3527 return operations.GetStoreStatus(); |
3511 } | 3528 } |
3581 if (IsUserContentType(attachment_.GetContentType())) | 3598 if (IsUserContentType(attachment_.GetContentType())) |
3582 { | 3599 { |
3583 transaction.LogChange(resourceId, ChangeType_UpdatedAttachment, resourceType, publicId_); | 3600 transaction.LogChange(resourceId, ChangeType_UpdatedAttachment, resourceType, publicId_); |
3584 } | 3601 } |
3585 | 3602 |
3586 transaction.GetListener().SignalAttachmentsAdded(attachment_.GetCompressedSize()); | 3603 transaction.GetTransactionContext().SignalAttachmentsAdded(attachment_.GetCompressedSize()); |
3587 | 3604 |
3588 status_ = StoreStatus_Success; | 3605 status_ = StoreStatus_Success; |
3589 } | 3606 } |
3590 } | 3607 } |
3591 }; | 3608 }; |