-
Notifications
You must be signed in to change notification settings - Fork 19
/
tick_map.rs
57 lines (51 loc) · 1.64 KB
/
tick_map.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//! ## Tick Map
//! [`TickMap`] provides a way to access tick data directly from a hashmap, supposedly more
//! efficient than [`TickList`].
use crate::prelude::*;
use alloy::uint;
use alloy_primitives::{aliases::I24, U256};
use rustc_hash::FxHashMap;
#[derive(Clone, Debug)]
pub struct TickMap<I = I24> {
pub bitmap: TickBitMap<I>,
pub inner: FxHashMap<I, Tick<I>>,
pub tick_spacing: I,
}
impl<I: TickIndex> TickMap<I> {
#[inline]
#[must_use]
pub fn new(ticks: Vec<Tick<I>>, tick_spacing: I) -> Self {
ticks.validate_list(tick_spacing);
let mut bitmap = TickBitMap::default();
for tick in &ticks {
let compressed = tick.index.compress(tick_spacing);
let (word_pos, bit_pos) = compressed.position();
let word = bitmap.get(&word_pos).unwrap_or(&U256::ZERO);
bitmap.insert(word_pos, word | (uint!(1_U256) << bit_pos));
}
Self {
bitmap,
inner: FxHashMap::from_iter(ticks.into_iter().map(|tick| (tick.index, tick))),
tick_spacing,
}
}
}
impl<I: TickIndex> TickDataProvider for TickMap<I> {
type Index = I;
#[inline]
fn get_tick(&self, tick: Self::Index) -> Result<&Tick<Self::Index>, Error> {
self.inner
.get(&tick)
.ok_or(Error::InvalidTick(tick.to_i24()))
}
#[inline]
fn next_initialized_tick_within_one_word(
&self,
tick: Self::Index,
lte: bool,
tick_spacing: Self::Index,
) -> Result<(Self::Index, bool), Error> {
self.bitmap
.next_initialized_tick_within_one_word(tick, lte, tick_spacing)
}
}