Skip to content

Instantly share code, notes, and snippets.

@divad1196
Last active November 20, 2022 11:16
Show Gist options
  • Save divad1196/2e5dcd62041ce31d2c4eb059929d720d to your computer and use it in GitHub Desktop.
Save divad1196/2e5dcd62041ce31d2c4eb059929d720d to your computer and use it in GitHub Desktop.
Storage optimized string container
// 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