WordDB: Use interned strings pointing directly into the buffer line data

This commit is contained in:
Maxime Coste 2014-10-07 09:15:32 +01:00
parent f3fb299359
commit b097bbbf52
5 changed files with 28 additions and 9 deletions

View File

@ -126,7 +126,7 @@ public:
BufferIterator end() const; BufferIterator end() const;
LineCount line_count() const; LineCount line_count() const;
const StringView& operator[](LineCount line) const const InternedString& operator[](LineCount line) const
{ return m_lines[line]; } { return m_lines[line]; }
// returns an iterator at given coordinates. clamp line_and_column // returns an iterator at given coordinates. clamp line_and_column

View File

@ -79,6 +79,21 @@ public:
using StringView::operator==; using StringView::operator==;
using StringView::operator!=; using StringView::operator!=;
InternedString acquire_substr(ByteCount from, ByteCount length = INT_MAX) const
{
if (m_slot == -1)
return InternedString{};
StringRegistry::instance().acquire(m_slot);
return InternedString{StringView::substr(from, length), m_slot};
}
InternedString acquire_substr(CharCount from, CharCount length = INT_MAX) const
{
if (m_slot == -1)
return InternedString{};
StringRegistry::instance().acquire(m_slot);
return InternedString{StringView::substr(from, length), m_slot};
}
private: private:
friend class StringRegistry; friend class StringRegistry;

View File

@ -424,7 +424,8 @@ Selection select_indent(const Buffer& buffer, const Selection& selection, Object
LineCount begin_line = line - 1; LineCount begin_line = line - 1;
if (flags & ObjectFlags::ToBegin) if (flags & ObjectFlags::ToBegin)
{ {
while (begin_line >= 0 and (buffer[begin_line] == "\n" or get_indent(buffer[begin_line], tabstop) >= indent)) while (begin_line >= 0 and (buffer[begin_line] == StringView{"\n"} or
get_indent(buffer[begin_line], tabstop) >= indent))
--begin_line; --begin_line;
} }
++begin_line; ++begin_line;
@ -432,7 +433,8 @@ Selection select_indent(const Buffer& buffer, const Selection& selection, Object
if (flags & ObjectFlags::ToEnd) if (flags & ObjectFlags::ToEnd)
{ {
const LineCount end = buffer.line_count(); const LineCount end = buffer.line_count();
while (end_line < end and (buffer[end_line] == "\n" or get_indent(buffer[end_line], tabstop) >= indent)) while (end_line < end and (buffer[end_line] == StringView{"\n"} or
get_indent(buffer[end_line], tabstop) >= indent))
++end_line; ++end_line;
} }
--end_line; --end_line;

View File

@ -35,20 +35,20 @@ void test_buffer()
// check insert at end behaviour: auto add end of line if necessary // check insert at end behaviour: auto add end of line if necessary
pos = buffer.end()-1; pos = buffer.end()-1;
buffer.insert(pos, "tchou"); buffer.insert(pos, "tchou");
kak_assert(buffer.string(pos.coord(), buffer.end_coord()) == "tchou\n"); kak_assert(buffer.string(pos.coord(), buffer.end_coord()) == StringView{"tchou\n"});
pos = buffer.end()-1; pos = buffer.end()-1;
buffer.insert(buffer.end(), "kanaky\n"); buffer.insert(buffer.end(), "kanaky\n");
kak_assert(buffer.string((pos+1).coord(), buffer.end_coord()) == "kanaky\n"); kak_assert(buffer.string((pos+1).coord(), buffer.end_coord()) == StringView{"kanaky\n"});
buffer.commit_undo_group(); buffer.commit_undo_group();
buffer.erase(pos+1, buffer.end()); buffer.erase(pos+1, buffer.end());
buffer.insert(buffer.end(), "mutch\n"); buffer.insert(buffer.end(), "mutch\n");
buffer.commit_undo_group(); buffer.commit_undo_group();
buffer.undo(); buffer.undo();
kak_assert(buffer.string(buffer.advance(buffer.end_coord(), -7), buffer.end_coord()) == "kanaky\n"); kak_assert(buffer.string(buffer.advance(buffer.end_coord(), -7), buffer.end_coord()) == StringView{"kanaky\n"});
buffer.redo(); buffer.redo();
kak_assert(buffer.string(buffer.advance(buffer.end_coord(), -6), buffer.end_coord()) == "mutch\n"); kak_assert(buffer.string(buffer.advance(buffer.end_coord(), -6), buffer.end_coord()) == StringView{"mutch\n"});
} }
void test_undo_group_optimizer() void test_undo_group_optimizer()

View File

@ -7,7 +7,7 @@
namespace Kakoune namespace Kakoune
{ {
static std::vector<InternedString> get_words(StringView content) static std::vector<InternedString> get_words(const InternedString& content)
{ {
std::vector<InternedString> res; std::vector<InternedString> res;
using Iterator = utf8::iterator<const char*, utf8::InvalidPolicy::Pass>; using Iterator = utf8::iterator<const char*, utf8::InvalidPolicy::Pass>;
@ -24,7 +24,9 @@ static std::vector<InternedString> get_words(StringView content)
} }
else if (in_word and not word) else if (in_word and not word)
{ {
res.push_back(StringView{word_start, it.base()}); const ByteCount start = word_start - content.begin();
const ByteCount length = it.base() - word_start;
res.push_back(content.acquire_substr(start, length));
in_word = false; in_word = false;
} }
} }