maplibre/legacy/util/
mod.rs1use std::{
2 hash::{DefaultHasher, Hash, Hasher},
3 ops::Range,
4};
5
6pub mod constants;
7pub mod geo;
8pub mod i18n;
9pub mod math;
10
11pub fn hash_combine<T: Hash>(seed: &mut u64, v: &T) {
13 let mut hasher = DefaultHasher::new(); v.hash(&mut hasher);
15 *seed ^= hasher
16 .finish()
17 .overflowing_add(0x9e3779b9)
18 .0
19 .overflowing_add(*seed << 6)
20 .0
21 .overflowing_add(*seed >> 2)
22 .0;
23}
24
25pub fn hash<T: Hash>(args: &[T]) -> u64 {
27 let mut seed = 0;
28
29 for arg in args {
30 hash_combine(&mut seed, arg);
31 }
32 seed
33}
34
35fn split_in_half(range: &Range<usize>) -> (Range<usize>, Range<usize>) {
37 let mid = (range.end - range.start) / 2 + range.start;
38
39 ((range.start..mid), (mid..range.end))
40}
41
42pub fn lower_bound<T: PartialOrd>(v: &[T], elt: &T) -> usize {
44 let mut range = 0..v.len();
45 while !range.is_empty() {
46 let (a, b) = split_in_half(&range);
47 if v[b.start] < *elt {
48 range = b.start + 1..b.end;
49 } else {
50 range = a;
51 }
52 }
53 range.start
54}
55
56#[cfg(test)]
57mod tests {
58 use crate::legacy::util::lower_bound;
59
60 #[test]
61 fn lower_bound_test() {
63 let mut input = [10, 20, 30, 30, 20, 10, 10, 20];
64
65 input.sort();
66
67 assert_eq!(lower_bound(&input, &20), 3);
68 assert_eq!(lower_bound(&input, &15), 3);
69 assert_eq!(lower_bound(&input, &5), 0);
70 }
71}