summaryrefslogtreecommitdiff
path: root/src/shared_string.hh
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2015-01-19 13:25:04 +0000
committerMaxime Coste <frrrwww@gmail.com>2015-01-19 13:25:04 +0000
commit3697548e35d8edb2558217b129db9fec89137c34 (patch)
tree4935955dd90fbdca94c774cc8ff0097e867de756 /src/shared_string.hh
parent39689f0a1806f49c47f6fa65163dba4ae901d839 (diff)
Use a single allocation for SharedString::Storage
Diffstat (limited to 'src/shared_string.hh')
-rw-r--r--src/shared_string.hh30
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());
}
}