InternedStrings know their slots
This commit is contained in:
parent
d4a84125ef
commit
844c8f1ec4
|
@ -453,7 +453,7 @@ ByteCoord Buffer::char_next(ByteCoord coord) const
|
||||||
if (coord.column < m_lines[coord.line].length() - 1)
|
if (coord.column < m_lines[coord.line].length() - 1)
|
||||||
{
|
{
|
||||||
auto line = m_lines[coord.line];
|
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
|
// Handle invalid utf-8
|
||||||
if (coord.column >= line.length())
|
if (coord.column >= line.length())
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,26 +24,32 @@ InternedString StringRegistry::acquire(StringView str)
|
||||||
StringView storage_view{m_storage[slot].first.data(), (int)m_storage[slot].first.size()};
|
StringView storage_view{m_storage[slot].first.data(), (int)m_storage[slot].first.size()};
|
||||||
m_slot_map[storage_view] = slot;
|
m_slot_map[storage_view] = slot;
|
||||||
|
|
||||||
return InternedString{storage_view, InternedString::AlreadyAcquired{}};
|
return InternedString{storage_view, slot};
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t slot = it->second;
|
size_t slot = it->second;
|
||||||
m_storage[slot].second++;
|
m_storage[slot].second++;
|
||||||
StringView storage_view{m_storage[slot].first.data(), (int)m_storage[slot].first.size()};
|
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(slot < m_storage.size());
|
||||||
kak_assert(it != m_slot_map.end());
|
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)
|
if (--m_storage[slot].second == 0)
|
||||||
{
|
{
|
||||||
m_free_slots.push_back(slot);
|
m_free_slots.push_back(slot);
|
||||||
|
std::vector<char>& 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_slot_map.erase(it);
|
||||||
m_storage[slot].first.clear();
|
data.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,8 @@ private:
|
||||||
friend class InternedString;
|
friend class InternedString;
|
||||||
|
|
||||||
InternedString acquire(StringView str);
|
InternedString acquire(StringView str);
|
||||||
void release(StringView str);
|
void acquire(size_t slot);
|
||||||
|
void release(size_t slot);
|
||||||
|
|
||||||
std::unordered_map<StringView, size_t> m_slot_map;
|
std::unordered_map<StringView, size_t> m_slot_map;
|
||||||
std::vector<size_t> m_free_slots;
|
std::vector<size_t> m_free_slots;
|
||||||
|
@ -34,26 +35,34 @@ public:
|
||||||
|
|
||||||
InternedString(InternedString&& str) : StringView(str)
|
InternedString(InternedString&& str) : StringView(str)
|
||||||
{
|
{
|
||||||
static_cast<StringView&>(str) = StringView{};
|
m_slot = str.m_slot;
|
||||||
|
str.m_slot = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
InternedString(const char* str) : StringView() { acquire_ifn(str); }
|
InternedString(const char* str) : StringView() { acquire_ifn(str); }
|
||||||
InternedString(StringView 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)
|
InternedString& operator=(const InternedString& str)
|
||||||
{
|
{
|
||||||
if (str.data() == data() && str.length() == length())
|
if (str.data() == data() && str.length() == length())
|
||||||
return *this;
|
return *this;
|
||||||
release_ifn();
|
static_cast<StringView&>(*this) = str;
|
||||||
acquire_ifn(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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
InternedString& operator=(InternedString&& str)
|
InternedString& operator=(InternedString&& str)
|
||||||
{
|
{
|
||||||
static_cast<StringView&>(*this) = str;
|
static_cast<StringView&>(*this) = str;
|
||||||
static_cast<StringView&>(str) = StringView{};
|
m_slot = str.m_slot;
|
||||||
|
str.m_slot = -1;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,23 +82,27 @@ public:
|
||||||
private:
|
private:
|
||||||
friend class StringRegistry;
|
friend class StringRegistry;
|
||||||
|
|
||||||
struct AlreadyAcquired{};
|
InternedString(StringView str, size_t slot)
|
||||||
InternedString(StringView str, AlreadyAcquired)
|
: StringView(str), m_slot(slot) {}
|
||||||
: StringView(str) {}
|
|
||||||
|
|
||||||
void acquire_ifn(StringView str)
|
void acquire_ifn(StringView str)
|
||||||
{
|
{
|
||||||
if (str.empty())
|
if (str.empty())
|
||||||
|
{
|
||||||
static_cast<StringView&>(*this) = StringView{};
|
static_cast<StringView&>(*this) = StringView{};
|
||||||
|
m_slot = -1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
*this = StringRegistry::instance().acquire(str);
|
*this = StringRegistry::instance().acquire(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void release_ifn()
|
void release_ifn()
|
||||||
{
|
{
|
||||||
if (!empty())
|
if (m_slot != -1)
|
||||||
StringRegistry::instance().release(*this);
|
StringRegistry::instance().release(m_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t m_slot = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user