Regex: use intrusive linked list for the free saves instead of a Vector

This commit is contained in:
Maxime Coste 2017-10-13 21:58:38 +08:00
parent 3acb75c5c2
commit cfc52d7e6a

View File

@ -185,7 +185,11 @@ public:
private: private:
struct Saves struct Saves
{ {
int refcount; union // ref count when in use, next_free when in free list
{
int refcount;
Saves* next_free;
};
Iterator pos[1]; Iterator pos[1];
}; };
@ -194,10 +198,10 @@ private:
{ {
kak_assert(not copy or pos != nullptr); kak_assert(not copy or pos != nullptr);
const auto count = m_program.save_count; const auto count = m_program.save_count;
if (not m_free_saves.empty()) if (m_first_free != nullptr)
{ {
Saves* res = m_free_saves.back(); Saves* res = m_first_free;
m_free_saves.pop_back(); m_first_free = res->next_free;
res->refcount = 1; res->refcount = 1;
if (copy) if (copy)
std::copy(pos, pos + count, res->pos); std::copy(pos, pos + count, res->pos);
@ -208,7 +212,7 @@ private:
} }
void* ptr = ::operator new (sizeof(Saves) + (count-1) * sizeof(Iterator)); void* ptr = ::operator new (sizeof(Saves) + (count-1) * sizeof(Iterator));
Saves* saves = new (ptr) Saves{1, {copy ? pos[0] : Iterator{}}}; Saves* saves = new (ptr) Saves{{1}, {copy ? pos[0] : Iterator{}}};
for (size_t i = 1; i < count; ++i) for (size_t i = 1; i < count; ++i)
new (&saves->pos[i]) Iterator{copy ? pos[i] : Iterator{}}; new (&saves->pos[i]) Iterator{copy ? pos[i] : Iterator{}};
m_saves.push_back(saves); m_saves.push_back(saves);
@ -218,7 +222,10 @@ private:
void release_saves(Saves* saves) void release_saves(Saves* saves)
{ {
if (saves and --saves->refcount == 0) if (saves and --saves->refcount == 0)
m_free_saves.push_back(saves); {
saves->next_free = m_first_free;
m_first_free = saves;
}
}; };
struct Thread struct Thread
@ -479,7 +486,7 @@ private:
RegexExecFlags m_flags; RegexExecFlags m_flags;
Vector<Saves*> m_saves; Vector<Saves*> m_saves;
Vector<Saves*> m_free_saves; Saves* m_first_free = nullptr;
Saves* m_captures = nullptr; Saves* m_captures = nullptr;
}; };