diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2015-01-19 13:25:04 +0000 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2015-01-19 13:25:04 +0000 |
| commit | 3697548e35d8edb2558217b129db9fec89137c34 (patch) | |
| tree | 4935955dd90fbdca94c774cc8ff0097e867de756 /src/shared_string.hh | |
| parent | 39689f0a1806f49c47f6fa65163dba4ae901d839 (diff) | |
Use a single allocation for SharedString::Storage
Diffstat (limited to 'src/shared_string.hh')
| -rw-r--r-- | src/shared_string.hh | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/src/shared_string.hh b/src/shared_string.hh index 8a84bf48..a0a4a8e1 100644 --- a/src/shared_string.hh +++ b/src/shared_string.hh @@ -14,19 +14,31 @@ class SharedString : public StringView public: struct Storage : UseMemoryDomain<MemoryDomain::SharedString> { - int refcount = 0; - Vector<char, MemoryDomain::SharedString> content; + int refcount; + int length; + char data[1]; - Storage(StringView str) + StringView strview() const { return {data, length}; } + + static Storage* create(StringView str) + { + const int len = (int)str.length(); + void* ptr = Storage::operator new(sizeof(Storage) + len); + Storage* res = reinterpret_cast<Storage*>(ptr); + memcpy(res->data, str.data(), len); + res->refcount = 0; + res->length = len; + res->data[len] = 0; + return res; + } + + static void destroy(Storage* s) { - content.reserve((int)str.length() + 1); - content.assign(str.begin(), str.end()); - content.push_back('\0'); + Storage::operator delete(s, sizeof(Storage) + s->length); } - StringView strview() const { return {&content.front(), &content.back()}; } friend void inc_ref_count(Storage* s) { ++s->refcount; } - friend void dec_ref_count(Storage* s) { if (--s->refcount == 0) delete s; } + friend void dec_ref_count(Storage* s) { if (--s->refcount == 0) Storage::destroy(s); } }; SharedString() = default; @@ -34,7 +46,7 @@ public: { if (not str.empty()) { - m_storage = new Storage{str}; + m_storage = Storage::create(str); StringView::operator=(m_storage->strview()); } } |
