changeset 5891:53e7a0c0648f find-refactoring

refactored StatelessDatabaseOperations::GetChildInstances()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 30 Nov 2024 21:20:33 +0100
parents 91d7c05eda4e
children e92f196afd04
files OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp OrthancServer/Sources/Database/StatelessDatabaseOperations.h OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp OrthancServer/Sources/ServerJobs/MergeStudyJob.cpp
diffstat 5 files changed, 48 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp	Sat Nov 30 15:48:28 2024 +0100
+++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp	Sat Nov 30 21:20:33 2024 +0100
@@ -931,65 +931,43 @@
 
 
   void StatelessDatabaseOperations::GetChildInstances(std::list<std::string>& result,
+                                                      const std::string& publicId,
+                                                      ResourceType level)
+  {
+    result.clear();
+    if (level == ResourceType_Instance)
+    {
+      result.push_back(publicId);
+    }
+    else
+    {
+      FindRequest request(level);
+      request.SetOrthancId(level, publicId);
+      request.GetChildrenSpecification(ResourceType_Instance).SetRetrieveIdentifiers(true);
+
+      FindResponse response;
+      const std::set<std::string>& instances = ExecuteSingleResource(response, request).GetChildrenIdentifiers(ResourceType_Instance);
+
+      for (std::set<std::string>::const_iterator it = instances.begin(); it != instances.end(); ++it)
+      {
+        result.push_back(*it);
+      }
+    }
+  }
+
+
+  void StatelessDatabaseOperations::GetChildInstances(std::list<std::string>& result,
                                                       const std::string& publicId)
   {
-    // TODO-FIND
-
-    class Operations : public ReadOnlyOperationsT2<std::list<std::string>&, const std::string&>
+    ResourceType level;
+    if (LookupResourceType(level, publicId))
     {
-    public:
-      virtual void ApplyTuple(ReadOnlyTransaction& transaction,
-                              const Tuple& tuple) ORTHANC_OVERRIDE
-      {
-        tuple.get<0>().clear();
-        
-        ResourceType type;
-        int64_t top;
-        if (!transaction.LookupResource(top, type, tuple.get<1>()))
-        {
-          throw OrthancException(ErrorCode_UnknownResource);
-        }
-        else if (type == ResourceType_Instance)
-        {
-          // The resource is already an instance: Do not go down the hierarchy
-          tuple.get<0>().push_back(tuple.get<1>());
-        }
-        else
-        {
-          std::stack<int64_t> toExplore;
-          toExplore.push(top);
-
-          std::list<int64_t> tmp;
-          while (!toExplore.empty())
-          {
-            // Get the internal ID of the current resource
-            int64_t resource = toExplore.top();
-            toExplore.pop();
-
-            // TODO - This could be optimized by seeing how many
-            // levels "type == transaction.GetResourceType(top)" is
-            // above the "instances level"
-            if (transaction.GetResourceType(resource) == ResourceType_Instance)
-            {
-              tuple.get<0>().push_back(transaction.GetPublicId(resource));
-            }
-            else
-            {
-              // Tag all the children of this resource as to be explored
-              transaction.GetChildrenInternalId(tmp, resource);
-              for (std::list<int64_t>::const_iterator 
-                     it = tmp.begin(); it != tmp.end(); ++it)
-              {
-                toExplore.push(*it);
-              }
-            }
-          }
-        }
-      }
-    };
-    
-    Operations operations;
-    operations.Apply(*this, result, publicId);
+      GetChildInstances(result, publicId, level);
+    }
+    else
+    {
+      throw OrthancException(ErrorCode_UnknownResource);
+    }
   }
 
 
--- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.h	Sat Nov 30 15:48:28 2024 +0100
+++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.h	Sat Nov 30 21:20:33 2024 +0100
@@ -562,6 +562,11 @@
                      ResourceType level,
                      const std::string& publicId);
 
+    // Always prefer this flavor, which is more efficient than the flavor without "level"
+    void GetChildInstances(std::list<std::string>& result,
+                           const std::string& publicId,
+                           ResourceType level);
+
     void GetChildInstances(std::list<std::string>& result,
                            const std::string& publicId);
 
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Sat Nov 30 15:48:28 2024 +0100
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Sat Nov 30 21:20:33 2024 +0100
@@ -807,7 +807,7 @@
       {
         // Retrieve all the instances of the parent resource
         std::list<std::string>  siblingInstances;
-        context.GetIndex().GetChildInstances(siblingInstances, parent);
+        context.GetIndex().GetChildInstances(siblingInstances, parent, parentType);
 
         if (siblingInstances.empty())
 	{
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Sat Nov 30 15:48:28 2024 +0100
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp	Sat Nov 30 21:20:33 2024 +0100
@@ -2767,12 +2767,13 @@
 
   static bool ExtractSharedTags(Json::Value& shared,
                                 ServerContext& context,
-                                const std::string& publicId)
+                                const std::string& publicId,
+                                ResourceType level)
   {
     // Retrieve all the instances of this patient/study/series
     typedef std::list<std::string> Instances;
     Instances instances;
-    context.GetIndex().GetChildInstances(instances, publicId);  // (*)
+    context.GetIndex().GetChildInstances(instances, publicId, level);  // (*)
 
     // Loop over the instances
     bool isFirst = true;
@@ -2864,7 +2865,7 @@
     std::string publicId = call.GetUriComponent("id", "");
 
     Json::Value sharedTags;
-    if (ExtractSharedTags(sharedTags, context, publicId))
+    if (ExtractSharedTags(sharedTags, context, publicId, level))
     {
       // Success: Send the value of the shared tags
       AnswerDicomAsJson(call, sharedTags, OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Full));
@@ -2939,7 +2940,7 @@
       // Retrieve all the instances of this patient/study/series
       typedef std::list<std::string> Instances;
       Instances instances;
-      context.GetIndex().GetChildInstances(instances, publicId);
+      context.GetIndex().GetChildInstances(instances, publicId, resourceType);
 
       if (instances.empty())
       {
@@ -3578,7 +3579,7 @@
     typedef std::list<std::string> Instances;
     Instances instances;
 
-    context.GetIndex().GetChildInstances(instances, publicId);  // (*)
+    context.GetIndex().GetChildInstances(instances, publicId, level);  // (*)
 
     Json::Value result = Json::objectValue;
 
@@ -3784,7 +3785,7 @@
            study = studies.begin(); study != studies.end(); ++study)
     {
       std::list<std::string> instances;
-      index.GetChildInstances(instances, *study);
+      index.GetChildInstances(instances, *study, ResourceType_Study);
 
       for (std::list<std::string>::const_iterator 
              instance = instances.begin(); instance != instances.end(); ++instance)
--- a/OrthancServer/Sources/ServerJobs/MergeStudyJob.cpp	Sat Nov 30 15:48:28 2024 +0100
+++ b/OrthancServer/Sources/ServerJobs/MergeStudyJob.cpp	Sat Nov 30 21:20:33 2024 +0100
@@ -190,7 +190,7 @@
     DicomTag::AddTagsForModule(removals_, DicomModule_Study);
     
     std::list<std::string> instances;
-    GetContext().GetIndex().GetChildInstances(instances, targetStudy);
+    GetContext().GetIndex().GetChildInstances(instances, targetStudy, ResourceType_Study);
     
     if (instances.empty())
     {