extern StaticMutex ValueCacheMutex; LRUCache& TheValueCache(); typedef LRUCache::Maker ValueMaker; Value MakeValueSz(ValueMaker& m, int& sz); Value MakeValue(ValueMaker& m); bool IsValueCacheActive(); void AdjustValueCache(); void ShrinkValueCache(); void SetupValueCache(int maxsize, int maxcount); template int ValueCacheRemove(P what) { Mutex::Lock __(ValueCacheMutex); return TheValueCache().Remove(what); } template int ValueCacheRemoveOne(P what) { Mutex::Lock __(ValueCacheMutex); return TheValueCache().Remove(what); } template void ValueCacheAdjustSize(P getsize) { Mutex::Lock __(ValueCacheMutex); TheValueCache().AdjustSize(getsize); } template Value MakeValue_(const String& key, const M& m, int& sz) { struct Maker : ValueMaker { const String& key; const M& m; String Key() const override { return key; } int Make(Value& object) const override { return m(object); } Maker(const String& key, const M& m) : key(key), m(m) {} }; Maker maker(key, m); return MakeValueSz(maker, sz); } template String MakeKey_(const K& k, const M& m) { StringBuffer key; RawCat(key, StaticTypeNo()); RawCat(key, StaticTypeNo()); key.Cat(k()); return String(key); } template Value MakeValue(const K& k, const M& m) { int sz; return MakeValue_(MakeKey_(k, m), m, sz); } template Value MakeValueTL(const K& k, const M& m) { String key = MakeKey_(k, m); struct Maker : ValueMaker { const String& key; const M& m; String Key() const override { return key; } int Make(Value& object) const override { int sz; object = MakeValue_(key, m, sz); return sz; } Maker(const String& key, const M& m) : key(key), m(m) {} }; Maker maker(key, m); if(IsMainThread()) { static LRUCache cache; // this is basically to avoid problem with leaks detection Value v = cache.Get(maker); cache.Shrink(128 * 1024, 1000); return v; } else { thread_local LRUCache cache; Value v = cache.Get(maker); cache.Shrink(128 * 1024, 1000); return v; } }