#include "Core.h" #define LLOG(x) // LOG(x) namespace Upp { StaticMutex ValueCacheMutex; std::atomic sValueCacheFinished; struct ValueMakeCacheClass : LRUCache { ~ValueMakeCacheClass() { sValueCacheFinished = true; } }; LRUCache& TheValueCache() { static ValueMakeCacheClass m; return m; } bool IsValueCacheActive() { return !sValueCacheFinished; } bool ValueCacheFixed = false; int ValueCacheMaxSize = 0; int ValueCacheMaxCount = 20000; void AdjustValueCache() { Mutex::Lock __(ValueCacheMutex); if(ValueCacheFixed) return; uint64 total, available; GetSystemMemoryStatus(total, available); ValueCacheMaxSize = int(available >> 10); if(!ValueCacheMaxSize && available) { ValueCacheMaxSize = 128*1024*1024; } ValueCacheMaxCount = max(ValueCacheMaxSize / 200, 20000); LLOG("New MakeValue max size " << ValueCacheMaxSize << " count " << ValueCacheMaxCount); ShrinkValueCache(); } void ShrinkValueCache() { Mutex::Lock __(ValueCacheMutex); if(!ValueCacheMaxSize) AdjustValueCache(); LLOG("MakeValue cache size before shrink: " << TheValueCache().GetSize()); TheValueCache().Shrink(ValueCacheMaxSize, ValueCacheMaxCount); LLOG("MakeValue cache size after shrink: " << TheValueCache().GetSize()); } void SetupValueCache(int maxsize, int maxcount) { Mutex::Lock __(ValueCacheMutex); if(maxsize <= 0) { ValueCacheFixed = false; AdjustValueCache(); } else { ValueCacheMaxSize = maxsize; ValueCacheMaxCount = maxcount; ValueCacheFixed = true; } } Value MakeValueSz(ValueMaker& m, int& sz) { Mutex::Lock __(ValueCacheMutex); LLOG("MakeValue cache size before make: " << TheValueCache().GetSize()); Value v = TheValueCache().Get(m, [] { ValueCacheMutex.Leave(); }, [] { ValueCacheMutex.Enter(); }, sz); LLOG("MakeValue cache size after make: " << TheValueCache().GetSize()); ShrinkValueCache(); LLOG("-------------"); return v; } Value MakeValue(ValueMaker& m) { int sz; return MakeValueSz(m, sz); } };