Think of collections of different types like Position
, Color
, Name
. Instances of those can be connected by using the same key in the collection. Keys are global unique identifiers of 64 bit length. Currently, I use a hash map but this is not ideal.
// custom types
struct Position { float x, y, z; bool static; };
enum Color { RED, BLUE, GREEN };
// collections
std::unordered_map<uint64_t, Position> positions;
std::unordered_map<uint64_t, Color> colors;
std::unordered_map<uint64_t, std::string> names;
// add some data
// ...
// only access positions collection,
// so the key is not needed here
for (auto i = positions.begin(); i != positions.end(); ++i) {
if (i->second.static) continue;
i->second.x = (rand() % 1000) / 1000.f;
i->second.y = (rand() % 1000) / 1000.f;
i->second.z = (rand() % 1000) / 1000.f;
}
// access to all three collections,
// so we need the key here
for (auto i = positions.begin(); i != positions.end(); ++i) {
uint64_t id = *i->first;
auto position = i->second;
auto color = colors.find(id);
auto name = names.find(id);
if (color == colors.end() || name == names.end()) continue;
draw(*name, *position, *color);
}
I try to separate the collections, but as you can see, it also happens that collected instances of multiple collections are needed at the same time. Of course, I also need to add or delete single elements from time to time, but these cases are not performance critical.
Now I'd like to optimize iterating over individual collections. Therefore, I try to get the collections contiguously stored, which is part of the idea of data oriented design. However, I still need to access individual instances very quickly. Directly using an array doesn't work since that would allocate way too much memory and not all instances of one type have counterparts of another type. On the other hand hash maps are not optimal for iteration.
I think the data structure have to internally use an array. Which data type should I use here? And is there such a data structure implemented in the C++ standard library?