mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-06-14 15:30:07 +00:00
#438: M1396870 M1397304
This commit is contained in:
parent
78dd4ea8ff
commit
3ee4857708
|
@ -936,11 +936,37 @@ void
|
||||||
imgCacheQueue::Remove(imgCacheEntry* entry)
|
imgCacheQueue::Remove(imgCacheEntry* entry)
|
||||||
{
|
{
|
||||||
queueContainer::iterator it = find(mQueue.begin(), mQueue.end(), entry);
|
queueContainer::iterator it = find(mQueue.begin(), mQueue.end(), entry);
|
||||||
if (it != mQueue.end()) {
|
if (it == mQueue.end()) {
|
||||||
mSize -= (*it)->GetDataSize();
|
return;
|
||||||
mQueue.erase(it);
|
|
||||||
MarkDirty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mSize -= (*it)->GetDataSize();
|
||||||
|
|
||||||
|
// If the queue is clean and this is the first entry,
|
||||||
|
// then we can efficiently remove the entry without
|
||||||
|
// dirtying the sort order.
|
||||||
|
if (!IsDirty() && it == mQueue.begin()) {
|
||||||
|
std::pop_heap(mQueue.begin(), mQueue.end(),
|
||||||
|
imgLoader::CompareCacheEntries);
|
||||||
|
mQueue.pop_back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove from the middle of the list. This potentially
|
||||||
|
// breaks the binary heap sort order.
|
||||||
|
mQueue.erase(it);
|
||||||
|
|
||||||
|
// If we only have one entry or the queue is empty, though,
|
||||||
|
// then the sort order is still effectively good. Simply
|
||||||
|
// refresh the list to clear the dirty flag.
|
||||||
|
if (mQueue.size() <= 1) {
|
||||||
|
Refresh();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise we must mark the queue dirty and potentially
|
||||||
|
// trigger an expensive sort later.
|
||||||
|
MarkDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -950,7 +976,11 @@ imgCacheQueue::Push(imgCacheEntry* entry)
|
||||||
|
|
||||||
RefPtr<imgCacheEntry> refptr(entry);
|
RefPtr<imgCacheEntry> refptr(entry);
|
||||||
mQueue.push_back(refptr);
|
mQueue.push_back(refptr);
|
||||||
MarkDirty();
|
// If we're not dirty already, then we can efficiently add this to the
|
||||||
|
// binary heap immediately. This is only O(log n).
|
||||||
|
if (!IsDirty()) {
|
||||||
|
std::push_heap(mQueue.begin(), mQueue.end(), imgLoader::CompareCacheEntries);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<imgCacheEntry>
|
already_AddRefed<imgCacheEntry>
|
||||||
|
@ -974,6 +1004,8 @@ imgCacheQueue::Pop()
|
||||||
void
|
void
|
||||||
imgCacheQueue::Refresh()
|
imgCacheQueue::Refresh()
|
||||||
{
|
{
|
||||||
|
// Resort the list. This is an O(3 * n) operation and best avoided
|
||||||
|
// if possible.
|
||||||
std::make_heap(mQueue.begin(), mQueue.end(), imgLoader::CompareCacheEntries);
|
std::make_heap(mQueue.begin(), mQueue.end(), imgLoader::CompareCacheEntries);
|
||||||
mDirty = false;
|
mDirty = false;
|
||||||
}
|
}
|
||||||
|
@ -996,6 +1028,14 @@ imgCacheQueue::GetNumElements() const
|
||||||
return mQueue.size();
|
return mQueue.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
imgCacheQueue::Contains(imgCacheEntry* aEntry) const
|
||||||
|
{
|
||||||
|
// return mQueue.Contains(aEntry); // if we convert this to nsTArray
|
||||||
|
// std::vector version
|
||||||
|
return (std::find(mQueue.begin(), mQueue.end(), aEntry) != mQueue.end());
|
||||||
|
}
|
||||||
|
|
||||||
imgCacheQueue::iterator
|
imgCacheQueue::iterator
|
||||||
imgCacheQueue::begin()
|
imgCacheQueue::begin()
|
||||||
{
|
{
|
||||||
|
@ -1523,7 +1563,12 @@ void
|
||||||
imgLoader::CacheEntriesChanged(bool aForChrome, int32_t aSizeDiff /* = 0 */)
|
imgLoader::CacheEntriesChanged(bool aForChrome, int32_t aSizeDiff /* = 0 */)
|
||||||
{
|
{
|
||||||
imgCacheQueue& queue = GetCacheQueue(aForChrome);
|
imgCacheQueue& queue = GetCacheQueue(aForChrome);
|
||||||
queue.MarkDirty();
|
// We only need to dirty the queue if there is any sorting
|
||||||
|
// taking place. Empty or single-entry lists can't become
|
||||||
|
// dirty.
|
||||||
|
if (queue.GetNumElements() > 1) {
|
||||||
|
queue.MarkDirty();
|
||||||
|
}
|
||||||
queue.UpdateSize(aSizeDiff);
|
queue.UpdateSize(aSizeDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1552,7 +1597,9 @@ imgLoader::CheckCacheLimits(imgCacheTable& cache, imgCacheQueue& queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry) {
|
if (entry) {
|
||||||
RemoveFromCache(entry);
|
// We just popped this entry from the queue, so pass AlreadyRemoved
|
||||||
|
// to avoid searching the queue again in RemoveFromCache.
|
||||||
|
RemoveFromCache(entry, QueueState::AlreadyRemoved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1859,7 +1906,7 @@ imgLoader::RemoveFromCache(const ImageCacheKey& aKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
imgLoader::RemoveFromCache(imgCacheEntry* entry)
|
imgLoader::RemoveFromCache(imgCacheEntry* entry, QueueState aQueueState)
|
||||||
{
|
{
|
||||||
LOG_STATIC_FUNC(gImgLog, "imgLoader::RemoveFromCache entry");
|
LOG_STATIC_FUNC(gImgLog, "imgLoader::RemoveFromCache entry");
|
||||||
|
|
||||||
|
@ -1881,7 +1928,14 @@ imgLoader::RemoveFromCache(imgCacheEntry* entry)
|
||||||
if (mCacheTracker) {
|
if (mCacheTracker) {
|
||||||
mCacheTracker->RemoveObject(entry);
|
mCacheTracker->RemoveObject(entry);
|
||||||
}
|
}
|
||||||
queue.Remove(entry);
|
// Only search the queue to remove the entry if its possible it might
|
||||||
|
// be in the queue. If we know its not in the queue this would be
|
||||||
|
// wasted work.
|
||||||
|
MOZ_ASSERT_IF(aQueueState == QueueState::AlreadyRemoved,
|
||||||
|
!queue.Contains(entry));
|
||||||
|
if (aQueueState == QueueState::MaybeExists) {
|
||||||
|
queue.Remove(entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->SetEvicted(true);
|
entry->SetEvicted(true);
|
||||||
|
|
|
@ -203,6 +203,7 @@ public:
|
||||||
uint32_t GetSize() const;
|
uint32_t GetSize() const;
|
||||||
void UpdateSize(int32_t diff);
|
void UpdateSize(int32_t diff);
|
||||||
uint32_t GetNumElements() const;
|
uint32_t GetNumElements() const;
|
||||||
|
bool Contains(imgCacheEntry* aEntry) const;
|
||||||
typedef std::vector<RefPtr<imgCacheEntry> > queueContainer;
|
typedef std::vector<RefPtr<imgCacheEntry> > queueContainer;
|
||||||
typedef queueContainer::iterator iterator;
|
typedef queueContainer::iterator iterator;
|
||||||
typedef queueContainer::const_iterator const_iterator;
|
typedef queueContainer::const_iterator const_iterator;
|
||||||
|
@ -321,7 +322,16 @@ public:
|
||||||
nsresult InitCache();
|
nsresult InitCache();
|
||||||
|
|
||||||
bool RemoveFromCache(const ImageCacheKey& aKey);
|
bool RemoveFromCache(const ImageCacheKey& aKey);
|
||||||
bool RemoveFromCache(imgCacheEntry* entry);
|
|
||||||
|
// Enumeration describing if a given entry is in the cache queue or not.
|
||||||
|
// There are some cases we know the entry is definitely not in the queue.
|
||||||
|
enum class QueueState {
|
||||||
|
MaybeExists,
|
||||||
|
AlreadyRemoved
|
||||||
|
};
|
||||||
|
|
||||||
|
bool RemoveFromCache(imgCacheEntry* entry,
|
||||||
|
QueueState aQueueState = QueueState::MaybeExists);
|
||||||
|
|
||||||
bool PutIntoCache(const ImageCacheKey& aKey, imgCacheEntry* aEntry);
|
bool PutIntoCache(const ImageCacheKey& aKey, imgCacheEntry* aEntry);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user