summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2014-10-05 10:20:50 +0100
committerMaxime Coste <frrrwww@gmail.com>2014-10-05 10:20:50 +0100
commit844c8f1ec4bfae6ee51fc70b9b6ebb0a4cd894ff (patch)
tree7477f42ac2f27a15ecd409b097cceb6fa37581a3 /src
parentd4a84125ef4d23f2c3e0b2eed5f6efbdc88af141 (diff)
InternedStrings know their slots
Diffstat (limited to 'src')
-rw-r--r--src/buffer.cc2
-rw-r--r--src/interned_string.cc20
-rw-r--r--src/interned_string.hh35
3 files changed, 38 insertions, 19 deletions
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<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_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<StringView, size_t> m_slot_map;
std::vector<size_t> m_free_slots;
@@ -34,26 +35,34 @@ public:
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(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<StringView&>(*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<StringView&>(*this) = str;
- static_cast<StringView&>(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<StringView&>(*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;
};
}