comparison OrthancFramework/Sources/Cache/MemoryStringCache.h @ 5420:d37dff2c0028 am-new-cache

Optimized the MemoryStringCache to prevent loading the same file multiple times if multiple users request the same file at the same time
author Alain Mazy <am@osimis.io>
date Mon, 13 Nov 2023 17:01:59 +0100
parents 0ea402b4d901
children c65e036d649b
comparison
equal deleted inserted replaced
5419:ac4e9fb87615 5420:d37dff2c0028
21 **/ 21 **/
22 22
23 23
24 #pragma once 24 #pragma once
25 25
26 #include "MemoryObjectCache.h" 26 #include "../OrthancFramework.h"
27 #include "ICacheable.h"
28 #include "LeastRecentlyUsedIndex.h"
29
30 #include <boost/thread/condition_variable.hpp>
31 #include <boost/thread/mutex.hpp>
32
27 33
28 namespace Orthanc 34 namespace Orthanc
29 { 35 {
30 /** 36 /**
31 * Facade object around "MemoryObjectCache" that caches a dictionary 37 * Class that caches a dictionary
32 * of strings, using the "fetch/add" paradigm of memcached. 38 * of strings, using the "fetch/add" paradigm of memcached.
39 *
40 * Starting from 1.12.2, if multiple clients are trying to access
41 * an inexistent item at the same time, only one of them will load it
42 * and the others will wait until the first one has loaded the data.
43 *
44 * The MemoryStringCache is only accessible through an Accessor.
33 * 45 *
34 * Note: this class is thread safe 46 * Note: this class is thread safe
35 **/ 47 **/
36 class ORTHANC_PUBLIC MemoryStringCache : public boost::noncopyable 48 class ORTHANC_PUBLIC MemoryStringCache : public boost::noncopyable
37 { 49 {
50 public:
51 class Accessor : public boost::noncopyable
52 {
53 MemoryStringCache& cache_;
54 bool shouldAdd_; // when this accessor is the one who should load and add the data
55 std::string keyToAdd_;
56 public:
57 Accessor(MemoryStringCache& cache);
58 ~Accessor();
59
60 bool Fetch(std::string& value, const std::string& key);
61 void Add(const std::string& key, const std::string& value);
62 void Add(const std::string& key,const char* buffer, size_t size);
63 };
64
38 private: 65 private:
39 class StringValue; 66 class StringValue;
40 67
41 MemoryObjectCache cache_; 68 boost::mutex cacheMutex_; // note: we can not use recursive_mutex with condition_variable
69 boost::condition_variable cacheCond_;
70 std::set<std::string> itemsBeingLoaded_;
71
72 size_t currentSize_;
73 size_t maxSize_;
74 LeastRecentlyUsedIndex<std::string, StringValue*> content_;
75
76 void Recycle(size_t targetSize);
42 77
43 public: 78 public:
79 MemoryStringCache();
80
81 ~MemoryStringCache();
82
44 size_t GetMaximumSize(); 83 size_t GetMaximumSize();
45 84
46 void SetMaximumSize(size_t size); 85 void SetMaximumSize(size_t size);
47 86
87 void Invalidate(const std::string& key);
88
89
90 private:
48 void Add(const std::string& key, 91 void Add(const std::string& key,
49 const std::string& value); 92 const std::string& value);
50 93
51 void Add(const std::string& key, 94 void Add(const std::string& key,
52 const void* buffer, 95 const void* buffer,
53 size_t size); 96 size_t size);
54 97
55 void Invalidate(const std::string& key);
56
57 bool Fetch(std::string& value, 98 bool Fetch(std::string& value,
58 const std::string& key); 99 const std::string& key);
100
101 void RemoveFromItemsBeingLoaded(const std::string& key);
102 void RemoveFromItemsBeingLoadedInternal(const std::string& key);
103
104 void AddToItemsBeingLoadedInternal(const std::string& key);
59 }; 105 };
60 } 106 }