# HG changeset patch # User Sebastien Jodogne # Date 1447861088 -3600 # Node ID bdcc1dba4a531a56a53810e29c1b0d53849984fe # Parent 6a2d507ef06453d8cb8981b2064c3e1603c8638b optimization diff -r 6a2d507ef064 -r bdcc1dba4a53 OrthancServer/DicomProtocol/DicomFindAnswers.cpp --- a/OrthancServer/DicomProtocol/DicomFindAnswers.cpp Wed Nov 18 16:11:28 2015 +0100 +++ b/OrthancServer/DicomProtocol/DicomFindAnswers.cpp Wed Nov 18 16:38:08 2015 +0100 @@ -38,56 +38,138 @@ #include "../../Core/OrthancException.h" #include +#include + namespace Orthanc { + class DicomFindAnswers::Answer + { + private: + ParsedDicomFile* dicom_; + DicomMap* map_; + + public: + Answer(ParsedDicomFile& dicom) : + dicom_(dicom.Clone()), + map_(NULL) + { + } + + Answer(const char* dicom, + size_t size) : + dicom_(new ParsedDicomFile(dicom, size)), + map_(NULL) + { + } + + Answer(const DicomMap& map) : + dicom_(NULL), + map_(map.Clone()) + { + } + + ~Answer() + { + if (dicom_ != NULL) + { + delete dicom_; + } + + if (map_ != NULL) + { + delete map_; + } + } + + ParsedDicomFile& GetDicomFile() + { + if (dicom_ == NULL) + { + assert(map_ != NULL); + dicom_ = new ParsedDicomFile(*map_); + } + + return *dicom_; + } + + DcmDataset* ExtractDcmDataset() const + { + if (dicom_ != NULL) + { + return new DcmDataset(*dicom_->GetDcmtkObject().getDataset()); + } + else + { + assert(map_ != NULL); + return ToDcmtkBridge::Convert(*map_); + } + } + }; + + void DicomFindAnswers::Clear() { - for (size_t i = 0; i < items_.size(); i++) + for (size_t i = 0; i < answers_.size(); i++) { - assert(items_[i] != NULL); - delete items_[i]; + assert(answers_[i] != NULL); + delete answers_[i]; } - items_.clear(); + answers_.clear(); } + void DicomFindAnswers::Reserve(size_t size) { - if (size > items_.size()) + if (size > answers_.size()) { - items_.reserve(size); + answers_.reserve(size); } } void DicomFindAnswers::Add(const DicomMap& map) { - items_.push_back(new ParsedDicomFile(map)); + answers_.push_back(new Answer(map)); } + void DicomFindAnswers::Add(ParsedDicomFile& dicom) { - items_.push_back(dicom.Clone()); + answers_.push_back(new Answer(dicom)); } + void DicomFindAnswers::Add(const char* dicom, size_t size) { - items_.push_back(new ParsedDicomFile(dicom, size)); + answers_.push_back(new Answer(dicom, size)); + } + + + DicomFindAnswers::Answer& DicomFindAnswers::GetAnswerInternal(size_t index) const + { + if (index < answers_.size()) + { + return *answers_.at(index); + } + else + { + throw OrthancException(ErrorCode_ParameterOutOfRange); + } } ParsedDicomFile& DicomFindAnswers::GetAnswer(size_t index) const { - if (index < items_.size()) - { - return *items_.at(index); - } - else - { - throw OrthancException(ErrorCode_ParameterOutOfRange); - } + return GetAnswerInternal(index).GetDicomFile(); + } + + + DcmDataset* DicomFindAnswers::ExtractDcmDataset(size_t index) const + { + return GetAnswerInternal(index).ExtractDcmDataset(); } diff -r 6a2d507ef064 -r bdcc1dba4a53 OrthancServer/DicomProtocol/DicomFindAnswers.h --- a/OrthancServer/DicomProtocol/DicomFindAnswers.h Wed Nov 18 16:11:28 2015 +0100 +++ b/OrthancServer/DicomProtocol/DicomFindAnswers.h Wed Nov 18 16:38:08 2015 +0100 @@ -39,7 +39,11 @@ class DicomFindAnswers : public boost::noncopyable { private: - std::vector items_; + class Answer; + + std::vector answers_; + + Answer& GetAnswerInternal(size_t index) const; public: ~DicomFindAnswers() @@ -60,11 +64,13 @@ size_t GetSize() const { - return items_.size(); + return answers_.size(); } ParsedDicomFile& GetAnswer(size_t index) const; + DcmDataset* ExtractDcmDataset(size_t index) const; + void ToJson(Json::Value& target, bool simplify) const; diff -r 6a2d507ef064 -r bdcc1dba4a53 OrthancServer/Internals/FindScp.cpp --- a/OrthancServer/Internals/FindScp.cpp Wed Nov 18 16:11:28 2015 +0100 +++ b/OrthancServer/Internals/FindScp.cpp Wed Nov 18 16:38:08 2015 +0100 @@ -186,11 +186,7 @@ { // There are pending results that are still to be sent response->DimseStatus = STATUS_Pending; - - DcmFileFormat& fileFormat = data.answers_.GetAnswer(responseCount - 1).GetDcmtkObject(); - - // TODO Is there a way to avoid this copy? - *responseIdentifiers = new DcmDataset(*fileFormat.getDataset()); + *responseIdentifiers = data.answers_.ExtractDcmDataset(responseCount - 1); } else if (data.noCroppingOfResults_) { diff -r 6a2d507ef064 -r bdcc1dba4a53 UnitTestsSources/FromDcmtkTests.cpp --- a/UnitTestsSources/FromDcmtkTests.cpp Wed Nov 18 16:11:28 2015 +0100 +++ b/UnitTestsSources/FromDcmtkTests.cpp Wed Nov 18 16:38:08 2015 +0100 @@ -620,6 +620,12 @@ } { + ParsedDicomFile d; + d.Replace(DICOM_TAG_PATIENT_ID, "my"); + a.Add(d); + } + + { DicomMap m; m.SetValue(DICOM_TAG_PATIENT_ID, "world"); a.Add(m); @@ -627,5 +633,7 @@ Json::Value j; a.ToJson(j, true); - ASSERT_EQ(2u, j.size()); + ASSERT_EQ(3u, j.size()); + + //std::cout << j; }