Audacity 3.2.0
Classes | Public Member Functions | Static Public Attributes | Protected Types | Protected Member Functions | Private Member Functions | Private Attributes | Friends | List of all members
GraphicsDataCacheBase Class Referenceabstract

A base class for the GraphicsDataCache. Implements LRU policy. More...

#include <GraphicsDataCache.h>

Inheritance diagram for GraphicsDataCacheBase:
[legend]
Collaboration diagram for GraphicsDataCacheBase:
[legend]

Classes

struct  BaseLookupResult
 A result of the cache lookup. More...
 
struct  LookupElement
 Element of the cache lookup. More...
 

Public Member Functions

virtual ~GraphicsDataCacheBase ()=default
 
void Invalidate ()
 Invalidate the cache content. More...
 
double GetScaledSampleRate () const noexcept
 Returns the sample rate associated with cache. More...
 
void UpdateViewportWidth (int64_t width) noexcept
 
int64_t GetMaxViewportWidth () const noexcept
 

Static Public Attributes

static constexpr uint32_t CacheElementWidth = 256
 

Protected Types

using Lookup = std::vector< LookupElement >
 Cache lookup is a vector, with items sorted using Key. More...
 

Protected Member Functions

 GraphicsDataCacheBase (double scaledSampleRate)
 
void SetScaledSampleRate (double scaledSampleRate)
 
virtual GraphicsDataCacheElementBaseCreateElement (const GraphicsDataCacheKey &key)=0
 Create a new Cache element. Implementation is responsible of the lifetime control. More...
 
virtual void DisposeElement (GraphicsDataCacheElementBase *element)=0
 This method is called, when the cache element should be evicted. Implementation may not deallocate the object. More...
 
virtual bool UpdateElement (const GraphicsDataCacheKey &key, GraphicsDataCacheElementBase &element)=0
 This method is called on all elements matching the request that are not complete (i. e. IsComplete if false). More...
 
BaseLookupResult PerformBaseLookup (const ZoomInfo &zoomInfo, double t0, double t1)
 Perform a lookup inside the cache. This method modifies mLookup and invalidates any previous result. More...
 
const GraphicsDataCacheElementBasePerformBaseLookup (GraphicsDataCacheKey key)
 Perform a lookup for the given key. This method modifies mLookup and invalidates any previous result. More...
 

Private Member Functions

bool CreateNewItems ()
 
void DisposeNewItems ()
 
Lookup::iterator FindKey (GraphicsDataCacheKey key)
 
void PerformCleanup ()
 
void PerformFullCleanup (int64_t currentSize, int64_t itemsToEvict)
 

Private Attributes

Lookup mLookup
 
Lookup mLookupHelper
 
Lookup mNewLookupItems
 
std::vector< size_t > mLRUHelper
 
double mScaledSampleRate {}
 
int64_t mMaxWidth { 1600 }
 
uint64_t mCacheAccessIndex {}
 
int32_t mCacheSizeMultiplier { 4 }
 

Friends

template<typename CacheElementType >
class GraphicsDataCacheIterator
 

Detailed Description

A base class for the GraphicsDataCache. Implements LRU policy.

Definition at line 54 of file GraphicsDataCache.h.

Member Typedef Documentation

◆ Lookup

using GraphicsDataCacheBase::Lookup = std::vector<LookupElement>
protected

Cache lookup is a vector, with items sorted using Key.

Definition at line 83 of file GraphicsDataCache.h.

Constructor & Destructor Documentation

◆ ~GraphicsDataCacheBase()

virtual GraphicsDataCacheBase::~GraphicsDataCacheBase ( )
virtualdefault

◆ GraphicsDataCacheBase()

GraphicsDataCacheBase::GraphicsDataCacheBase ( double  scaledSampleRate)
explicitprotected

Definition at line 97 of file GraphicsDataCache.cpp.

Member Function Documentation

◆ CreateElement()

virtual GraphicsDataCacheElementBase * GraphicsDataCacheBase::CreateElement ( const GraphicsDataCacheKey key)
protectedpure virtual

Create a new Cache element. Implementation is responsible of the lifetime control.

Implemented in GraphicsDataCache< CacheElementType >, GraphicsDataCache< WaveBitmapCacheElement >, and GraphicsDataCache< WaveCacheElement >.

Referenced by CreateNewItems(), and PerformBaseLookup().

Here is the caller graph for this function:

◆ CreateNewItems()

bool GraphicsDataCacheBase::CreateNewItems ( )
private

Definition at line 298 of file GraphicsDataCache.cpp.

299{
300 for (auto& item : mNewLookupItems)
301 {
302 item.Data = CreateElement(item.Key);
303
304 if (item.Data == nullptr)
305 return false;
306
307 item.Data->LastUpdate = mCacheAccessIndex;
308 }
309
310 return true;
311}
virtual GraphicsDataCacheElementBase * CreateElement(const GraphicsDataCacheKey &key)=0
Create a new Cache element. Implementation is responsible of the lifetime control.

References CreateElement(), mCacheAccessIndex, and mNewLookupItems.

Referenced by PerformBaseLookup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DisposeElement()

virtual void GraphicsDataCacheBase::DisposeElement ( GraphicsDataCacheElementBase element)
protectedpure virtual

This method is called, when the cache element should be evicted. Implementation may not deallocate the object.

Implemented in GraphicsDataCache< CacheElementType >, GraphicsDataCache< WaveBitmapCacheElement >, and GraphicsDataCache< WaveCacheElement >.

Referenced by Invalidate(), PerformCleanup(), and PerformFullCleanup().

Here is the caller graph for this function:

◆ DisposeNewItems()

void GraphicsDataCacheBase::DisposeNewItems ( )
private

Definition at line 313 of file GraphicsDataCache.cpp.

314{
315 std::for_each(
316 mNewLookupItems.begin(), mNewLookupItems.end(),
317 [](auto elem)
318 {
319 if (elem.Data != nullptr)
320 elem.Data->Dispose();
321 });
322}

References mNewLookupItems.

Referenced by PerformBaseLookup().

Here is the caller graph for this function:

◆ FindKey()

GraphicsDataCacheBase::Lookup::iterator GraphicsDataCacheBase::FindKey ( GraphicsDataCacheKey  key)
private

Definition at line 325 of file GraphicsDataCache.cpp.

326{
327 return std::find_if(
328 mLookup.begin(), mLookup.end(),
329 [sampleRate = mScaledSampleRate, key](auto lhs)
330 { return IsSameKey(sampleRate, lhs.Key, key); });
331}
static const AudacityProject::AttachedObjects::RegisteredFactory key

References key, mLookup, mScaledSampleRate, and anonymous_namespace{ClipSegmentTest.cpp}::sampleRate.

Referenced by PerformBaseLookup().

Here is the caller graph for this function:

◆ GetMaxViewportWidth()

int64_t GraphicsDataCacheBase::GetMaxViewportWidth ( ) const
noexcept

Definition at line 92 of file GraphicsDataCache.cpp.

93{
94 return mMaxWidth;
95}

References mMaxWidth.

Referenced by WaveBitmapCache::LookupHelper::PerformLookup().

Here is the caller graph for this function:

◆ GetScaledSampleRate()

double GraphicsDataCacheBase::GetScaledSampleRate ( ) const
noexcept

Returns the sample rate associated with cache.

Definition at line 82 of file GraphicsDataCache.cpp.

83{
84 return mScaledSampleRate;
85}

References mScaledSampleRate.

Referenced by WaveDataCache::InitializeElement(), and WaveBitmapCache::LookupHelper::PerformLookup().

Here is the caller graph for this function:

◆ Invalidate()

void GraphicsDataCacheBase::Invalidate ( )

Invalidate the cache content.

Definition at line 74 of file GraphicsDataCache.cpp.

75{
76 for (auto& item : mLookup)
77 DisposeElement(item.Data);
78
79 mLookup.clear();
80}
virtual void DisposeElement(GraphicsDataCacheElementBase *element)=0
This method is called, when the cache element should be evicted. Implementation may not deallocate th...

References DisposeElement(), and mLookup.

Referenced by WaveBitmapCache::CheckCache(), WaveBitmapCache::SetPaintParameters(), SetScaledSampleRate(), WaveBitmapCache::SetSelection(), and GraphicsDataCache< CacheElementType >::~GraphicsDataCache().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PerformBaseLookup() [1/2]

GraphicsDataCacheBase::BaseLookupResult GraphicsDataCacheBase::PerformBaseLookup ( const ZoomInfo zoomInfo,
double  t0,
double  t1 
)
protected

Perform a lookup inside the cache. This method modifies mLookup and invalidates any previous result.

Definition at line 123 of file GraphicsDataCache.cpp.

125{
126 if (bool(t0 > t1) || IsSameSample(mScaledSampleRate, t0, t1))
127 return {};
128
129 const double pixelsPerSecond = zoomInfo.GetZoom();
130
131 const int64_t left = zoomInfo.TimeToPosition(t0);
132 const int64_t right = zoomInfo.TimeToPosition(t1) + 1;
133
134 const int64_t width = right - left;
135
136 const int64_t cacheLeft = left / CacheElementWidth;
137 const int64_t cacheRight = (right + CacheElementWidth - 1) / CacheElementWidth;
138 const int64_t cacheItemsCount = cacheRight - cacheLeft;
139
140 const int64_t cacheLeftColumn = cacheLeft * CacheElementWidth;
141 const int64_t cacheRightColumn = cacheRight * CacheElementWidth;
142
143 const double samplesPerPixel = mScaledSampleRate / pixelsPerSecond;
144
145 UpdateViewportWidth(width);
146
147 mNewLookupItems.clear();
148 mNewLookupItems.reserve(cacheItemsCount);
149
150 const auto ppsMatchRange =
151 GetPPSMatchRange(mLookup, pixelsPerSecond, mScaledSampleRate);
152
153 for (int64_t itemIndex = 0; itemIndex < cacheItemsCount; ++itemIndex)
154 {
155 const int64_t column = cacheLeftColumn + itemIndex * CacheElementWidth;
156
157 const int64_t firstSample =
158 static_cast<int64_t>(column * samplesPerPixel);
159
160 const auto it = std::find_if(
161 ppsMatchRange.first, ppsMatchRange.second,
162 [firstSample](auto element)
163 { return element.Key.FirstSample == firstSample; });
164
165 if (it == ppsMatchRange.second)
166 mNewLookupItems.push_back({ pixelsPerSecond, firstSample });
167 }
168
169 bool needsSmoothing = !mNewLookupItems.empty();
170
172
173 if (!CreateNewItems())
174 {
176 return {};
177 }
178
179 mLookupHelper.reserve(mLookup.size() + mNewLookupItems.size());
180
181 std::merge(
182 mLookup.begin(), mLookup.end(), mNewLookupItems.begin(),
183 mNewLookupItems.end(), std::back_inserter(mLookupHelper),
184 [sampleRate = mScaledSampleRate](auto lhs, auto rhs)
185 { return IsKeyLess(sampleRate, lhs.Key, rhs.Key); });
186
188 mLookupHelper.clear();
189
190 // Find the very first item satisfying the range
191 const GraphicsDataCacheKey firstItemKey {
192 pixelsPerSecond, int64_t(cacheLeftColumn * samplesPerPixel)
193 };
194
195 auto it = FindKey(firstItemKey);
196
197 assert(it != mLookup.end());
198
199 if (it == mLookup.end())
200 return {};
201
202 GraphicsDataCacheElementBase* prevItem = nullptr;
203
204 for (int64_t itemIndex = 0; itemIndex < cacheItemsCount; ++itemIndex)
205 {
206 auto data = it->Data;
207
209 data->AwaitsEviction = false;
210
211 if (!data->IsComplete && data->LastUpdate != mCacheAccessIndex)
212 {
213 if (!UpdateElement(it->Key, *data))
214 return {};
215
216 needsSmoothing = true;
217 }
218
219 if (needsSmoothing)
220 data->Smooth(prevItem);
221
222 prevItem = data;
223
224 ++it;
225 }
226
228
229 it = FindKey(firstItemKey);
230 auto last = it;
231
232 std::advance(last, cacheItemsCount);
233
234 return { it, last,
235 static_cast<size_t>(std::max(int64_t(0), left - cacheLeftColumn)),
236 static_cast<size_t>(
237 std::max(int64_t(0), cacheRightColumn - right)) };
238}
virtual bool UpdateElement(const GraphicsDataCacheKey &key, GraphicsDataCacheElementBase &element)=0
This method is called on all elements matching the request that are not complete (i....
void UpdateViewportWidth(int64_t width) noexcept
static constexpr uint32_t CacheElementWidth
Lookup::iterator FindKey(GraphicsDataCacheKey key)
int64 TimeToPosition(double time, int64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
Definition: ZoomInfo.cpp:44
double GetZoom() const
Definition: ZoomInfo.cpp:75
auto GetPPSMatchRange(const Container &container, double pixelsPerSecond, double sampleRate)
bool IsSameSample(double sampleRate, double t0, double t1) noexcept
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:634
A base class for the for cache elements.
uint64_t LastCacheAccess
Index filled by GraphicsDataCacheBase to implement LRU eviction policy.
A key into the graphics data cache.

References CacheElementWidth, CreateNewItems(), DisposeNewItems(), FindKey(), anonymous_namespace{GraphicsDataCache.cpp}::GetPPSMatchRange(), ZoomInfo::GetZoom(), anonymous_namespace{GraphicsDataCache.cpp}::IsSameSample(), GraphicsDataCacheElementBase::LastCacheAccess, mCacheAccessIndex, mLookup, mLookupHelper, mNewLookupItems, mScaledSampleRate, PerformCleanup(), anonymous_namespace{ClipSegmentTest.cpp}::sampleRate, anonymous_namespace{NoteTrack.cpp}::swap(), ZoomInfo::TimeToPosition(), UpdateElement(), and UpdateViewportWidth().

Referenced by GraphicsDataCache< CacheElementType >::PerformLookup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PerformBaseLookup() [2/2]

const GraphicsDataCacheElementBase * GraphicsDataCacheBase::PerformBaseLookup ( GraphicsDataCacheKey  key)
protected

Perform a lookup for the given key. This method modifies mLookup and invalidates any previous result.

Definition at line 241 of file GraphicsDataCache.cpp.

242{
243 auto it = FindKey(key);
244
246
247 if (it != mLookup.end())
248 {
249 GraphicsDataCacheElementBase* data = it->Data;
250
251 if (!data->IsComplete && data->LastUpdate != mCacheAccessIndex)
252 {
253 if (!UpdateElement(it->Key, *data))
254 return {};
255 }
256
257 data->Smooth(it == mLookup.begin() ? nullptr : (it - 1)->Data);
258
259 return data;
260 }
261
262 mNewLookupItems.clear();
263 mNewLookupItems.reserve(1);
264
265 mNewLookupItems.push_back({ key, nullptr });
266
267 LookupElement newElement { key, CreateElement(key) };
268
269 if (newElement.Data == nullptr)
270 return nullptr;
271
272 newElement.Data->LastUpdate = mCacheAccessIndex;
273 newElement.Data->LastCacheAccess = mCacheAccessIndex;
274 newElement.Data->AwaitsEviction = false;
275
276 auto insertedPosition = mLookup.insert(
277 std::upper_bound(
278 mLookup.begin(), mLookup.end(), key,
279 [sampleRate = mScaledSampleRate](auto lhs, auto rhs)
280 {
281 if constexpr (std::is_same_v<
282 std::decay_t<decltype(lhs)>, GraphicsDataCacheKey>)
283 return IsKeyLess(sampleRate, lhs, rhs.Key);
284 else
285 return IsKeyLess(sampleRate, lhs.Key, rhs);
286 }),
287 newElement);
288
289 newElement.Data->Smooth(
290 insertedPosition == mLookup.begin() ? nullptr :
291 (insertedPosition - 1)->Data);
292
294
295 return newElement.Data;
296}
uint64_t LastUpdate
The last time the item was updated. If (!IsComplete && LastUpdate < LastCacheAccess) the item will be...
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....

References CreateElement(), FindKey(), GraphicsDataCacheElementBase::IsComplete, key, GraphicsDataCacheElementBase::LastUpdate, mCacheAccessIndex, mLookup, mNewLookupItems, mScaledSampleRate, PerformCleanup(), anonymous_namespace{ClipSegmentTest.cpp}::sampleRate, GraphicsDataCacheElementBase::Smooth(), and UpdateElement().

Here is the call graph for this function:

◆ PerformCleanup()

void GraphicsDataCacheBase::PerformCleanup ( )
private

Definition at line 333 of file GraphicsDataCache.cpp.

334{
335 const int64_t lookupSize = static_cast<int64_t>(mLookup.size());
336
337 const auto allowedItems =
339
340 const int64_t itemsToEvict = lookupSize - allowedItems;
341
342 if (itemsToEvict <= 0)
343 return;
344
345 if (itemsToEvict == 1)
346 {
347 auto it = std::min_element(
348 mLookup.begin(), mLookup.end(),
349 [](auto lhs, auto rhs)
350 { return lhs.Data->LastCacheAccess < rhs.Data->LastCacheAccess; });
351
352 if (it->Data->LastCacheAccess < mCacheAccessIndex)
353 {
354 DisposeElement(it->Data);
355 mLookup.erase(it);
356 }
357 }
358 else
359 {
360 PerformFullCleanup(lookupSize, itemsToEvict);
361 }
362}
auto RoundUpUnsafe(LType numerator, RType denominator) noexcept
Returns a rounded up integer result for numerator / denominator.
Definition: RoundUpUnsafe.h:21
void PerformFullCleanup(int64_t currentSize, int64_t itemsToEvict)

References CacheElementWidth, DisposeElement(), mCacheAccessIndex, mCacheSizeMultiplier, mLookup, mMaxWidth, PerformFullCleanup(), and RoundUpUnsafe().

Referenced by PerformBaseLookup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PerformFullCleanup()

void GraphicsDataCacheBase::PerformFullCleanup ( int64_t  currentSize,
int64_t  itemsToEvict 
)
private

Definition at line 364 of file GraphicsDataCache.cpp.

366{
367 mLRUHelper.reserve(currentSize);
368
369 for (size_t i = 0; i < currentSize; ++i)
370 mLRUHelper.push_back(i);
371
372 std::make_heap(
373 mLRUHelper.begin(), mLRUHelper.end(),
374 [this](size_t lhs, size_t rhs)
375 {
376 return mLookup[lhs].Data->LastCacheAccess >
377 mLookup[rhs].Data->LastCacheAccess;
378 });
379
380 for (int64_t itemIndex = 0; itemIndex < itemsToEvict; ++itemIndex)
381 {
382 std::pop_heap(mLRUHelper.begin(), mLRUHelper.end());
383
384 const size_t index = mLRUHelper.back();
385 mLRUHelper.pop_back();
386
387 auto data = mLookup[index].Data;
388
389 if (data->LastCacheAccess >= mCacheAccessIndex)
390 break;
391
392 DisposeElement(data);
393 data->AwaitsEviction = true;
394 }
395
396 mLookup.erase(
397 std::remove_if(
398 mLookup.begin(), mLookup.end(),
399 [](auto item) { return item.Data->AwaitsEviction; }),
400 mLookup.end());
401
402 mLRUHelper.clear();
403}
std::vector< size_t > mLRUHelper

References DisposeElement(), mCacheAccessIndex, mLookup, and mLRUHelper.

Referenced by PerformCleanup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetScaledSampleRate()

void GraphicsDataCacheBase::SetScaledSampleRate ( double  scaledSampleRate)
protected

Definition at line 102 of file GraphicsDataCache.cpp.

103{
104 if (
105 std::abs(mScaledSampleRate - scaledSampleRate) <=
106 std::numeric_limits<double>::epsilon())
107 return;
108
109 mScaledSampleRate = scaledSampleRate;
110 Invalidate();
111}
void Invalidate()
Invalidate the cache content.

References Invalidate(), and mScaledSampleRate.

Referenced by WaveBitmapCache::WaveBitmapCache().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateElement()

virtual bool GraphicsDataCacheBase::UpdateElement ( const GraphicsDataCacheKey key,
GraphicsDataCacheElementBase element 
)
protectedpure virtual

This method is called on all elements matching the request that are not complete (i. e. IsComplete if false).

Implemented in GraphicsDataCache< CacheElementType >, GraphicsDataCache< WaveBitmapCacheElement >, and GraphicsDataCache< WaveCacheElement >.

Referenced by PerformBaseLookup().

Here is the caller graph for this function:

◆ UpdateViewportWidth()

void GraphicsDataCacheBase::UpdateViewportWidth ( int64_t  width)
noexcept

Definition at line 87 of file GraphicsDataCache.cpp.

88{
89 mMaxWidth = std::max(mMaxWidth, width);
90}

Referenced by PerformBaseLookup().

Here is the caller graph for this function:

Friends And Related Function Documentation

◆ GraphicsDataCacheIterator

template<typename CacheElementType >
friend class GraphicsDataCacheIterator
friend

Definition at line 143 of file GraphicsDataCache.h.

Member Data Documentation

◆ CacheElementWidth

constexpr uint32_t GraphicsDataCacheBase::CacheElementWidth = 256
staticconstexpr

◆ mCacheAccessIndex

uint64_t GraphicsDataCacheBase::mCacheAccessIndex {}
private

◆ mCacheSizeMultiplier

int32_t GraphicsDataCacheBase::mCacheSizeMultiplier { 4 }
private

Definition at line 140 of file GraphicsDataCache.h.

Referenced by PerformCleanup().

◆ mLookup

Lookup GraphicsDataCacheBase::mLookup
private

◆ mLookupHelper

Lookup GraphicsDataCacheBase::mLookupHelper
private

Definition at line 126 of file GraphicsDataCache.h.

Referenced by PerformBaseLookup().

◆ mLRUHelper

std::vector<size_t> GraphicsDataCacheBase::mLRUHelper
private

Definition at line 130 of file GraphicsDataCache.h.

Referenced by PerformFullCleanup().

◆ mMaxWidth

int64_t GraphicsDataCacheBase::mMaxWidth { 1600 }
private

Definition at line 136 of file GraphicsDataCache.h.

Referenced by GetMaxViewportWidth(), and PerformCleanup().

◆ mNewLookupItems

Lookup GraphicsDataCacheBase::mNewLookupItems
private

Definition at line 128 of file GraphicsDataCache.h.

Referenced by CreateNewItems(), DisposeNewItems(), and PerformBaseLookup().

◆ mScaledSampleRate

double GraphicsDataCacheBase::mScaledSampleRate {}
private

The documentation for this class was generated from the following files: