nautilus_common/defi/
cache.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! DeFi-specific cache functionality.
17
18use ahash::AHashMap;
19use nautilus_model::{
20    defi::{Pool, PoolProfiler},
21    identifiers::{InstrumentId, Venue},
22};
23
24use crate::cache::Cache;
25
26/// DeFi-specific cache state.
27#[derive(Clone, Debug, Default)]
28pub(crate) struct DefiCache {
29    pub(crate) pools: AHashMap<InstrumentId, Pool>,
30    pub(crate) pool_profilers: AHashMap<InstrumentId, PoolProfiler>,
31}
32
33impl Cache {
34    /// Adds a `Pool` to the cache.
35    ///
36    /// # Errors
37    ///
38    /// This function currently does not return errors but follows the same pattern as other add methods for consistency.
39    pub fn add_pool(&mut self, pool: Pool) -> anyhow::Result<()> {
40        log::debug!("Adding `Pool` {}", pool.instrument_id);
41
42        self.defi.pools.insert(pool.instrument_id, pool);
43        Ok(())
44    }
45
46    /// Adds a `PoolProfiler` to the cache.
47    ///
48    /// # Errors
49    ///
50    /// This function currently does not return errors but follows the same pattern as other add methods for consistency.
51    pub fn add_pool_profiler(&mut self, pool_profiler: PoolProfiler) -> anyhow::Result<()> {
52        let instrument_id = pool_profiler.pool.instrument_id;
53        log::debug!("Adding `PoolProfiler` {instrument_id}");
54
55        self.defi
56            .pool_profilers
57            .insert(instrument_id, pool_profiler);
58        Ok(())
59    }
60
61    /// Gets a reference to the pool for the `instrument_id`.
62    #[must_use]
63    pub fn pool(&self, instrument_id: &InstrumentId) -> Option<&Pool> {
64        self.defi.pools.get(instrument_id)
65    }
66
67    /// Gets a mutable reference to the pool for the `instrument_id`.
68    #[must_use]
69    pub fn pool_mut(&mut self, instrument_id: &InstrumentId) -> Option<&mut Pool> {
70        self.defi.pools.get_mut(instrument_id)
71    }
72
73    /// Returns the instrument IDs of all pools in the cache, optionally filtered by `venue`.
74    #[must_use]
75    pub fn pool_ids(&self, venue: Option<&Venue>) -> Vec<InstrumentId> {
76        match venue {
77            Some(v) => self
78                .defi
79                .pools
80                .keys()
81                .filter(|id| &id.venue == v)
82                .copied()
83                .collect(),
84            None => self.defi.pools.keys().copied().collect(),
85        }
86    }
87
88    /// Returns references to all pools in the cache, optionally filtered by `venue`.
89    #[must_use]
90    pub fn pools(&self, venue: Option<&Venue>) -> Vec<&Pool> {
91        match venue {
92            Some(v) => self
93                .defi
94                .pools
95                .values()
96                .filter(|p| &p.instrument_id.venue == v)
97                .collect(),
98            None => self.defi.pools.values().collect(),
99        }
100    }
101
102    /// Gets a reference to the pool profiler for the `instrument_id`.
103    #[must_use]
104    pub fn pool_profiler(&self, instrument_id: &InstrumentId) -> Option<&PoolProfiler> {
105        self.defi.pool_profilers.get(instrument_id)
106    }
107
108    /// Gets a mutable reference to the pool profiler for the `instrument_id`.
109    #[must_use]
110    pub fn pool_profiler_mut(&mut self, instrument_id: &InstrumentId) -> Option<&mut PoolProfiler> {
111        self.defi.pool_profilers.get_mut(instrument_id)
112    }
113
114    /// Returns the instrument IDs of all pool profilers in the cache, optionally filtered by `venue`.
115    #[must_use]
116    pub fn pool_profiler_ids(&self, venue: Option<&Venue>) -> Vec<InstrumentId> {
117        match venue {
118            Some(v) => self
119                .defi
120                .pool_profilers
121                .keys()
122                .filter(|id| &id.venue == v)
123                .copied()
124                .collect(),
125            None => self.defi.pool_profilers.keys().copied().collect(),
126        }
127    }
128
129    /// Returns references to all pool profilers in the cache, optionally filtered by `venue`.
130    #[must_use]
131    pub fn pool_profilers(&self, venue: Option<&Venue>) -> Vec<&PoolProfiler> {
132        match venue {
133            Some(v) => self
134                .defi
135                .pool_profilers
136                .values()
137                .filter(|p| &p.pool.instrument_id.venue == v)
138                .collect(),
139            None => self.defi.pool_profilers.values().collect(),
140        }
141    }
142}