changeset 69:d529d9ce3c7e

cache for DicomPyramidInstance
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 25 Nov 2016 21:56:07 +0100
parents c619c8bd72ed
children f2c179294382
files Applications/DicomToTiff.cpp Framework/Inputs/DicomPyramid.cpp Framework/Inputs/DicomPyramid.h Framework/Inputs/DicomPyramidInstance.cpp Framework/Inputs/DicomPyramidInstance.h Resources/Graveyard/Hello.cpp Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.cpp Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.h Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.cpp Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.h Resources/Orthanc/Plugins/Samples/Common/OrthancPluginConnection.cpp Resources/Orthanc/Plugins/Samples/Common/OrthancPluginConnection.h Resources/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.h ViewerPlugin/Plugin.cpp
diffstat 14 files changed, 132 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/DicomToTiff.cpp	Fri Nov 25 21:18:46 2016 +0100
+++ b/Applications/DicomToTiff.cpp	Fri Nov 25 21:56:07 2016 +0100
@@ -300,7 +300,8 @@
       }
 
       OrthancPlugins::OrthancHttpConnection orthanc(params);
-      OrthancWSI::DicomPyramid source(orthanc, options["input"].as<std::string>());
+      OrthancWSI::DicomPyramid source(orthanc, options["input"].as<std::string>(), 
+                                      false /* don't use cached metadata */);
 
       OrthancWSI::TiledPyramidStatistics stats(source);
       Run(stats, options);
--- a/Framework/Inputs/DicomPyramid.cpp	Fri Nov 25 21:18:46 2016 +0100
+++ b/Framework/Inputs/DicomPyramid.cpp	Fri Nov 25 21:56:07 2016 +0100
@@ -60,7 +60,8 @@
   }
 
 
-  void DicomPyramid::RegisterInstances(const std::string& seriesId)
+  void DicomPyramid::RegisterInstances(const std::string& seriesId,
+                                       bool useCache)
   {
     Json::Value series;
     OrthancPlugins::IOrthancConnection::RestApiGet(series, orthanc_, "/series/" + seriesId);
@@ -86,7 +87,7 @@
 
       try
       {
-        instances_.push_back(new DicomPyramidInstance(orthanc_, instance));
+        instances_.push_back(new DicomPyramidInstance(orthanc_, instance, useCache));
       }
       catch (Orthanc::OrthancException&)
       {
@@ -138,11 +139,12 @@
 
 
   DicomPyramid::DicomPyramid(OrthancPlugins::IOrthancConnection& orthanc,
-                             const std::string& seriesId) :
+                             const std::string& seriesId,
+                             bool useCache) :
     orthanc_(orthanc),
     seriesId_(seriesId)
   {
-    RegisterInstances(seriesId);
+    RegisterInstances(seriesId, useCache);
 
     // Sort the instances of the pyramid by decreasing total widths
     std::sort(instances_.begin(), instances_.end(), Comparator());
--- a/Framework/Inputs/DicomPyramid.h	Fri Nov 25 21:18:46 2016 +0100
+++ b/Framework/Inputs/DicomPyramid.h	Fri Nov 25 21:56:07 2016 +0100
@@ -38,7 +38,8 @@
 
     void Clear();
 
-    void RegisterInstances(const std::string& seriesId);
+    void RegisterInstances(const std::string& seriesId,
+                           bool useCache);
 
     void Check(const std::string& seriesId) const;
 
@@ -46,7 +47,8 @@
 
   public:
     DicomPyramid(OrthancPlugins::IOrthancConnection& orthanc,
-                 const std::string& seriesId);
+                 const std::string& seriesId,
+                 bool useCache);
 
     virtual ~DicomPyramid()
     {
--- a/Framework/Inputs/DicomPyramidInstance.cpp	Fri Nov 25 21:18:46 2016 +0100
+++ b/Framework/Inputs/DicomPyramidInstance.cpp	Fri Nov 25 21:56:07 2016 +0100
@@ -31,6 +31,8 @@
 #include <cassert>
 #include <json/writer.h>
 
+#define SERIALIZED_METADATA  "4200"
+
 namespace OrthancWSI
 {
   static ImageCompression DetectImageCompression(OrthancPlugins::IOrthancConnection& orthanc,
@@ -137,6 +139,7 @@
       throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
     }
 
+    hasCompression_ = false;
     format_ = DetectPixelFormat(reader);
     tileWidth_ = reader.GetUnsignedIntegerValue(DICOM_TAG_COLUMNS);
     tileHeight_ = reader.GetUnsignedIntegerValue(DICOM_TAG_ROWS);
@@ -193,11 +196,33 @@
 
 
   DicomPyramidInstance::DicomPyramidInstance(OrthancPlugins::IOrthancConnection&  orthanc,
-                                             const std::string& instanceId) :
+                                             const std::string& instanceId,
+                                             bool useCache) :
     instanceId_(instanceId),
     hasCompression_(false)
   {
+    if (useCache)
+    {
+      try
+      {
+        // Try and deserialized the cached information about this instance
+        std::string serialized;
+        orthanc.RestApiGet(serialized, "/instances/" + instanceId + "/metadata/" + SERIALIZED_METADATA);
+        Deserialize(serialized);
+        return;  // Success
+      }
+      catch (Orthanc::OrthancException&)
+      {
+      }
+    }
+
+    // No cached information, compute it from scratch
     Load(orthanc, instanceId);
+
+    // Serialize the computed information and cache it as a metadata
+    std::string serialized, tmp;
+    Serialize(serialized);
+    orthanc.RestApiPut(tmp, "/instances/" + instanceId + "/metadata/" + SERIALIZED_METADATA, serialized);
   }
 
 
@@ -281,7 +306,7 @@
       throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
     }
 
-    switch (content["Frames"].asInt())
+    switch (content["PixelFormat"].asInt())
     {
       case 0:
         format_ = Orthanc::PixelFormat_RGB24;
@@ -295,6 +320,7 @@
         throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
     }
 
+    hasCompression_ = false;
     tileHeight_ = static_cast<unsigned int>(content["TileHeight"].asInt());
     tileWidth_ = static_cast<unsigned int>(content["TileWidth"].asInt());
     totalHeight_ = static_cast<unsigned int>(content["TotalHeight"].asInt());
--- a/Framework/Inputs/DicomPyramidInstance.h	Fri Nov 25 21:18:46 2016 +0100
+++ b/Framework/Inputs/DicomPyramidInstance.h	Fri Nov 25 21:56:07 2016 +0100
@@ -50,7 +50,8 @@
 
   public:
     DicomPyramidInstance(OrthancPlugins::IOrthancConnection&  orthanc,
-                         const std::string& instanceId);
+                         const std::string& instanceId,
+                         bool useCache);
 
     const std::string& GetInstanceId() const
     {
--- a/Resources/Graveyard/Hello.cpp	Fri Nov 25 21:18:46 2016 +0100
+++ b/Resources/Graveyard/Hello.cpp	Fri Nov 25 21:56:07 2016 +0100
@@ -66,7 +66,7 @@
     }
 
 #else
-    OrthancWSI::DicomPyramid pyramid(orthanc, "68bc53a6-8bd5b470-05072b43-af144cf8-665c54fd");
+    OrthancWSI::DicomPyramid pyramid(orthanc, "09d0cca4-a8f0cd78-5480c690-ed14eb3b-a6614d14", true);
     //OrthancWSI::DicomPyramid pyramid(orthanc, "4fdff9b9-8b81bc8f-04a3f903-4d44bd57-cc3bf42c");
 #endif
   }
--- a/Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.cpp	Fri Nov 25 21:18:46 2016 +0100
+++ b/Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.cpp	Fri Nov 25 21:56:07 2016 +0100
@@ -69,4 +69,15 @@
     orthanc.RestApiPost(content, uri, body);
     ParseJson(result, content);
   }
+
+
+  void IOrthancConnection::RestApiPut(Json::Value& result,
+                                      IOrthancConnection& orthanc,
+                                      const std::string& uri,
+                                      const std::string& body)
+  {
+    std::string content;
+    orthanc.RestApiPut(content, uri, body);
+    ParseJson(result, content);
+  }
 }
--- a/Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.h	Fri Nov 25 21:18:46 2016 +0100
+++ b/Resources/Orthanc/Plugins/Samples/Common/IOrthancConnection.h	Fri Nov 25 21:56:07 2016 +0100
@@ -54,6 +54,12 @@
                              const std::string& uri,
                              const std::string& body) = 0;
 
+    virtual void RestApiPut(std::string& result,
+                            const std::string& uri,
+                            const std::string& body) = 0;
+
+    virtual void RestApiDelete(const std::string& uri) = 0;
+
     static void ParseJson(Json::Value& result,
                           const std::string& content);
 
@@ -65,5 +71,10 @@
                             IOrthancConnection& orthanc,
                             const std::string& uri,
                             const std::string& body);
+
+    static void RestApiPut(Json::Value& result,
+                           IOrthancConnection& orthanc,
+                           const std::string& uri,
+                           const std::string& body);
   };
 }
--- a/Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.cpp	Fri Nov 25 21:18:46 2016 +0100
+++ b/Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.cpp	Fri Nov 25 21:56:07 2016 +0100
@@ -79,4 +79,29 @@
     client_.SetBody(body);
     client_.ApplyAndThrowException(result);
   }
+
+
+  void OrthancHttpConnection::RestApiPut(std::string& result,
+                                         const std::string& uri,
+                                         const std::string& body)
+  {
+    boost::mutex::scoped_lock lock(mutex_);
+
+    client_.SetMethod(Orthanc::HttpMethod_Put);
+    client_.SetUrl(url_ + uri);
+    client_.SetBody(body);
+    client_.ApplyAndThrowException(result);
+  }
+
+
+  void OrthancHttpConnection::RestApiDelete(const std::string& uri)
+  {
+    boost::mutex::scoped_lock lock(mutex_);
+
+    std::string result;
+
+    client_.SetMethod(Orthanc::HttpMethod_Delete);
+    client_.SetUrl(url_ + uri);
+    client_.ApplyAndThrowException(result);
+  }
 }
--- a/Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.h	Fri Nov 25 21:18:46 2016 +0100
+++ b/Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.h	Fri Nov 25 21:56:07 2016 +0100
@@ -65,5 +65,11 @@
     virtual void RestApiPost(std::string& result,
                              const std::string& uri,
                              const std::string& body);
+
+    virtual void RestApiPut(std::string& result,
+                            const std::string& uri,
+                            const std::string& body);
+
+    virtual void RestApiDelete(const std::string& uri);
   };
 }
--- a/Resources/Orthanc/Plugins/Samples/Common/OrthancPluginConnection.cpp	Fri Nov 25 21:18:46 2016 +0100
+++ b/Resources/Orthanc/Plugins/Samples/Common/OrthancPluginConnection.cpp	Fri Nov 25 21:56:07 2016 +0100
@@ -58,7 +58,7 @@
   {
     OrthancPlugins::MemoryBuffer buffer(context_);
 
-    if (!buffer.RestApiPost(uri, body.c_str(), body.size(), false))
+    if (buffer.RestApiPost(uri, body.c_str(), body.size(), false))
     {
       buffer.ToString(result);
     }
@@ -67,4 +67,32 @@
       ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_UnknownResource);
     }
   }
+
+
+  void OrthancPluginConnection::RestApiPut(std::string& result,
+                                           const std::string& uri,
+                                           const std::string& body)
+  {
+    OrthancPlugins::MemoryBuffer buffer(context_);
+
+    if (buffer.RestApiPut(uri, body.c_str(), body.size(), false))
+    {
+      buffer.ToString(result);
+    }
+    else
+    {
+      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_UnknownResource);
+    }
+  }
+
+
+  void OrthancPluginConnection::RestApiDelete(const std::string& uri)
+  {
+    OrthancPlugins::MemoryBuffer buffer(context_);
+
+    if (!::OrthancPlugins::RestApiDelete(context_, uri, false))
+    {
+      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_UnknownResource);
+    }
+  }
 }
--- a/Resources/Orthanc/Plugins/Samples/Common/OrthancPluginConnection.h	Fri Nov 25 21:18:46 2016 +0100
+++ b/Resources/Orthanc/Plugins/Samples/Common/OrthancPluginConnection.h	Fri Nov 25 21:56:07 2016 +0100
@@ -56,5 +56,11 @@
     virtual void RestApiPost(std::string& result,
                              const std::string& uri,
                              const std::string& body);
+
+    virtual void RestApiPut(std::string& result,
+                            const std::string& uri,
+                            const std::string& body);
+
+    virtual void RestApiDelete(const std::string& uri);
   };
 }
--- a/Resources/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Fri Nov 25 21:18:46 2016 +0100
+++ b/Resources/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Fri Nov 25 21:56:07 2016 +0100
@@ -375,10 +375,6 @@
                      const std::string& uri,
                      bool applyPlugins);
 
-  bool RestApiDelete(OrthancPluginContext* context,
-                     const std::string& uri,
-                     bool applyPlugins);
-
   inline void LogError(OrthancPluginContext* context,
                        const std::string& message)
   {
--- a/ViewerPlugin/Plugin.cpp	Fri Nov 25 21:18:46 2016 +0100
+++ b/ViewerPlugin/Plugin.cpp	Fri Nov 25 21:56:07 2016 +0100
@@ -52,7 +52,7 @@
       if (pyramid_.get() == NULL ||
           pyramid_->GetSeriesId() != seriesId)
       {
-        pyramid_.reset(new DicomPyramid(orthanc_, seriesId));
+        pyramid_.reset(new DicomPyramid(orthanc_, seriesId, true /* use metadata cache */));
       }
 
       if (pyramid_.get() == NULL)