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