leveldb/database/
comparator.rs

1//! All keys in leveldb are compared by their binary value unless
2//! defined otherwise.
3//!
4//! Comparators allow to override this comparison.
5//! The ordering of keys introduced by the comparator influences iteration order.
6//! Databases written with one Comparator cannot be opened with another.
7use leveldb_sys::*;
8use libc::{size_t, c_void, c_char};
9use std::slice;
10use std::cmp::Ordering;
11
12/// A comparator has two important functions:
13///
14/// * the name function returns a fixed name to detect errors when
15///   opening databases with a different name
16/// * The comparison implementation
17pub trait Comparator {
18    /// Return the name of the Comparator
19    fn name(&self) -> *const c_char;
20    /// compare two keys. This must implement a total ordering.
21    fn compare(&self, a: &[u8], b: &[u8]) -> Ordering {
22        a.cmp(b)
23    }
24
25    /// whether the comparator is the `DefaultComparator`
26    fn null() -> bool {
27        false
28    }
29}
30
31/// DefaultComparator is the a stand in for "no comparator set"
32#[derive(Copy,Clone)]
33pub struct DefaultComparator;
34
35unsafe trait InternalComparator: Comparator where Self: Sized {
36    extern "C" fn name(state: *mut c_void) -> *const c_char {
37        let x = unsafe { &*(state as *mut Self) };
38        x.name()
39    }
40
41    extern "C" fn compare(
42        state: *mut c_void,
43        a: *const c_char,
44        a_len: size_t,
45        b: *const c_char,
46        b_len: size_t
47    ) -> i32 {
48        unsafe {
49            let a_slice = slice::from_raw_parts::<u8>(a as *const u8, a_len as usize);
50            let b_slice = slice::from_raw_parts::<u8>(b as *const u8, b_len as usize);
51            let x = &*(state as *mut Self);
52
53            match x.compare(&a_slice, &b_slice) {
54                Ordering::Less => -1,
55                Ordering::Equal => 0,
56                Ordering::Greater => 1,
57            }
58        }
59    }
60
61    extern "C" fn destructor(state: *mut c_void) {
62        let _x: Box<Self> = unsafe { Box::from_raw(state as *mut Self) };
63        // let the Box fall out of scope and run the T's destructor
64    }
65}
66
67unsafe impl<C: Comparator> InternalComparator for C {}
68
69
70#[allow(missing_docs)]
71pub fn create_comparator<T: Comparator>(x: Box<T>) -> *mut leveldb_comparator_t {
72    unsafe {
73        leveldb_comparator_create(Box::into_raw(x) as *mut c_void,
74                                  <T as InternalComparator>::destructor,
75                                  <T as InternalComparator>::compare,
76                                  <T as InternalComparator>::name)
77    }
78}
79
80impl Comparator for DefaultComparator {
81    fn name(&self) -> *const c_char {
82        "default_comparator".as_ptr() as *const c_char
83    }
84
85    fn null() -> bool {
86        true
87    }
88}