Last active
November 20, 2022 11:16
-
-
Save divad1196/2e5dcd62041ce31d2c4eb059929d720d to your computer and use it in GitHub Desktop.
Storage optimized string container
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://www.linkedin.com/feed/update/urn:li:activity:6999211953961275392/?commentUrn=urn%3Ali%3Acomment%3A(groupPost%3A86782-6999211953495715840%2C7000029997675487233)&dashCommentUrn=urn%3Ali%3Afsd_comment%3A(7000029997675487233%2Curn%3Ali%3AgroupPost%3A86782-6999211953495715840) | |
#include<string_view> | |
#include<vector> | |
#include<iostream> | |
#include<cstring> | |
// g++ --std=c++17 string_pool.cpp -o string_pool | |
/* | |
Total overhead (i.e. whats more than just the chars): | |
- incompressible: 1 char*, 1 size_t, 1 vector (2 size_t and 1 ptr). | |
Nb: vector is for simplicity, this could be changed if needed | |
- Relative to content: 1 char* per string, nothing more | |
Nb: | |
- We do not store the trailling \0 | |
- Access is constant time, independently of the size of the string you plan to store. | |
- I did it on a rush, there is many more we can do/add/optimize. | |
There may be some flaws in the implementation, this is just a POC. | |
*/ | |
class StringPool { | |
public: | |
StringPool(size_t pool_size, size_t string_count): m_pool_size(pool_size) { | |
m_cursor = (char*)malloc(pool_size); | |
m_strings.reserve(string_count); | |
} | |
~StringPool() { | |
void* ptr = (void*) (m_strings.empty() ? m_cursor : m_strings[0]); | |
free(ptr); | |
} | |
void insert(const char* str, size_t size) { | |
m_strings.push_back(m_cursor); | |
strncpy(m_cursor, str, size); | |
m_cursor += size; | |
} | |
void insert(const char* str) { | |
size_t size = strlen(str); | |
insert(str, size); | |
} | |
std::string_view get(size_t index) { | |
const char* start = m_strings.at(index); | |
const char* end = index + 1 < m_strings.size() ? m_strings[index + 1] : m_cursor; | |
return std::string_view(start, end - start); | |
} | |
private: | |
char* m_cursor; | |
size_t m_pool_size; | |
std::vector<const char*> m_strings; | |
}; | |
int main() { | |
StringPool pool{1000, 10}; | |
pool.insert("Hello World"); | |
pool.insert("foo"); | |
pool.insert("bar"); | |
pool.insert("baz"); | |
std::cout << pool.get(0) << std::endl; | |
std::cout << pool.get(1) << std::endl; | |
std::cout << pool.get(2) << std::endl; | |
std::cout << pool.get(3) << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment