How to define an ordered Map/Set with a runtime-defined comparator?

Viewed 405

This is similar to How do I use a custom comparator function with BTreeSet? however in my case I won't know the sorting criteria until runtime. The possible criteria are extensive and can't be hard-coded (think something like sort by distance to target or sort by specific bytes in a payload or combination thereof). The sorting criteria won't change after the map/set is created.

The only alternatives I see are:

  • use a Vec, but log(n) inserts and deletes are crucial
  • wrap each of the elements with the sorting criteria (directly or indirectly), but that seems wasteful

This is possible with standard C++ containers std::map/std::set but doesn't seem possible with Rust's BTreeMap/BTreeSet. Is there an alternative in the standard library or in another crate that can do this? Or will I have to implement this myself?


My use-case is a database-like system where elements in the set are defined by a schema, like:

Element {
    FIELD x: f32
    FIELD y: f32
    FIELD z: i64

    ORDERBY z
}

But since the schema is user-defined at runtime, the elements are stored in a set of bytes (BTreeSet<Vec<u8>>). Likewise the order of the elements is user-defined. So the comparator I would give to BTreeSet would look like |a, b| schema.cmp(a, b). Hard-coded, the above example may look something like:

fn cmp(a: &Vec<u8>, b: &Vec<u8>) -> Ordering {
    let a_field = self.get_field(a, 2).as_i64();
    let b_field = self.get_field(b, 2).as_i64();
    a_field.cmp(b_field)
}
0 Answers
Related