changeset 5667:93dff1fccf36 find-refactoring

recursive descent to the children
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 04 Jul 2024 21:31:48 +0200
parents aa231c18b9d2
children bd1352bd9d82
files OrthancServer/Sources/Database/Compatibility/GenericFind.cpp OrthancServer/Sources/Database/FindRequest.h OrthancServer/Sources/Database/FindResponse.cpp OrthancServer/Sources/ResourceFinder.cpp
diffstat 4 files changed, 117 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/Sources/Database/Compatibility/GenericFind.cpp	Thu Jul 04 18:31:54 2024 +0200
+++ b/OrthancServer/Sources/Database/Compatibility/GenericFind.cpp	Thu Jul 04 21:31:48 2024 +0200
@@ -240,8 +240,7 @@
           return ResourceType_Patient;
 
         case ResourceType_Study:
-          if (request.GetParentRetrieveSpecification(ResourceType_Patient).IsRetrieveMainDicomTags() ||
-              request.GetParentRetrieveSpecification(ResourceType_Patient).IsRetrieveMetadata())
+          if (request.GetParentRetrieveSpecification(ResourceType_Patient).IsOfInterest())
           {
             return ResourceType_Patient;
           }
@@ -251,13 +250,11 @@
           }
 
         case ResourceType_Series:
-          if (request.GetParentRetrieveSpecification(ResourceType_Patient).IsRetrieveMainDicomTags() ||
-              request.GetParentRetrieveSpecification(ResourceType_Patient).IsRetrieveMetadata())
+          if (request.GetParentRetrieveSpecification(ResourceType_Patient).IsOfInterest())
           {
             return ResourceType_Patient;
           }
-          else if (request.GetParentRetrieveSpecification(ResourceType_Study).IsRetrieveMainDicomTags() ||
-                   request.GetParentRetrieveSpecification(ResourceType_Study).IsRetrieveMetadata())
+          else if (request.GetParentRetrieveSpecification(ResourceType_Study).IsOfInterest())
           {
             return ResourceType_Study;
           }
@@ -267,18 +264,15 @@
           }
 
         case ResourceType_Instance:
-          if (request.GetParentRetrieveSpecification(ResourceType_Patient).IsRetrieveMainDicomTags() ||
-              request.GetParentRetrieveSpecification(ResourceType_Patient).IsRetrieveMetadata())
+          if (request.GetParentRetrieveSpecification(ResourceType_Patient).IsOfInterest())
           {
             return ResourceType_Patient;
           }
-          else if (request.GetParentRetrieveSpecification(ResourceType_Study).IsRetrieveMainDicomTags() ||
-                   request.GetParentRetrieveSpecification(ResourceType_Study).IsRetrieveMetadata())
+          else if (request.GetParentRetrieveSpecification(ResourceType_Study).IsOfInterest())
           {
             return ResourceType_Study;
           }
-          else if (request.GetParentRetrieveSpecification(ResourceType_Series).IsRetrieveMainDicomTags() ||
-                   request.GetParentRetrieveSpecification(ResourceType_Series).IsRetrieveMetadata())
+          else if (request.GetParentRetrieveSpecification(ResourceType_Series).IsOfInterest())
           {
             return ResourceType_Series;
           }
@@ -293,6 +287,61 @@
     }
 
 
+    static ResourceType GetBottomLevelOfInterest(const FindRequest& request)
+    {
+      switch (request.GetLevel())
+      {
+        case ResourceType_Patient:
+          if (request.GetChildrenRetrieveSpecification(ResourceType_Instance).IsOfInterest())
+          {
+            return ResourceType_Instance;
+          }
+          else if (request.GetChildrenRetrieveSpecification(ResourceType_Series).IsOfInterest())
+          {
+            return ResourceType_Series;
+          }
+          else if (request.GetChildrenRetrieveSpecification(ResourceType_Study).IsOfInterest())
+          {
+            return ResourceType_Study;
+          }
+          else
+          {
+            return ResourceType_Patient;
+          }
+
+        case ResourceType_Study:
+          if (request.GetChildrenRetrieveSpecification(ResourceType_Instance).IsOfInterest())
+          {
+            return ResourceType_Instance;
+          }
+          else if (request.GetChildrenRetrieveSpecification(ResourceType_Series).IsOfInterest())
+          {
+            return ResourceType_Series;
+          }
+          else
+          {
+            return ResourceType_Study;
+          }
+
+        case ResourceType_Series:
+          if (request.GetChildrenRetrieveSpecification(ResourceType_Instance).IsOfInterest())
+          {
+            return ResourceType_Instance;
+          }
+          else
+          {
+            return ResourceType_Series;
+          }
+
+        case ResourceType_Instance:
+          return ResourceType_Instance;
+
+        default:
+          throw OrthancException(ErrorCode_ParameterOutOfRange);
+      }
+    }
+
+
     void GenericFind::ExecuteExpand(FindResponse& response,
                                     const FindRequest& request,
                                     const std::string& identifier)
@@ -411,20 +460,53 @@
         }
       }
 
-      if (request.GetLevel() != ResourceType_Instance)
       {
-        // TODO-FIND: Retrieve other levels than immediate children
-        const ResourceType childLevel = GetChildResourceType(request.GetLevel());
+        const ResourceType bottomLevel = GetBottomLevelOfInterest(request);
 
-        if (request.GetChildrenRetrieveSpecification(childLevel).IsRetrieveIdentifiers())
+        std::list<int64_t> currentIds;
+        currentIds.push_back(internalId);
+
+        ResourceType currentLevel = level;
+
+        while (currentLevel != bottomLevel)
         {
-          std::list<std::string> children;
-          transaction_.GetChildrenPublicId(children, internalId);
+          ResourceType childrenLevel = GetChildResourceType(currentLevel);
+
+          if (request.GetChildrenRetrieveSpecification(childrenLevel).IsRetrieveIdentifiers())
+          {
+            for (std::list<int64_t>::const_iterator it = currentIds.begin();
+                 it != currentIds.end(); ++it)
+            {
+              std::list<std::string> ids;
+              transaction_.GetChildrenPublicId(ids, *it);
+
+              for (std::list<std::string>::const_iterator it2 = ids.begin(); it2 != ids.end(); ++it2)
+              {
+                resource->AddChildIdentifier(childrenLevel, *it2);
+              }
+            }
+          }
 
-          for (std::list<std::string>::const_iterator it = children.begin(); it != children.end(); ++it)
+          if (childrenLevel != bottomLevel)
           {
-            resource->AddChildIdentifier(childLevel, *it);
+            std::list<int64_t> childrenIds;
+
+            for (std::list<int64_t>::const_iterator it = currentIds.begin(); it != currentIds.end(); ++it)
+            {
+              std::list<int64_t> tmp;
+              transaction_.GetChildrenInternalId(tmp, *it);
+
+              childrenIds.splice(childrenIds.end(), tmp);
+            }
+
+            currentIds = childrenIds;
           }
+          else
+          {
+            currentIds.clear();
+          }
+
+          currentLevel = childrenLevel;
         }
       }
 
--- a/OrthancServer/Sources/Database/FindRequest.h	Thu Jul 04 18:31:54 2024 +0200
+++ b/OrthancServer/Sources/Database/FindRequest.h	Thu Jul 04 21:31:48 2024 +0200
@@ -187,6 +187,11 @@
       {
         return metadata_;
       }
+
+      bool IsOfInterest() const
+      {
+        return (mainDicomTags_ || metadata_);
+      }
     };
 
 
@@ -194,12 +199,10 @@
     {
     private:
       bool  identifiers_;
-      bool  count_;
 
     public:
       ChildrenRetrieveSpecification() :
-        identifiers_(false),
-        count_(false)
+        identifiers_(false)
       {
       }
 
@@ -213,14 +216,9 @@
         return identifiers_;
       }
 
-      void SetRetrieveCount(bool retrieve)
+      bool IsOfInterest() const
       {
-        count_ = retrieve;
-      }
-
-      bool IsRetrieveCount() const
-      {
-        return count_;
+        return identifiers_;
       }
     };
 
--- a/OrthancServer/Sources/Database/FindResponse.cpp	Thu Jul 04 18:31:54 2024 +0200
+++ b/OrthancServer/Sources/Database/FindResponse.cpp	Thu Jul 04 21:31:48 2024 +0200
@@ -531,21 +531,14 @@
       {
         if (request.GetChildrenRetrieveSpecification(levels[i]).IsRetrieveIdentifiers())
         {
-          if (levels[i] != GetChildResourceType(request.GetLevel()))
-          {
-            throw OrthancException(ErrorCode_NotImplemented);  // TODO-FIND
-          }
-          else
-          {
-            const std::set<std::string>& ids = GetChildrenIdentifiers(levels[i]);
+          const std::set<std::string>& ids = GetChildrenIdentifiers(levels[i]);
 
-            Json::Value v = Json::arrayValue;
-            for (std::set<std::string>::const_iterator it = ids.begin(); it != ids.end(); ++it)
-            {
-              v.append(*it);
-            }
-            target[level]["Identifiers"] = v;
+          Json::Value v = Json::arrayValue;
+          for (std::set<std::string>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+          {
+            v.append(*it);
           }
+          target[level]["Identifiers"] = v;
         }
       }
     }
--- a/OrthancServer/Sources/ResourceFinder.cpp	Thu Jul 04 18:31:54 2024 +0200
+++ b/OrthancServer/Sources/ResourceFinder.cpp	Thu Jul 04 21:31:48 2024 +0200
@@ -43,7 +43,7 @@
     {
       requestedComputedTags_.insert(tag);
       hasRequestedTags_ = true;
-      request_.GetChildrenRetrieveSpecification(childLevel).SetRetrieveCount(true);
+      request_.GetChildrenRetrieveSpecification(childLevel).SetRetrieveIdentifiers(true);
     }
   }