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 ≤ bandb ≤ cthena ≤ c. - Antisymmetry: if
a ≤ bandb ≤ athena == b. - Totality: every pair of keys is comparable (no
Nonefrompartial_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§
Required Methods§
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.