Is any crate or Btreemap exposed interface could search closest key's corresponding value more effectively?
O(n) version, I think the tree data structure could do this more effectively,Is that so?
extern crate rand;
extern crate time;
use std::collections::BTreeMap;
use rand::{Rng, Rand};
use time::PreciseTime;
type ID = [u8; 20];
trait Close<K, V> {
fn get_closest(&self, key :K) -> Option<&V>;
}
impl <V> Close<ID, V> for BTreeMap<ID, V> {
fn get_closest(&self, key:ID) -> Option<&V> {
if self.is_empty() { return None };
if self.contains_key(&key) {return self.get(&key) };
let keys = self.keys();
let mut last_key: Option<&ID> = None;
for i in keys {
if i > &key {
match last_key {
Some(k) => if closer(&key, i, k) {
return self.get(i)
} else {
return self.get(k)
},
None => return self.get(i),
}
}
else {
last_key = Some(i)
}
}
return self.get(last_key.unwrap());
fn closer(orig: &ID, id1: &ID, id2: &ID) -> bool {
for (d1, d2) in orig.iter().zip(id1.iter()).map(|(x, y)| y - x)
.zip(orig.iter().zip(id2.iter()).map(|(x, y)| y -x)) {
if d1 < d2 {
return true
} else if d1 > d2 {
return false
}
}
return false
}
}
}
fn main() {
fn gen_id() -> ID {
let mut rng= rand::thread_rng();
ID::rand(&mut rng)
}
let mut bt = BTreeMap::new();
for i in 0..10000000 {
bt.insert(gen_id(), "hello".to_string());
}
for i in 0..100 {
let id = gen_id();
let mut cid = id;
cid[19] += 1;
bt.insert(id, "world".to_string());
let start = PreciseTime::now();
assert_eq!(bt.get_closest(cid).unwrap().trim(), "world");
let end = PreciseTime::now();
println!("{}", start.to(end));
}
}