MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / DeleteEntriesFromSpriteCache

Function DeleteEntriesFromSpriteCache

src/spritecache.cpp:704–760  ·  view source on GitHub ↗

* Delete entries from the sprite cache to remove the requested number of bytes. * Sprite data is removed in order of LRU values. * The total number of bytes removed may be larger than the number requested. * @param to_remove Requested number of bytes to remove. */

Source from the content-addressed store, hash-verified

702 * @param to_remove Requested number of bytes to remove.
703 */
704static void DeleteEntriesFromSpriteCache(size_t to_remove)
705{
706 const size_t initial_in_use = _spritecache_bytes_used;
707
708 struct SpriteInfo {
709 uint32_t lru;
710 SpriteID id;
711 size_t size;
712
713 bool operator<(const SpriteInfo &other) const
714 {
715 return this->lru < other.lru;
716 }
717 };
718
719 std::vector<SpriteInfo> candidates; // max heap, ordered by LRU
720 size_t candidate_bytes = 0; // total bytes that would be released when clearing all sprites in candidates
721
722 auto push = [&](SpriteInfo info) {
723 candidates.push_back(info);
724 std::push_heap(candidates.begin(), candidates.end());
725 candidate_bytes += info.size;
726 };
727
728 auto pop = [&]() {
729 candidate_bytes -= candidates.front().size;
730 std::pop_heap(candidates.begin(), candidates.end());
731 candidates.pop_back();
732 };
733
734 SpriteID i = 0;
735 for (; i != static_cast<SpriteID>(_spritecache.size()) && candidate_bytes < to_remove; i++) {
736 const SpriteCache *sc = GetSpriteCache(i);
737 if (sc->ptr != nullptr) {
738 push({ sc->lru, i, sc->length });
739 if (candidate_bytes >= to_remove) break;
740 }
741 }
742 /* candidates now contains enough bytes to meet to_remove.
743 * only sprites with LRU values <= the maximum (i.e. the top of the heap) need to be considered */
744 for (; i != static_cast<SpriteID>(_spritecache.size()); i++) {
745 const SpriteCache *sc = GetSpriteCache(i);
746 if (sc->ptr != nullptr && sc->lru <= candidates.front().lru) {
747 push({ sc->lru, i, sc->length });
748 while (!candidates.empty() && candidate_bytes - candidates.front().size >= to_remove) {
749 pop();
750 }
751 }
752 }
753
754 for (const auto &it : candidates) {
755 GetSpriteCache(it.id)->ClearSpriteData();
756 }
757
758 Debug(sprite, 3, "DeleteEntriesFromSpriteCache, deleted: {}, freed: {}, in use: {} --> {}, requested: {}",
759 candidates.size(), candidate_bytes, initial_in_use, _spritecache_bytes_used, to_remove);
760}
761

Callers 1

IncreaseSpriteLRUFunction · 0.85

Calls 8

GetSpriteCacheFunction · 0.85
push_backMethod · 0.80
pop_backMethod · 0.80
ClearSpriteDataMethod · 0.80
beginMethod · 0.45
endMethod · 0.45
sizeMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected