changeset 2309:4d24c9a525b4 refactoring

using the new cache in WebAssemblyOracle
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 29 Sep 2026 12:05:04 +0200
parents e499cac2a048
children 25906f58b4cd
files Applications/Samples/Sdl/SingleFrameViewer/SdlSimpleViewer.cpp Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp OrthancStone/Sources/Platforms/WebAssembly/WebAssemblyLoadersContext.h OrthancStone/Sources/Platforms/WebAssembly/WebAssemblyOracle.cpp OrthancStone/Sources/Platforms/WebAssembly/WebAssemblyOracle.h OrthancStone/Sources/StoneApplication.cpp OrthancStone/Sources/Toolbox/ParsedDicomCache.h
diffstat 7 files changed, 40 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/Samples/Sdl/SingleFrameViewer/SdlSimpleViewer.cpp	Tue Sep 29 11:20:29 2026 +0200
+++ b/Applications/Samples/Sdl/SingleFrameViewer/SdlSimpleViewer.cpp	Tue Sep 29 12:05:04 2026 +0200
@@ -222,6 +222,7 @@
 
       OrthancStone::StoneApplication::Configuration configuration;
       configuration.SetRemoteOrthancParameters(orthancWebService);
+      configuration.SetDicomCacheSize(128 * 1024 * 1024);  // TODO Refactoring - Remove this
       configuration.SetRootDirectory("/tmp");  // TODO Refactoring - Remove this
 
       OrthancStone::StoneApplication::Initialize(configuration);
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp	Tue Sep 29 11:20:29 2026 +0200
+++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp	Tue Sep 29 12:05:04 2026 +0200
@@ -3156,8 +3156,8 @@
        * cache of the oracle, bypass the loading of the "rendered" and
        * use the cached DICOM file.
        **/
-      std::unique_ptr<OrthancStone::WebAssemblyOracle::CachedInstanceAccessor> accessor(
-        context_.AccessCachedInstance(instance.GetSopInstanceUid()));
+      std::unique_ptr<OrthancStone::New::ParsedDicomCache::Accessor> accessor(
+        context_.GetCachedDicomInstance(instance.GetSopInstanceUid()));
 
       if (accessor.get() != NULL &&
           accessor->IsValid())
@@ -3167,15 +3167,15 @@
           std::unique_ptr<Orthanc::ImageAccessor> frame;
           if (OrthancStone::IsStructuredReport(instance.GetSopClassUid()))
           {
-            OrthancStone::DicomStructuredReport report(const_cast<Orthanc::ParsedDicomFile&>(accessor->GetDicom()));
+            OrthancStone::DicomStructuredReport report(*accessor->GetDicom());
             frame.reset(report.Render(font_, GetHighlightedColorInternal(), GetAnnotationsColorInternal()));
           }
           else
           {
-            frame.reset(accessor->GetDicom().DecodeFrame(frameNumber));
+            frame.reset(accessor->GetDicom()->DecodeFrame(frameNumber));
           }
 
-          SetFullDicomFrame::Apply(*this, accessor->GetDicom(), frame.release(), instance.GetSopInstanceUid(), frameNumber);
+          SetFullDicomFrame::Apply(*this, *accessor->GetDicom(), frame.release(), instance.GetSopInstanceUid(), frameNumber);
           return;  // Success
         }
         catch (Orthanc::OrthancException&)
@@ -5000,6 +5000,18 @@
         command->SetUri("/system/");
         oracle.Submit(environment, toto_, command.release());
       }
+
+      for (unsigned int i = 0; i < 10; i++)
+      {
+        // hand.dcm
+        const std::string& study = "1.2.276.0.7230010.3.1.2.296485376.1.1656336504.287249";
+        const std::string& series = "1.2.276.0.7230010.3.1.3.296485376.1.1656336504.287250";
+        const std::string& sop = "1.2.276.0.7230010.3.1.4.296485376.1.1656336504.287251";
+        oracle.Submit(environment, toto_, OrthancStone::ParseDicomFromWadoCommand::Create(
+                        source_, study, series, sop, false /* no transcoding */,
+                        Orthanc::DicomTransferSyntax_LittleEndianExplicit /* dummy value */,
+                        new Orthanc::IDynamicObject));
+      }
     }
   }
 
--- a/OrthancStone/Sources/Platforms/WebAssembly/WebAssemblyLoadersContext.h	Tue Sep 29 11:20:29 2026 +0200
+++ b/OrthancStone/Sources/Platforms/WebAssembly/WebAssemblyLoadersContext.h	Tue Sep 29 12:05:04 2026 +0200
@@ -46,9 +46,9 @@
                               unsigned int maxStandardPriority,
                               unsigned int maxLowPriority);
 
-    WebAssemblyOracle::CachedInstanceAccessor* AccessCachedInstance(const std::string& sopInstanceUid)
+    New::ParsedDicomCache::Accessor* GetCachedDicomInstance(const std::string& sopInstanceUid)
     {
-      return new WebAssemblyOracle::CachedInstanceAccessor(oracle_, sopInstanceUid);
+      return oracle_.GetCachedDicomInstance(sopInstanceUid);
     }
 
     virtual ILock* Lock() ORTHANC_OVERRIDE;
--- a/OrthancStone/Sources/Platforms/WebAssembly/WebAssemblyOracle.cpp	Tue Sep 29 11:20:29 2026 +0200
+++ b/OrthancStone/Sources/Platforms/WebAssembly/WebAssemblyOracle.cpp	Tue Sep 29 12:05:04 2026 +0200
@@ -40,11 +40,6 @@
 #include <emscripten/fetch.h>
 
 
-#if ORTHANC_ENABLE_DCMTK == 1
-static unsigned int BUCKET_SOP = 1;
-#endif
-
-
 namespace OrthancStone
 {
   static void TimeoutCallback(void *userData)
@@ -505,16 +500,13 @@
       boost::shared_ptr<Orthanc::ParsedDicomFile> dicom
         (ParseDicomSuccessMessage::ParseWadoAnswer(fileSize, answer, headers));
 
-      callback.NotifySuccess(new ParseDicomSuccessMessage(c, c.GetSource(), dicom, fileSize, true));
-
-#if 0
-      // TODO Refactoring - Reactivate the cache!!!
       if (dicomCache_.get())
       {
         // Store it into the cache for future use
-        dicomCache_->Acquire(BUCKET_SOP, c.GetSopInstanceUid(), dicom.release(), fileSize, true);
+        dicomCache_->Store(c.GetSopInstanceUid(), dicom, static_cast<size_t>(fileSize), true);
       }
-#endif
+
+      callback.NotifySuccess(new ParseDicomSuccessMessage(c, c.GetSource(), dicom, fileSize, true));
 
 #else
       throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
@@ -652,23 +644,20 @@
 
     const ParseDicomFromWadoCommand& command = dynamic_cast<const ParseDicomFromWadoCommand&>(protection->GetCommand());
 
-#if 0
-      // TODO Refactoring - Reactivate the cache!!!
 #if ORTHANC_ENABLE_DCMTK == 1
     if (dicomCache_.get())
     {
-      ParsedDicomCache::Reader reader(*dicomCache_, BUCKET_SOP, command.GetSopInstanceUid());
-      if (reader.IsValid() &&
-          reader.HasPixelData())
+      New::ParsedDicomCache::Accessor accessor(*dicomCache_, command.GetSopInstanceUid());
+      if (accessor.IsValid() &&
+          accessor.HasPixelData())
       {
         // Reuse the DICOM file from the cache
-        protection->NotifySuccess(new ParseDicomSuccessMessage(command, command.GetSource(), reader.GetDicom(),
-                                                               reader.GetFileSize(), reader.HasPixelData()));
+        protection->NotifySuccess(new ParseDicomSuccessMessage(command, command.GetSource(), accessor.GetDicom(),
+                                                               accessor.GetFileSize(), accessor.HasPixelData()));
         return;
       }
     }
 #endif
-#endif
 
     switch (command.GetRestCommand().GetType())
     {
@@ -799,7 +788,7 @@
     {
       LOG(INFO) << "The DICOM cache size is set to "
                 << (static_cast<float>(configuration.GetDicomCacheSize()) / static_cast<float>(1024 * 1024)) << " MB";
-      dicomCache_.reset(new ParsedDicomCache(configuration.GetDicomCacheSize()));
+      dicomCache_.reset(new New::ParsedDicomCache(configuration.GetDicomCacheSize()));
     }
 #else
     LOG(INFO) << "DCMTK support is disabled, the DICOM cache is disabled";
@@ -815,73 +804,15 @@
   }
 
 
-  WebAssemblyOracle::CachedInstanceAccessor::CachedInstanceAccessor(WebAssemblyOracle& oracle,
-                                                                    const std::string& sopInstanceUid)
-  {
-#if ORTHANC_ENABLE_DCMTK == 1
-    if (oracle.dicomCache_.get() != NULL)
-    {
-      reader_.reset(new ParsedDicomCache::Reader(*oracle.dicomCache_, BUCKET_SOP, sopInstanceUid));
-    }
-#endif
-  }
-
-
-  bool WebAssemblyOracle::CachedInstanceAccessor::IsValid() const
+  New::ParsedDicomCache::Accessor* WebAssemblyOracle::GetCachedDicomInstance(const std::string& sopInstanceUid)
   {
-#if ORTHANC_ENABLE_DCMTK == 1
-    return (reader_.get() != NULL &&
-            reader_->IsValid());
-#else
-    return false;
-#endif
-  }
-
-
-#if ORTHANC_ENABLE_DCMTK == 1
-  const Orthanc::ParsedDicomFile& WebAssemblyOracle::CachedInstanceAccessor::GetDicom() const
-  {
-    if (IsValid())
+    if (dicomCache_)
     {
-      assert(reader_.get() != NULL);
-      return reader_->GetDicom();
+      return new New::ParsedDicomCache::Accessor(*dicomCache_, sopInstanceUid);
     }
     else
     {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-  }
-#endif
-
-
-  size_t WebAssemblyOracle::CachedInstanceAccessor::GetFileSize() const
-  {
-#if ORTHANC_ENABLE_DCMTK == 1
-    if (IsValid())
-    {
-      assert(reader_.get() != NULL);
-      return reader_->GetFileSize();
-    }
-    else
-#endif
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-  }
-
-
-  bool WebAssemblyOracle::CachedInstanceAccessor::HasPixelData() const
-  {
-#if ORTHANC_ENABLE_DCMTK == 1
-    if (IsValid())
-    {
-      assert(reader_.get() != NULL);
-      return reader_->HasPixelData();
-    }
-    else
-#endif
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
+      return new New::ParsedDicomCache::Accessor;
     }
   }
 }
--- a/OrthancStone/Sources/Platforms/WebAssembly/WebAssemblyOracle.h	Tue Sep 29 11:20:29 2026 +0200
+++ b/OrthancStone/Sources/Platforms/WebAssembly/WebAssemblyOracle.h	Tue Sep 29 12:05:04 2026 +0200
@@ -76,7 +76,7 @@
     StoneApplication::Configuration  configuration_;
 
 #if ORTHANC_ENABLE_DCMTK == 1
-    std::unique_ptr<ParsedDicomCache>  dicomCache_;
+    std::unique_ptr<New::ParsedDicomCache>  dicomCache_;
 #endif
 
     void ProcessFetchResult(IOracleCallback& callback,
@@ -92,26 +92,6 @@
                         const boost::shared_ptr<IOracleClient>& client,
                         IOracleCommand* command /* takes ownership */) ORTHANC_OVERRIDE;
 
-    class CachedInstanceAccessor : public boost::noncopyable
-    {
-    private:
-#if ORTHANC_ENABLE_DCMTK == 1
-      std::unique_ptr<ParsedDicomCache::Reader>  reader_;
-#endif
-
-    public:
-      CachedInstanceAccessor(WebAssemblyOracle& oracle,
-                             const std::string& sopInstanceUid);
-
-      bool IsValid() const;
-
-#if ORTHANC_ENABLE_DCMTK == 1
-      const Orthanc::ParsedDicomFile& GetDicom() const;
-#endif
-
-      size_t GetFileSize() const;
-
-      bool HasPixelData() const;
-    };    
+    New::ParsedDicomCache::Accessor*  GetCachedDicomInstance(const std::string& sopInstanceUid);
   };
 }
--- a/OrthancStone/Sources/StoneApplication.cpp	Tue Sep 29 11:20:29 2026 +0200
+++ b/OrthancStone/Sources/StoneApplication.cpp	Tue Sep 29 12:05:04 2026 +0200
@@ -45,7 +45,7 @@
     rootDirectory_("."),
     oracleThreadsCount_(4),
     workersTimeResolution_(50),  // By default, time resolution of 50ms
-    dicomCacheSize_(128 * 1024 * 1024)  // By default, use a cache of 128MB
+    dicomCacheSize_(0)  // By default, the cache is disabled
   {
   }
 
--- a/OrthancStone/Sources/Toolbox/ParsedDicomCache.h	Tue Sep 29 11:20:29 2026 +0200
+++ b/OrthancStone/Sources/Toolbox/ParsedDicomCache.h	Tue Sep 29 12:05:04 2026 +0200
@@ -150,6 +150,10 @@
         const Item& GetItem() const;
 
       public:
+        Accessor()  // This flavor can be used if the cache is disabled
+        {
+        }
+
         Accessor(ParsedDicomCache& cache,
                  const std::string& key);