diff options
Diffstat (limited to 'src/shared_string.cc')
| -rw-r--r-- | src/shared_string.cc | 44 |
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; |
