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}