27 const auto firstSample = llrint(t0 *
sampleRate);
28 const auto secondSample = llrint(t1 *
sampleRate);
30 return firstSample == secondSample;
35 return std::abs(1.0 / lhs - 1.0 / rhs) *
56template<
typename Container>
58 const Container& container,
double pixelsPerSecond,
double sampleRate)
60 return std::equal_range(
61 container.begin(), container.end(), pixelsPerSecond,
64 if constexpr (std::is_arithmetic_v<std::decay_t<decltype(lhs)>>)
65 return !IsSamePPS(sampleRate, lhs, rhs.Key.PixelsPerSecond) &&
66 lhs < rhs.Key.PixelsPerSecond;
68 return !IsSamePPS(sampleRate, lhs.Key.PixelsPerSecond, rhs) &&
69 lhs.Key.PixelsPerSecond < rhs;
89 mMaxWidth = std::max(mMaxWidth, width);
106 std::numeric_limits<double>::epsilon())
124 const ZoomInfo& zoomInfo,
double t0,
double t1)
129 const double pixelsPerSecond = zoomInfo.
GetZoom();
134 const int64_t width = right - left;
138 const int64_t cacheItemsCount = cacheRight - cacheLeft;
150 const auto ppsMatchRange =
153 for (int64_t itemIndex = 0; itemIndex < cacheItemsCount; ++itemIndex)
157 const int64_t firstSample =
158 static_cast<int64_t
>(column * samplesPerPixel);
160 const auto it = std::find_if(
161 ppsMatchRange.first, ppsMatchRange.second,
162 [firstSample](
auto element)
163 { return element.Key.FirstSample == firstSample; });
165 if (it == ppsMatchRange.second)
185 { return IsKeyLess(sampleRate, lhs.Key, rhs.Key); });
192 pixelsPerSecond, int64_t(cacheLeftColumn * samplesPerPixel)
195 auto it =
FindKey(firstItemKey);
204 for (int64_t itemIndex = 0; itemIndex < cacheItemsCount; ++itemIndex)
206 auto data = it->Data;
209 data->AwaitsEviction =
false;
216 needsSmoothing =
true;
220 data->Smooth(prevItem);
232 std::advance(last, cacheItemsCount);
235 static_cast<size_t>(std::max(int64_t(0), left - cacheLeftColumn)),
237 std::max(int64_t(0), cacheRightColumn - right)) };
257 data->
Smooth(it ==
mLookup.begin() ?
nullptr : (it - 1)->Data);
269 if (newElement.Data ==
nullptr)
274 newElement.Data->AwaitsEviction =
false;
276 auto insertedPosition =
mLookup.insert(
281 if constexpr (std::is_same_v<
282 std::decay_t<decltype(lhs)>, GraphicsDataCacheKey>)
283 return IsKeyLess(sampleRate, lhs, rhs.Key);
285 return IsKeyLess(sampleRate, lhs.Key, rhs);
289 newElement.Data->Smooth(
290 insertedPosition ==
mLookup.begin() ?
nullptr :
291 (insertedPosition - 1)->Data);
295 return newElement.Data;
304 if (item.Data ==
nullptr)
319 if (elem.Data != nullptr)
320 elem.Data->Dispose();
324GraphicsDataCacheBase::Lookup::iterator
330 { return IsSameKey(sampleRate, lhs.Key, key); });
335 const int64_t lookupSize =
static_cast<int64_t
>(
mLookup.size());
337 const auto allowedItems =
340 const int64_t itemsToEvict = lookupSize - allowedItems;
342 if (itemsToEvict <= 0)
345 if (itemsToEvict == 1)
347 auto it = std::min_element(
349 [](
auto lhs,
auto rhs)
350 { return lhs.Data->LastCacheAccess < rhs.Data->LastCacheAccess; });
365 int64_t currentSize, int64_t itemsToEvict)
369 for (
size_t i = 0; i < currentSize; ++i)
374 [
this](
size_t lhs,
size_t rhs)
376 return mLookup[lhs].Data->LastCacheAccess >
377 mLookup[rhs].Data->LastCacheAccess;
380 for (int64_t itemIndex = 0; itemIndex < itemsToEvict; ++itemIndex)
387 auto data =
mLookup[index].Data;
393 data->AwaitsEviction =
true;
399 [](
auto item) { return item.Data->AwaitsEviction; }),
auto RoundUpUnsafe(LType numerator, RType denominator) noexcept
Returns a rounded up integer result for numerator / denominator.
GraphicsDataCacheBase(double scaledSampleRate)
std::vector< size_t > mLRUHelper
int32_t mCacheSizeMultiplier
virtual void DisposeElement(GraphicsDataCacheElementBase *element)=0
This method is called, when the cache element should be evicted. Implementation may not deallocate th...
virtual bool UpdateElement(const GraphicsDataCacheKey &key, GraphicsDataCacheElementBase &element)=0
This method is called on all elements matching the request that are not complete (i....
uint64_t mCacheAccessIndex
BaseLookupResult PerformBaseLookup(const ZoomInfo &zoomInfo, double t0, double t1)
Perform a lookup inside the cache. This method modifies mLookup and invalidates any previous result.
int64_t GetMaxViewportWidth() const noexcept
void Invalidate()
Invalidate the cache content.
virtual GraphicsDataCacheElementBase * CreateElement(const GraphicsDataCacheKey &key)=0
Create a new Cache element. Implementation is responsible of the lifetime control.
void UpdateViewportWidth(int64_t width) noexcept
void PerformFullCleanup(int64_t currentSize, int64_t itemsToEvict)
static constexpr uint32_t CacheElementWidth
Lookup::iterator FindKey(GraphicsDataCacheKey key)
double GetScaledSampleRate() const noexcept
Returns the sample rate associated with cache.
void SetScaledSampleRate(double scaledSampleRate)
int64 TimeToPosition(double time, int64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
constexpr auto sampleRate
auto GetPPSMatchRange(const Container &container, double pixelsPerSecond, double sampleRate)
bool IsSameKey(double sampleRate, GraphicsDataCacheKey lhs, GraphicsDataCacheKey rhs)
bool IsSameSample(double sampleRate, double t0, double t1) noexcept
bool IsKeyLess(double sampleRate, GraphicsDataCacheKey lhs, GraphicsDataCacheKey rhs)
bool IsSamePPS(double sampleRate, double lhs, double rhs)
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
A result of the cache lookup.
Element of the cache lookup.
A base class for the for cache elements.
virtual void Dispose()
This method is called when the item is evicted from the cache. Default implementation is empty.
uint64_t LastUpdate
The last time the item was updated. If (!IsComplete && LastUpdate < LastCacheAccess) the item will be...
uint64_t LastCacheAccess
Index filled by GraphicsDataCacheBase to implement LRU eviction policy.
bool IsComplete
Cache implementation is responsible to set this flag when all the data of the item is filled.
virtual void Smooth(GraphicsDataCacheElementBase *prevElement)
This method is called during the lookup when new items are inserted. prevElement can be nullptr....
A key into the graphics data cache.
int64_t FirstSample
Level 2 key: first cached sample in the "global" scale.
double PixelsPerSecond
Level 1 key: zoom level.