summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-10-13 21:58:38 +0800
committerMaxime Coste <mawww@kakoune.org>2017-11-01 14:05:14 +0800
commitcfc52d7e6a02adadc4897c9531a85ddaa8dc9266 (patch)
tree2440f14d5b75862a3fc863c955e8f867d7b867ff /src
parent3acb75c5c282b8487f4ba6c047aae1c5594c0adc (diff)
Regex: use intrusive linked list for the free saves instead of a Vector
Diffstat (limited to 'src')
-rw-r--r--src/regex_impl.hh21
1 files changed, 14 insertions, 7 deletions
diff --git a/src/regex_impl.hh b/src/regex_impl.hh
index f1068dca..4a299504 100644
--- a/src/regex_impl.hh
+++ b/src/regex_impl.hh
@@ -185,7 +185,11 @@ public:
private:
struct Saves
{
- int refcount;
+ union // ref count when in use, next_free when in free list
+ {
+ int refcount;
+ Saves* next_free;
+ };
Iterator pos[1];
};
@@ -194,10 +198,10 @@ private:
{
kak_assert(not copy or pos != nullptr);
const auto count = m_program.save_count;
- if (not m_free_saves.empty())
+ if (m_first_free != nullptr)
{
- Saves* res = m_free_saves.back();
- m_free_saves.pop_back();
+ Saves* res = m_first_free;
+ m_first_free = res->next_free;
res->refcount = 1;
if (copy)
std::copy(pos, pos + count, res->pos);
@@ -208,7 +212,7 @@ private:
}
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)
new (&saves->pos[i]) Iterator{copy ? pos[i] : Iterator{}};
m_saves.push_back(saves);
@@ -218,7 +222,10 @@ private:
void release_saves(Saves* saves)
{
if (saves and --saves->refcount == 0)
- m_free_saves.push_back(saves);
+ {
+ saves->next_free = m_first_free;
+ m_first_free = saves;
+ }
};
struct Thread
@@ -479,7 +486,7 @@ private:
RegexExecFlags m_flags;
Vector<Saves*> m_saves;
- Vector<Saves*> m_free_saves;
+ Saves* m_first_free = nullptr;
Saves* m_captures = nullptr;
};