diff --git a/src/buffer.cc b/src/buffer.cc index be3ca7a2..8b5f6ee5 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -180,7 +180,7 @@ void Buffer::reload(BufferLines lines, time_t fs_timestamp) auto diff = find_diff(m_lines.begin(), m_lines.size(), lines.begin(), (int)lines.size(), [](const StringDataPtr& lhs, const StringDataPtr& rhs) - { return lhs->strview() == rhs->strview(); }); + { return lhs->hash == rhs->hash and lhs->strview() == rhs->strview(); }); auto it = m_lines.begin(); for (auto& d : diff) diff --git a/src/shared_string.hh b/src/shared_string.hh index 74232613..cc52e0d9 100644 --- a/src/shared_string.hh +++ b/src/shared_string.hh @@ -13,8 +13,9 @@ struct StringData : UseMemoryDomain { int refcount; int length; + uint32_t hash; - constexpr StringData(int ref, int len) : refcount(ref), length(len) {} + StringData(int ref, int len) : refcount(ref), length(len) {} [[gnu::always_inline]] char* data() { return reinterpret_cast(this + 1); } @@ -32,6 +33,7 @@ struct StringData : UseMemoryDomain if (back != 0) res->data()[len-1] = back; res->data()[len] = 0; + res->hash = hash_data(res->data(), res->length); return RefPtr(res); } @@ -88,6 +90,11 @@ public: explicit SharedString(StringDataPtr storage) : StringView{storage->strview()}, m_storage(std::move(storage)) {} + friend size_t hash_value(const SharedString& str) + { + return str.m_storage ? str.m_storage->hash : hash_data(str.data(), (int)str.length()); + } + private: SharedString(StringView str, StringDataPtr storage) : StringView{str}, m_storage(std::move(storage)) {} @@ -96,11 +103,6 @@ private: StringDataPtr m_storage; }; -inline size_t hash_value(const SharedString& str) -{ - return hash_data(str.data(), (int)str.length()); -} - class StringRegistry : public Singleton { public: