This is not specific to the IC. This is a general Rust problem that I’m stuck with.
So, my use case is I have a post that has 3 fields, the post ID, the publisher ID and the score. The combination of the publisher ID and the post ID makes a unique post. And the score is used to rank the posts. So, I store them in a standard BTreeSet. Basically I need to store them in a sorted order by score so that I can paginate over them. And when updating the scores, the existing post whose publisher ID and post ID combination match should be updated. So, I have implemented Eq , PartialEq , Ord and PartialOrd on the custom item.
If you run the tests, you’ll see that when comparing the post objects directly, they behave as I expect them to. But when I put them in a BTreeSet, duplicates are created. I’m kinda lost on how to remedy this.
A great library for stuff that needs to be owned somewhere, and then indexed or referenced however else in many ways, is slotmap. You insert a value, get back a key, and can then copy that key around freely without worrying about lifetimes. Basically like storing a list index, except versioned so removing values Just Works.
You can’t use this directly with an automatically-sorted collection, but you can easily store a regular vector and use binary_search_by_key to maintain a sort order - if you search for your new element, given an already-sorted slice, it will tell you in O(log n) where to insert it.
Thank you for the tip. I’ll see if it improves my current implementation.
I have currently implemented a custom collection that provides an iterator to yield values exactly as I need them as described above. The implementation uses a mix of a BTreeMap and a HashMap to store the values. But it solves my needs allowing storing duplicate entries for a same score, while still maintaining a sort order for items inserted and also providing a mechanism to update score values with equality checked on a different set of properties.
Quite proud of myself for having managed to figure this part out