51 lines
1.4 KiB
C++
51 lines
1.4 KiB
C++
|
#include "interned_string.hh"
|
||
|
|
||
|
namespace Kakoune
|
||
|
{
|
||
|
|
||
|
InternedString StringRegistry::acquire(StringView str)
|
||
|
{
|
||
|
auto it = m_slot_map.find(str);
|
||
|
if (it == m_slot_map.end())
|
||
|
{
|
||
|
size_t slot;
|
||
|
if (not m_free_slots.empty())
|
||
|
{
|
||
|
slot = m_free_slots.back();
|
||
|
m_free_slots.pop_back();
|
||
|
m_storage[slot] = DataAndRefCount({str.begin(), str.end()}, 1);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
slot = m_storage.size();
|
||
|
m_storage.push_back(DataAndRefCount({str.begin(), str.end()}, 1));
|
||
|
}
|
||
|
// Create a new string view that point to the storage data
|
||
|
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{}};
|
||
|
}
|
||
|
|
||
|
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{}};
|
||
|
}
|
||
|
|
||
|
void StringRegistry::release(StringView str)
|
||
|
{
|
||
|
auto it = m_slot_map.find(str);
|
||
|
kak_assert(it != m_slot_map.end());
|
||
|
|
||
|
size_t slot = it->second;
|
||
|
if (--m_storage[slot].second == 0)
|
||
|
{
|
||
|
m_free_slots.push_back(slot);
|
||
|
m_slot_map.erase(it);
|
||
|
m_storage[slot].first.clear();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|