In my application I'm storing a huge(!) container: A vector of vectors. Each of the vectors has a unique name and I use a map to store the index to the vector for further access. Storing the data in vectors is needed in my application as I have to do a lot of processing and therefore need fast access to the elements in it.
Unfortunately std::map doesn't care for the insertion order which is important in my use case and I came across this topic:
A std::map that keep track of the order of insertion?
Unfortunately the proposed solution is not exactly what I need and I now wonder:
- Is it possible to make boost_multi_index use vectors to store the data?
- Is it reasonable at all (in my case) to replace vector/map usage with boost multi_index or
- Use something like bimap or
- Is there a more elegant way for "my problem"?
Sample code:
#include <vector>
#include <map>
#include <string>
#include <iostream>
using payload_t = std::vector<uint32_t>;
using container_t = std::vector<payload_t>;
using container_map_t = std::map<std::string, size_t>;
using connectionMask_t = std::map<std::string, uint32_t>;
int main()
{
container_t container;
container_map_t container_map;
// Store 1st payload
container.push_back(std::move(payload_t{1,2,3}));
container_map["One"] = container.size() - 1;
// Store 2nd payload
container.push_back(std::move(payload_t{4,5,6,7}));
container_map["Two"] = container.size() - 1;
// Store 3rd payload
container.push_back(std::move(payload_t{8,9}));
container_map["Three"] = container.size() - 1;
// Assign unique mask to each layer (name)
connectionMask_t masks;
for (auto const&[name, data] : container_map)
{
// Assign mask to each layer
masks[name] = 1UL << masks.size();
}
// Iterating vector access
for (auto& outer : container)
for (auto& inner : outer)
std::cout << inner;
std::cout << std::endl << std::endl;
// Direct vector access
for (auto& inner : container[1])
std::cout << inner;
std::cout << std::endl << std::endl;
// Access via name
for (auto& inner : container.at(container_map.at("Two")))
std::cout << inner;
std::cout << std::endl << std::endl;
// Iterating access via map; order not preserved
for (auto& [key, vec] : container_map)
{
std::cout << key << ": ";
for (auto& inner : container[vec])
std::cout << inner;
std::cout << std::endl;
}
return 0;
}
No. All the containers are implemented on node-based storage so iterator/reference stability is guaranteed.
It seems so, but see below.
It's unclear to me how it will fill any gap.
Perhaps. Simplest wins, IMO:
Live On Coliru
Printing
From Here
Sprinkle in what you need to taste:
Boost Container
small_vectoror evenstatic_vectorwill be a huge performance improvement)Boost Interprocess
To put all of this in shared memory/memory mapped files. This will allow you to deal with data structures way bigger than available RAM and also persisting across runs