diff --git a/src/buffer.cc b/src/buffer.cc index 3c402905..2f80cc9c 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -453,7 +453,7 @@ ByteCoord Buffer::char_next(ByteCoord coord) const if (coord.column < m_lines[coord.line].length() - 1) { auto line = m_lines[coord.line]; - coord.column += utf8::codepoint_size(line[(int)coord.column]); + coord.column += utf8::codepoint_size(line[coord.column]); // Handle invalid utf-8 if (coord.column >= line.length()) { diff --git a/src/interned_string.cc b/src/interned_string.cc index b8825f66..5afb460e 100644 --- a/src/interned_string.cc +++ b/src/interned_string.cc @@ -24,26 +24,32 @@ InternedString StringRegistry::acquire(StringView str) StringView storage_view{m_storage[slot].first.data(), (int)m_storage[slot].first.size()}; m_slot_map[storage_view] = slot; - return InternedString{storage_view, InternedString::AlreadyAcquired{}}; + return InternedString{storage_view, slot}; } size_t slot = it->second; m_storage[slot].second++; StringView storage_view{m_storage[slot].first.data(), (int)m_storage[slot].first.size()}; - return InternedString{storage_view, InternedString::AlreadyAcquired{}}; + return InternedString{storage_view, slot}; } -void StringRegistry::release(StringView str) +void StringRegistry::acquire(size_t slot) { - auto it = m_slot_map.find(str); - kak_assert(it != m_slot_map.end()); + kak_assert(slot < m_storage.size()); + kak_assert(m_storage[slot].second > 0); + ++m_storage[slot].second; +} - size_t slot = it->second; +void StringRegistry::release(size_t slot) +{ if (--m_storage[slot].second == 0) { m_free_slots.push_back(slot); + std::vector& data = m_storage[slot].first; + auto it = m_slot_map.find(StringView{data.data(), (int)data.size()}); + kak_assert(it != m_slot_map.end()); m_slot_map.erase(it); - m_storage[slot].first.clear(); + data.clear(); } } diff --git a/src/interned_string.hh b/src/interned_string.hh index 23984a5d..c1bf3517 100644 --- a/src/interned_string.hh +++ b/src/interned_string.hh @@ -17,7 +17,8 @@ private: friend class InternedString; InternedString acquire(StringView str); - void release(StringView str); + void acquire(size_t slot); + void release(size_t slot); std::unordered_map m_slot_map; std::vector m_free_slots; @@ -34,26 +35,34 @@ public: InternedString(InternedString&& str) : StringView(str) { - static_cast(str) = StringView{}; + m_slot = str.m_slot; + str.m_slot = -1; } InternedString(const char* str) : StringView() { acquire_ifn(str); } InternedString(StringView str) : StringView() { acquire_ifn(str); } - //InternedString(const String& str) : StringView() { acquire_ifn(str); } InternedString& operator=(const InternedString& str) { if (str.data() == data() && str.length() == length()) return *this; - release_ifn(); - acquire_ifn(str); + static_cast(*this) = str; + if (str.m_slot != m_slot) + { + release_ifn(); + m_slot = str.m_slot; + if (str.m_slot != -1) + StringRegistry::instance().acquire(str.m_slot); + } + return *this; } InternedString& operator=(InternedString&& str) { static_cast(*this) = str; - static_cast(str) = StringView{}; + m_slot = str.m_slot; + str.m_slot = -1; return *this; } @@ -73,23 +82,27 @@ public: private: friend class StringRegistry; - struct AlreadyAcquired{}; - InternedString(StringView str, AlreadyAcquired) - : StringView(str) {} + InternedString(StringView str, size_t slot) + : StringView(str), m_slot(slot) {} void acquire_ifn(StringView str) { if (str.empty()) + { static_cast(*this) = StringView{}; + m_slot = -1; + } else *this = StringRegistry::instance().acquire(str); } void release_ifn() { - if (!empty()) - StringRegistry::instance().release(*this); + if (m_slot != -1) + StringRegistry::instance().release(m_slot); } + + size_t m_slot = -1; }; }