1use std::{
2 cell::UnsafeCell,
3 ops::{Index, IndexMut},
4};
5
6pub struct StockPool<T> {
10 stock_list: [Vec<UnsafeCell<Option<Box<T>>>>; 10],
11}
12
13impl<T: Default> StockPool<T> {
14
15 #[must_use]
16 pub fn new_default() -> StockPool<T> {
17 let get = || {
18 let mut add_v = Vec::with_capacity(10_0000);
19 for _ in 0..10_0000 {
20 add_v.push(UnsafeCell::new(Some(Box::new(T::default()))));
21 }
22 add_v
23 };
24 StockPool {
25 stock_list: [
26 get(),
27 get(),
28 get(),
29 get(),
30 get(),
31 get(),
32 get(),
33 get(),
34 get(),
35 get(),
36 ],
37 }
38 }
39}
40
41impl<T> StockPool<T> {
42 #[must_use]
44 pub fn new_empty() -> StockPool<T> {
45 let get = || {
46 let mut add_v = Vec::with_capacity(10_0000);
47 for _ in 0..10_0000 {
48 add_v.push(UnsafeCell::new(None));
49 }
50 add_v
51 };
52 StockPool {
53 stock_list: [
54 get(),
55 get(),
56 get(),
57 get(),
58 get(),
59 get(),
60 get(),
61 get(),
62 get(),
63 get(),
64 ],
65 }
66 }
67
68 #[must_use]
69 pub fn len(&self) -> usize {
70 self.all_items().len()
71 }
72
73 #[inline(always)]
74 fn _get<'a>(&'a self, i7: i32) -> &'a mut Option<Box<T>> {
75 let i7 = i7 as usize;
77 let i6 = i7 % 1_000_000;
78 let i = i6 / 1000_00;
79 let i5 = i6 % 1000_00;
80 let r = &self.stock_list[i]
81 .get(i5)
82 .unwrap_or_else(|| unreachable!("股票代码在股票池中不存在: {i7}({i}-{i5})"));
83 unsafe { &mut *r.get() }
84 }
85
86 pub fn all_items(&self) -> Vec<&T> {
87 let mut items = Vec::new();
88 for ele in self.stock_list.iter() {
89 for ele in ele {
90 if let Some(item) = unsafe { &*ele.get() } {
91 items.push(item.as_ref());
92 }
93 }
94 }
95
96 items
97 }
98
99 #[inline(always)]
100 pub fn is_empty(&self, i7: i32) -> bool {
101 self._get(i7).is_none()
102 }
103
104 #[inline(always)]
106 pub fn get(&self, i7: i32) -> Option<&T> {
107 self._get(i7).as_ref().map(|x| x.as_ref())
108 }
109
110 #[inline(always)]
111 pub fn get_unchecked(&self, i7: i32) -> &T {
112 self._get(i7)
113 .as_ref()
114 .unwrap_or_else(|| unreachable!("股票数据为空: {i7}"))
115 }
116
117 #[inline(always)]
118 pub fn get_mut(&self, i7: i32) -> Option<&mut T> {
119 self._get(i7).as_mut().map(|x| x.as_mut())
120 }
121
122 #[inline(always)]
123 pub fn insert(&self, i7: i32, val: T) -> Option<Box<T>> {
124 self._get(i7).replace(Box::new(val))
125 }
126
127 #[inline(always)]
128 pub fn remove(&self, i7: i32) -> Option<Box<T>> {
129 self._get(i7).take()
130 }
131}
132
133impl<T: Default> Index<i32> for StockPool<T> {
134 type Output = T;
135 fn index(&self, i7: i32) -> &Self::Output {
136 self.get(i7)
137 .unwrap_or_else(|| unreachable!("股票代码在股票池中不存在: {}", i7))
138 }
139}
140
141impl<T: Default> IndexMut<i32> for StockPool<T> {
142 fn index_mut(&mut self, i7: i32) -> &mut Self::Output {
143 self.get_mut(i7)
144 .unwrap_or_else(|| unreachable!("股票代码在股票池中不存在: {}", i7))
145 }
146}
147
148unsafe impl<T: Sync> Sync for StockPool<T> {}
149unsafe impl<T: Send> Send for StockPool<T> {}
150
151#[test]
168fn test_stock_pool() {
169 unsafe { std::env::set_var("RUST_LOG", "debug") };
170 env_logger::init();
171
172 let pool = StockPool::<i32>::new_empty();
173 pool.insert(1000001, 100);
174 println!("pool.all_items().len {}", pool.all_items().len());
175 assert_eq!(pool[1000001], 100);
176
177 let pool = StockPool::<i32>::new_default();
178 assert_eq!(pool[1000001], 0);
179
180 let pool = StockPool::<String>::new_empty();
181 assert_eq!(pool.get(1000001), None);
182 let pool = StockPool::<String>::new_default();
185 assert_eq!(pool[1000001], "".to_string());
186
187 let pool = StockPool::<i32>::new_default();
188 println!("pool.all_items().len {}", pool.all_items().len());
189
190 let pool = StockPool::<String>::new_default();
191 assert_eq!(pool[1000001], "".to_string());
192}
193
194#[test]
195fn test_stock_pool_2() {
196 unsafe { std::env::set_var("RUST_LOG", "debug") };
197 env_logger::init();
198
199 let pool = StockPool::<i32>::new_empty();
200 for i in 1..=99999 {
201 pool.insert(1_600_000 + i, i + 100000);
202 }
203 for i in 1..=99999 {
204 pool.insert(2_000_000 + i, i + 300000);
205 }
206 for i in 1..=99999 {
207 pool.insert(2_300_000 + i, i + 300000);
208 }
209 for i in 1..=99999 {
210 pool.insert(400_000 + i, i + 400000);
211 }
212
213 for i in 1..=99999 {
214 pool.insert(1_200_000 + i, i + 220000);
215 }
216
217 for i in 1..=99999 {
218 pool.insert(1_500_000 + i, i + 550000);
219 }
220
221 for i in 1..=99999 {
222 let ii = 1_600_000 + i;
223 assert_eq!((ii, pool[ii]), (ii, i + 100000));
224 }
225 for i in 1..=99999 {
226 assert_eq!(pool[2_000_000 + i], i + 300000);
227 }
228 for i in 1..=99999 {
229 let ii = 2_300_000 + i;
230 assert_eq!((ii, pool[ii]), (ii, i + 300000));
231 }
232 for i in 1..=99999 {
233 let ii = 400_000 + i;
234 assert_eq!((ii, pool[ii]), (ii, i + 400000));
235 }
236
237 for i in 1..=99999 {
238 assert_eq!(pool[1_500_000 + i], i + 550000);
239 }
240 for i in 1..=99999 {
241 assert_eq!(pool[1_200_000 + i], i + 220000);
242 }
243}