Let’s say I’m using a map that uses three strings as a key. Here’s a quick example struct:
struct ExampleMapKey
{
std::string key0;
std::string key1;
std::string key2;
bool operator<(const ExampleMapKey& other) const
{
if (key0 < other.key0) return true;
else if (key0 > other.key0) return false;
if (key1 < other.key1) return true;
else if (key1 > other.key1) return false;
return key2 < other.key2;
}
}
Now, this works fine until I decide I want to use lower_bound and upper_bound. If I want to find the range of values formed by any key0, any key1 starting with “ab”, and any key2 starting with “cd”, using those 2 functions with ExampleMapKey("", "ab", "cd") and ExampleMapKey("", "ac", "ce") respectively will have me iterating through keys that don’t fulfill my requirements. Or will I miss keys that do? Either way, it’s wrong.
It seems what I need is a data structure that explicitly indexes by each key, and will also allow me to perform potentially complicated lower_bound and upper_bound iterations. Is there such a thing? I’m not necessarily using strings, nor am I limited to only 3 keys, so it needs to be STL-style or similarly generic.
Boost Multi-index Containers Library can be of help.
Update: After rereading your question, I think you may have to do what is taught in db classes; you would have to use one of the indices to create a temporary result, and prune that result, based on your second constraint (alternatively, you can run each constraint on each index, joining the results). Boost Multi-index Containers will only allow lookup on one index at a time AFAIK.
For the particular type of query that you asked, you might be able to come up with a very specialized data structure that can help, by adding indices on partitions of indices. That is for example, you take the 2nd index, split it in half, rewrite a 3rd index for the first half, and for the 2nd half. Then you split each half and repeat. This way, you can select a section of the 2nd index, and then subsequently select a part of the 3rd index that is within (approximately) that part of the 2nd index. But I don’t know of any library that does this.
Codes for (3):
Output: