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

View file

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