We are using a multi index container to store some data indexed both by a text key and by a timestamp.
For the text key index, we are using a non-unique ordering like below:
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<tags::key>,
boost::multi_index::identity<Transaction> >
Sometimes we have an issue where we get duplicate keys for transactions that aren’t actually duplicates (don’t ask). In this case, we can tell them apart by looking at their timestamp and checking if both transactions occurred within a
certain window.
To do this, we tried to overload operator< in the following way:
bool MyTransaction::operator<(const Transaction & rhs) const {
const std::time_t WINDOW = 2;
if (getHashKey() == rhs.getHashKey()) {
if ((epochTime() - WINDOW) <= rhs.epochTime() &&
(epochTime() + WINDOW) >= rhs.epochTime())
{
return false;
} else {
return (epochTime() < rhs.epochTime());
}
} else {
return (getHashKey() < rhs.getHashKey());
}
}
This ought to work, under the assumption that equality is determined by checking that (lhs < rhs) is false and (rhs < lhs) is false. This doesn’t seem to be working correctly though. If we add some logging inside the operator overload,
we see that it only gets called once, not twice, when we call find() on that keyed index.
What is the logic behind find()? I tried to take a look but it’s so heavily templated that I couldn’t see much more than that it was doing a tree traversal and using a comp() method that’s provided as a template argument.
Also, I am testing this with just one item in the container. That item has a matching key, but the timestamps are not within the time window I’m using in the operator< overload.
I have not checked to see if the behavior is different for a container with many elements. I also tried overloading all the other comparison operators for kicks, and none of them get called ever either.
Ideas?
Thanks,
Paul