Skip to content

Abstract key lookup into a trait for Family::get_or_create #157

@cheshirskycode

Description

@cheshirskycode

Family::get_or_create forces to clone labels data for the lookup of a counter. Example:

#[derive(Clone, Eq, Hash, PartialEq, EncodeLabelSet)]
struct RequestLabels {
    host: String,
    api: String,
}

fn test() {
    let family = Family::<RequestLabels, Counter>::default();

    fn call(host: &str, api: &str, family: &Family<RequestLabels, Counter>) {
        let labels = RequestLabels {
            host: host.to_string(),
            api: api.to_string(),
        };

        let counter = family.get_or_create(&labels);
        counter.inc();
    }
}

I must create RequestLabels with cloning host and api values instead of getting counter by data references. The Family struct uses the std::collections::HashMap inside, which doesn't allow any other way to look up.

It would be great to have the ability to write something like this:

#[derive(Clone, Eq, Hash, PartialEq, EncodeLabelSet)]
struct RequestLabels {
    host: String,
    api: String,
}

struct RequestLabelsQ<'a> {
    host: &'a str,
    api: &'a str,
}

impl Equivalent<RequestLabels> for RequestLabelsQ<'_> {
    fn equivalent(&self, key: &RequestLabels) -> bool {
        self.host == key.host && self.api == key.api
    }
}

fn test() {
    let family = Family::<RequestLabels, Counter>::default();

    fn call(host: &str, api: &str, family: &Family<RequestLabels, Counter>) {
        let labels = RequestLabelsQ {
            host, api,
        };

        let counter = family.get_or_create(&labels);
        counter.inc();
    }
}

This will require using hashbrown instead of std::collections::HashMap (but actually std map is wrapper on hashbrown).
Equivalent
HashMap::get
Also, it will affect the definition of Family::get_or_create but the behavior should be the same.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions