summaryrefslogtreecommitdiff
path: root/src/shared_string.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared_string.cc')
-rw-r--r--src/shared_string.cc44
1 files changed, 29 insertions, 15 deletions
diff --git a/src/shared_string.cc b/src/shared_string.cc
index 9d816a58..6cf270c2 100644
--- a/src/shared_string.cc
+++ b/src/shared_string.cc
@@ -4,29 +4,43 @@
namespace Kakoune
{
-StringDataPtr StringRegistry::intern(StringView str)
+StringDataPtr StringData::create(ArrayView<const StringView> strs)
{
- auto it = m_strings.find(str);
- if (it == m_strings.end())
+ const int len = std::accumulate(strs.begin(), strs.end(), 0,
+ [](int l, StringView s)
+ { return l + (int)s.length(); });
+ void* ptr = StringData::operator new(sizeof(StringData) + len + 1);
+ auto* res = new (ptr) StringData(len);
+ auto* data = reinterpret_cast<char*>(res + 1);
+ for (auto& str : strs)
{
- auto data = StringData::create(str);
- it = m_strings.emplace(data->strview(), data).first;
+ memcpy(data, str.begin(), (size_t)str.length());
+ data += (int)str.length();
}
- return it->second;
+ *data = 0;
+ return RefPtr<StringData, PtrPolicy>{res};
}
-void StringRegistry::purge_unused()
+StringDataPtr StringData::Registry::intern(StringView str)
{
- for (auto it = m_strings.begin(); it != m_strings.end(); )
- {
- if (it->second->refcount == 1)
- it = m_strings.erase(it);
- else
- ++it;
- }
+ auto it = m_strings.find(str);
+ if (it != m_strings.end())
+ return StringDataPtr{it->second};
+
+ auto data = StringData::create(str);
+ data->refcount |= interned_flag;
+ m_strings.emplace(data->strview(), data.get());
+ return data;
+}
+
+void StringData::Registry::remove(StringView str)
+{
+ auto it = m_strings.find(str);
+ kak_assert(it != m_strings.end());
+ m_strings.erase(it);
}
-void StringRegistry::debug_stats() const
+void StringData::Registry::debug_stats() const
{
write_to_debug_buffer("Shared Strings stats:");
size_t total_refcount = 0;