diff UnitTests/MemoryCache.cpp @ 509:e7841864c97c

StableResourcesMonitor
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 16 Aug 2013 14:23:54 +0200
parents c4122c3a47c1
children 3b735fdf320b
line wrap: on
line diff
--- a/UnitTests/MemoryCache.cpp	Fri Aug 16 10:24:49 2013 +0200
+++ b/UnitTests/MemoryCache.cpp	Fri Aug 16 14:23:54 2013 +0200
@@ -17,12 +17,12 @@
   r.Add("c");
   r.Add("b");
 
-  r.TagAsMostRecent("a");
-  r.TagAsMostRecent("d");
-  r.TagAsMostRecent("b");
-  r.TagAsMostRecent("c");
-  r.TagAsMostRecent("d");
-  r.TagAsMostRecent("c");
+  r.MakeMostRecent("a");
+  r.MakeMostRecent("d");
+  r.MakeMostRecent("b");
+  r.MakeMostRecent("c");
+  r.MakeMostRecent("d");
+  r.MakeMostRecent("c");
 
   ASSERT_EQ("a", r.GetOldest());
   ASSERT_EQ("a", r.RemoveOldest());
@@ -49,12 +49,12 @@
   r.Add("c", 422);
   r.Add("d", 423);
 
-  r.TagAsMostRecent("a");
-  r.TagAsMostRecent("d");
-  r.TagAsMostRecent("b");
-  r.TagAsMostRecent("c");
-  r.TagAsMostRecent("d");
-  r.TagAsMostRecent("c");
+  r.MakeMostRecent("a");
+  r.MakeMostRecent("d");
+  r.MakeMostRecent("b");
+  r.MakeMostRecent("c");
+  r.MakeMostRecent("d");
+  r.MakeMostRecent("c");
 
   ASSERT_TRUE(r.Contains("b"));
   ASSERT_EQ(421, r.Invalidate("b"));
@@ -81,6 +81,60 @@
 }
 
 
+TEST(LRU, PayloadUpdate)
+{
+  Orthanc::LeastRecentlyUsedIndex<std::string, int> r;
+  
+  r.Add("a", 420);
+  r.Add("b", 421);
+  r.Add("d", 423);
+
+  r.MakeMostRecent("a", 424);
+  r.MakeMostRecent("d", 421);
+
+  ASSERT_EQ("b", r.GetOldest());
+  ASSERT_EQ(421, r.GetOldestPayload());
+  r.RemoveOldest();
+
+  ASSERT_EQ("a", r.GetOldest());
+  ASSERT_EQ(424, r.GetOldestPayload());
+  r.RemoveOldest();
+
+  ASSERT_EQ("d", r.GetOldest());
+  ASSERT_EQ(421, r.GetOldestPayload());
+  r.RemoveOldest();
+
+  ASSERT_TRUE(r.IsEmpty());
+}
+
+
+
+TEST(LRU, PayloadUpdateBis)
+{
+  Orthanc::LeastRecentlyUsedIndex<std::string, int> r;
+  
+  r.AddOrMakeMostRecent("a", 420);
+  r.AddOrMakeMostRecent("b", 421);
+  r.AddOrMakeMostRecent("d", 423);
+  r.AddOrMakeMostRecent("a", 424);
+  r.AddOrMakeMostRecent("d", 421);
+
+  ASSERT_EQ("b", r.GetOldest());
+  ASSERT_EQ(421, r.GetOldestPayload());
+  r.RemoveOldest();
+
+  ASSERT_EQ("a", r.GetOldest());
+  ASSERT_EQ(424, r.GetOldestPayload());
+  r.RemoveOldest();
+
+  ASSERT_EQ("d", r.GetOldest());
+  ASSERT_EQ(421, r.GetOldestPayload());
+  r.RemoveOldest();
+
+  ASSERT_TRUE(r.IsEmpty());
+}
+
+
 
 
 namespace
@@ -141,3 +195,105 @@
 
   ASSERT_EQ("45 42 43 47 44 42 ", provider.log_);
 }
+
+
+#include "../OrthancServer/ServerEnumerations.h"
+
+namespace
+{
+  struct Payload
+  {
+    Orthanc::ResourceType type_;
+    boost::posix_time::ptime time_;
+
+    Payload() : type_(Orthanc::ResourceType_Instance)
+    {
+    }
+
+    Payload(Orthanc::ResourceType type) : type_(type)
+    {
+      time_ = boost::posix_time::second_clock::local_time();
+    }
+
+    unsigned int GetAge() const
+    {
+      return (boost::posix_time::second_clock::local_time() - time_).total_seconds();
+    }
+  };
+
+
+  class StableResourcesMonitor
+  {
+  private:
+    bool done_;
+    boost::mutex mutex_;
+    unsigned int stableTimeout_;
+    Orthanc::LeastRecentlyUsedIndex<std::string, Payload>  unstableResources_;
+    boost::thread thread_;
+
+    static void Thread(StableResourcesMonitor* that)
+    {
+      static const unsigned int SLEEP = 1;  // Check for stable resources each second
+
+      while (!that->done_)
+      {
+        boost::this_thread::sleep(boost::posix_time::seconds(SLEEP));
+
+        boost::mutex::scoped_lock lock(that->mutex_);
+        while (!that->unstableResources_.IsEmpty() &&
+               that->unstableResources_.GetOldestPayload().GetAge() > that->stableTimeout_)
+        {
+          // This DICOM resource has not received any new instance for
+          // some time. It can be considered as stable.
+          
+          Payload payload;
+          std::string id = that->unstableResources_.RemoveOldest(payload);
+
+          LOG(INFO) << "Stable resource: " << id << " (type " << payload.type_ << ")";
+        }
+      }
+
+      LOG(INFO) << "Closing the monitor for stable resources";
+    }
+
+  public:
+    StableResourcesMonitor(unsigned int stableTimeout)
+    {
+      done_ = false;
+      stableTimeout_ = stableTimeout;
+      thread_ = boost::thread(Thread, this);
+    }
+
+    ~StableResourcesMonitor()
+    {
+      done_ = true;
+
+      if (thread_.joinable())
+      {
+        thread_.join();
+      }
+    }
+
+    void ResourceUpdated(const std::string& id,
+                         Orthanc::ResourceType type)
+    {
+      assert(type == Orthanc::ResourceType_Patient ||
+             type == Orthanc::ResourceType_Study ||
+             type == Orthanc::ResourceType_Series);
+
+      boost::mutex::scoped_lock lock(mutex_);
+      unstableResources_.AddOrMakeMostRecent(id, type);
+    }
+  };
+}
+
+TEST(LRU, Hello)
+{
+  StableResourcesMonitor m(5);
+  boost::this_thread::sleep(boost::posix_time::seconds(1));
+  m.ResourceUpdated("Hello", Orthanc::ResourceType_Study);
+  m.ResourceUpdated("World", Orthanc::ResourceType_Series);
+  boost::this_thread::sleep(boost::posix_time::seconds(2));
+  m.ResourceUpdated("Hello", Orthanc::ResourceType_Study);
+  boost::this_thread::sleep(boost::posix_time::seconds(10));
+}