Speed up aging the block cache

Keep track of the total size rather than recalculating it every time as
calculating the size actually takes while.
This commit is contained in:
Thomas Goyne 2014-07-16 11:57:01 -07:00
parent 641f1e2e81
commit e2a11f2d90
1 changed files with 28 additions and 27 deletions

View File

@ -127,6 +127,9 @@ class DataBlockCache {
/// Bitmask to extract the inside-macroblock index for a block by bitwise and
size_t macroblock_index_mask;
/// Current size of the cache in bytes
size_t size = 0;
/// Factory object for blocks
BlockFactoryT factory;
@ -137,19 +140,23 @@ class DataBlockCache {
if (mb.blocks.empty())
return;
mb.blocks.clear();
auto& ba = mb.blocks;
size += (ba.size() - std::count(ba.begin(), ba.end(), nullptr)) * factory.GetBlockSize();
ba.clear();
age.erase(mb.position);
}
public:
#ifdef _MSC_VER
DataBlockCache(DataBlockCache&& rgt)
: data(std::move(rgt.data))
, age(std::move(rgt.age))
, macroblock_size(rgt.macroblock_size)
, macroblock_index_mask(rgt.macroblock_index_mask)
, factory(std::move(rgt.factory))
{ }
DataBlockCache(DataBlockCache&& rgt)
: data(std::move(rgt.data))
, age(std::move(rgt.age))
, macroblock_size(rgt.macroblock_size)
, macroblock_index_mask(rgt.macroblock_index_mask)
, size(rgt.size)
, factory(std::move(rgt.factory))
{ }
#endif
/// @brief Constructor
@ -181,9 +188,9 @@ public:
macroblock_index_mask = ~(((~0) >> MacroblockExponent) << MacroblockExponent);
data.resize((block_count + macroblock_size - 1) >> MacroblockExponent);
size = 0;
}
/// @brief Clean up the cache
/// @param max_size Target maximum size of the cache in bytes
///
@ -201,24 +208,15 @@ public:
data.clear();
data.resize(block_count);
age.clear();
size = 0;
return;
}
// Sum up data size until we hit the max
size_t cur_size = 0;
size_t block_size = factory.GetBlockSize();
auto it = age.begin();
for (; it != age.end() && cur_size < max_size; ++it)
{
auto& ba = (*it)->blocks;
cur_size += (ba.size() - std::count(ba.begin(), ba.end(), nullptr)) * block_size;
}
// Hit max, clear all remaining blocks
for (; it != age.end(); )
// Remove old entries until we're under the max size
for (auto it = age.rbegin(); size > max_size && it != age.rend(); )
KillMacroBlock(**it++);
}
/// @brief Obtain a data block from the cache
/// @param i Index of the block to retrieve
/// @param[out] created On return, tells whether the returned block was created during the operation
@ -232,13 +230,15 @@ public:
MacroBlock &mb = data[mbi];
if (mb.blocks.empty())
mb.blocks.resize(macroblock_size);
else
age.erase(mb.position);
// Move this macroblock to the front of the age list
age.push_front(&mb);
if (mb.blocks.empty())
{
mb.blocks.resize(macroblock_size);
age.push_front(&mb);
}
else if (mb.position != begin(age))
age.splice(begin(age), age, mb.position);
mb.position = age.begin();
size_t block_index = i & macroblock_index_mask;
@ -251,6 +251,7 @@ public:
mb.blocks[block_index] = factory.ProduceBlock(i);
b = mb.blocks[block_index].get();
assert(b != nullptr);
size += factory.GetBlockSize();
if (created) *created = true;
}