Core: ValueCache full reentrancy

This commit is contained in:
Mirek Fidler 2023-01-28 13:00:54 +01:00
parent 852c1f1899
commit 87034d3fe0
5 changed files with 24 additions and 6 deletions

View file

@ -258,7 +258,9 @@ public:
template <class P> int Remove(P predicate);
template <class P> bool RemoveOne(P predicate);
T& Get(const Maker& m);
template <class B, class A>
T& Get(const Maker& m, B before_make, A after_make);
T& Get(const Maker& m) { return Get(m, []{}, []{}); }
void Clear();

View file

@ -177,7 +177,8 @@ void LRUCache<T, K>::ClearCounters()
}
template <class T, class K>
T& LRUCache<T, K>::Get(const Maker& m)
template <class B, class A>
T& LRUCache<T, K>::Get(const Maker& m, B before_make, A after_make)
{
Key k;
k.key = m.Key();
@ -185,7 +186,9 @@ T& LRUCache<T, K>::Get(const Maker& m)
int q = key.Find(k);
if(q < 0) {
One<T> val;
before_make();
int sz = m.Make(val.Create());
after_make();
q = key.Put(k);
Item& t = data.At(q);
t.data = pick(val);

View file

@ -64,7 +64,7 @@ Value MakeValue(ValueMaker& m)
{
Mutex::Lock __(ValueCacheMutex);
LLOG("MakeValue cache size before make: " << TheValueCache().GetSize());
Value v = TheValueCache().Get(m);
Value v = TheValueCache().Get(m, [] { ValueCacheMutex.Leave(); }, [] { ValueCacheMutex.Enter(); });
LLOG("MakeValue cache size after make: " << TheValueCache().GetSize());
ShrinkValueCache();
LLOG("-------------");

View file

@ -117,9 +117,19 @@ items to least recently used. Returns true if item was found
and removed.&]
[s3;%% &]
[s4; &]
[s5;:Upp`:`:LRUCache`:`:Get`(const Upp`:`:LRUCache`:`:Maker`&`,B`,A`): [@(0.0.255) temp
late] <B, A> T[@(0.0.255) `&] [* Get]([@(0.0.255) const] Maker[@(0.0.255) `&]
[*@3 m], B [*@3 before`_make], A [*@3 after`_make])&]
[s2;%% Retrieves data from the cache or creates them if needed. Required
data and method to create them is provided by [%-*@3 m]. If data
needs to be created, [%-*@3 before`_make] is called before call
to Maker`::Make and [%-*@3 after`_make] when it is finished.&]
[s3; &]
[s4; &]
[s5;:LRUCache`:`:Get`(const LRUCache`:`:Maker`&`): [*@4 T][@(0.0.255) `&]_[* Get]([@(0.0.255) c
onst]_[_^LRUCache`:`:Maker^ Maker][@(0.0.255) `&]_[*@3 m])&]
[s2;%% Retrieves data from the cache or creates them if needed [%-*@3 m].&]
[s2;%% Retrieves data from the cache or creates them if needed. Required
data and method to create them is provided by [%-*@3 m].&]
[s3;%% &]
[s4; &]
[s5;:LRUCache`:`:Clear`(`): [@(0.0.255) void]_[* Clear]()&]

View file

@ -24,7 +24,7 @@ alueMaker][@(0.0.255) `&]_[*@3 m])&]
derived from ValueMaker, which is class with two virtual methods:&]
[s2; &]
[s2; virtual String [* Key]() const;&]
[s2; virtual int [* Make](T`& object) const;&]
[s2; virtual int [* Make](Value`& object) const;&]
[s2; &]
[s2; [* Key] should return unique identifier for Value requested with
ValueMaker derived class. Note that the type of ValueMaker derived
@ -34,7 +34,10 @@ the corresponding Value and returns the approximate memory consumption
needed to store that Value. [* MakeValue] first checks whether
Value corresponding to given ValueMaker and Key are in the cache,
if yes then it returns Value from the cache, otherwise calls
ValueMaker`::Make to obtain the Value and stores it to the cache.&]
ValueMaker`::Make to obtain the Value and stores it to the cache.
Note that this function allows full reentrancy (from various
threads as well as recursive calls (through Make method) in single
thread&]
[s3; &]
[s4;%- &]
[s5;:Upp`:`:IsValueCacheActive`(`):%- [@(0.0.255) bool]_[* IsValueCacheActive]()&]