# HG changeset patch # User Sebastien Jodogne # Date 1447411879 -3600 # Node ID 0f5c416969dc17b03627a4c3d17a6106b7665150 # Parent 3c28f5f6c9b7114f3d46479c1fc6c418cc135680 more memory-efficient ArchiveIndex diff -r 3c28f5f6c9b7 -r 0f5c416969dc OrthancServer/OrthancRestApi/OrthancRestArchive.cpp --- a/OrthancServer/OrthancRestApi/OrthancRestArchive.cpp Fri Nov 13 11:36:51 2015 +0100 +++ b/OrthancServer/OrthancRestApi/OrthancRestArchive.cpp Fri Nov 13 11:51:19 2015 +0100 @@ -512,22 +512,34 @@ } }; + // A "NULL" value for ArchiveIndex indicates a non-expanded node typedef std::map Resources; - ServerIndex& index_; - ResourceType level_; - Resources resources_; - std::vector instances_; + ResourceType level_; + Resources resources_; // Only at patient/study/series level + std::list instances_; // Only at instance level + - void AddResourceToExpand(const std::string& id) + void AddResourceToExpand(ServerIndex& index, + const std::string& id) { - resources_[id] = NULL; + if (level_ == ResourceType_Instance) + { + FileInfo tmp; + if (index.LookupAttachment(tmp, id, FileContentType_Dicom)) + { + instances_.push_back(Instance(id, tmp)); + } + } + else + { + resources_[id] = NULL; + } } + public: - ArchiveIndex(ServerIndex& index, - ResourceType level) : - index_(index), + ArchiveIndex(ResourceType level) : level_(level) { } @@ -541,12 +553,18 @@ } } - void Add(const ResourceIdentifiers& resource) + + void Add(ServerIndex& index, + const ResourceIdentifiers& resource) { const std::string& id = resource.GetIdentifier(level_); Resources::iterator previous = resources_.find(id); - if (resource.GetLevel() == level_) + if (level_ == ResourceType_Instance) + { + AddResourceToExpand(index, id); + } + else if (resource.GetLevel() == level_) { // Mark this resource for further expansion if (previous != resources_.end()) @@ -559,13 +577,13 @@ else if (previous == resources_.end()) { // This is the first time we meet this resource - std::auto_ptr child(new ArchiveIndex(index_, GetChildResourceType(level_))); - child->Add(resource); + std::auto_ptr child(new ArchiveIndex(GetChildResourceType(level_))); + child->Add(index, resource); resources_[id] = child.release(); } else if (previous->second != NULL) { - previous->second->Add(resource); + previous->second->Add(index, resource); } else { @@ -574,53 +592,37 @@ } - void Expand() + void Expand(ServerIndex& index) { if (level_ == ResourceType_Instance) { - // At the instance level, locate all the DICOM files - // associated with the instances - instances_.reserve(resources_.size()); - - for (Resources::iterator it = resources_.begin(); - it != resources_.end(); ++it) - { - assert(it->second == NULL); + // Expanding an instance node makes no sense + return; + } - FileInfo tmp; - if (index_.LookupAttachment(tmp, it->first, FileContentType_Dicom)) - { - instances_.push_back(Instance(it->first, tmp)); - } - } - } - else + for (Resources::iterator it = resources_.begin(); + it != resources_.end(); ++it) { - // At the patient, study or series level - for (Resources::iterator it = resources_.begin(); - it != resources_.end(); ++it) + if (it->second == NULL) { - if (it->second == NULL) - { - // This is resource is marked for expansion - std::list children; - index_.GetChildren(children, it->first); + // This is resource is marked for expansion + std::list children; + index.GetChildren(children, it->first); - std::auto_ptr child(new ArchiveIndex(index_, GetChildResourceType(level_))); + std::auto_ptr child(new ArchiveIndex(GetChildResourceType(level_))); - for (std::list::const_iterator - it2 = children.begin(); it2 != children.end(); ++it2) - { - child->AddResourceToExpand(*it2); - } - - it->second = child.release(); + for (std::list::const_iterator + it2 = children.begin(); it2 != children.end(); ++it2) + { + child->AddResourceToExpand(index, *it2); } - assert(it->second != NULL); - it->second->Expand(); - } - } + it->second = child.release(); + } + + assert(it->second != NULL); + it->second->Expand(index); + } } @@ -628,9 +630,10 @@ { if (level_ == ResourceType_Instance) { - for (size_t i = 0; i < instances_.size(); i++) + for (std::list::const_iterator + it = instances_.begin(); it != instances_.end(); ++it) { - visitor.AddInstance(instances_[i].id_, instances_[i].dicom_); + visitor.AddInstance(it->id_, it->dicom_); } } else @@ -734,7 +737,7 @@ if (call.ParseJsonRequest(resources) && resources.type() == Json::arrayValue) { - ArchiveIndex archive(index, ResourceType_Patient); // root + ArchiveIndex archive(ResourceType_Patient); // root for (Json::Value::ArrayIndex i = 0; i < resources.size(); i++) { @@ -744,10 +747,10 @@ } ResourceIdentifiers resource(index, resources[i].asString()); - archive.Add(resource); + archive.Add(index, resource); } - archive.Expand(); + archive.Expand(index); PrintVisitor v(std::cout); archive.Apply(v);