Skip to main content

DeriveKey

Trait DeriveKey 

Source
pub trait DeriveKey<V>:
    Send
    + Sync
    + 'static {
    type Key: Serialize + DeserializeOwned + Ord + Clone + Send;

    // Required method
    fn derive(value: &V) -> Self::Key;
}
Expand description

Describes how to derive a secondary index key from a record value.

Implement this trait on a marker struct, one per secondary index. For composite indices in the future, set Key to a tuple type — no change to this trait is required.

§Correctness

The secondary index B-tree routes all inserts, lookups, and range queries through Key’s Ord implementation — not raw byte comparison. Your Ord implementation must be a valid total order:

  • Transitivity: if a ≤ b and b ≤ c then a ≤ c.
  • Antisymmetry: if a ≤ b and b ≤ a then a == b.
  • Totality: every pair of keys is comparable (no None from partial_cmp).
  • Consistency: PartialOrd::partial_cmp(a, b) == Some(Ord::cmp(a, b)) always.

Violating any of these properties will silently corrupt the B-tree’s internal node ordering, causing missed lookups, phantom results, or incorrect range iteration — with no runtime error to signal the problem.

§Custom ordering

Because the B-tree uses Key::cmp for all inserts and range traversal, you can control the iteration order of a secondary-index range scan simply by choosing a Key type with the desired Ord behaviour. For example, wrapping String in a newtype whose Ord reverses the comparison stores entries in reverse alphabetical order, so range scans return them last-to-first alphabetically.

Note that identity — which bucket a key lands in — is based on the serialised byte representation, not on Ord. Two values that are Equal under a custom Ord but serialise to different bytes (e.g. "London" vs "LONDON" with a case-insensitive comparator) are stored as separate entries. To make case variants share a bucket, normalise in derive (e.g. value.city.to_lowercase()) rather than relying on Ord.

§Example

use serde::{Serialize, Deserialize};
use highlandcows_isam::DeriveKey;

#[derive(Serialize, Deserialize, Clone)]
struct User { name: String, city: String }

struct CityIndex;
impl DeriveKey<User> for CityIndex {
    type Key = String;
    fn derive(value: &User) -> String { value.city.clone() }
}

Required Associated Types§

Source

type Key: Serialize + DeserializeOwned + Ord + Clone + Send

The type of the derived secondary key.

Required Methods§

Source

fn derive(value: &V) -> Self::Key

Derive the secondary key from a value.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§