Skip to content

RFC: Procs for searching in sets and tables by "compatible" key #33

@zah

Description

@zah

Consider the existence of types like the following:

type ComplexObject = ref object
  id: UniqueId
  # many other fields that are expensive to setup

Instances of such types are often added to sets (or they can be used as keys in tables). To achieve this, you just need to implement hashing and equality comparison in the following way:

proc hash*(o: ComplexObject): int = hash(o.id)
proc `==`(lhs, rhs: ComplexObject): bool = lhs.id == rhs.id

But this leaves one problem. When you search the set or the table for an existing key, you must allocate and construct a full instance of ComplexObject which may be expensive or non-trivial. It would be nice if one is able to search the set directly for an object with a specific id without allocating any memory.

A possible solution:

1. Add a new mixed-in proc called keyOf that would be implemented as identity by default, but would allow the user to provide the following override:

template keyOf*(o: ComplexObject): UniqueId = o.id

The implementation in tables.nim and sets.nim will then use this call prior to hashing and checking the equality of the elements in the hash table.

2. Change the signature of procs such as get, containts, etc, to the following:

proc contains[T](s: HashSet[T], key: T or type(keyOf(default(T)))): bool =

.. or just provide alternative names for the lookups using the alternative key type.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions