1const DEFAULT_MAX_INLINE_CAPACITY: usize = 10;
3const DEFAULT_INITIAL_OVERFLOW_CAPACITY: usize = 5;
5
6#[derive(Debug, Clone, PartialEq)]
7pub(crate) struct GrowableArray<
15 T: Default + Clone + PartialEq,
16 const MAX_INLINE_CAPACITY: usize = DEFAULT_MAX_INLINE_CAPACITY,
17 const INITIAL_OVERFLOW_CAPACITY: usize = DEFAULT_INITIAL_OVERFLOW_CAPACITY,
18> {
19 inline: [T; MAX_INLINE_CAPACITY],
20 overflow: Option<Vec<T>>,
21 count: usize,
22}
23
24impl<
25 T: Default + Clone + PartialEq,
26 const MAX_INLINE_CAPACITY: usize,
27 const INITIAL_OVERFLOW_CAPACITY: usize,
28 > Default for GrowableArray<T, MAX_INLINE_CAPACITY, INITIAL_OVERFLOW_CAPACITY>
29{
30 fn default() -> Self {
31 Self {
32 inline: [(); MAX_INLINE_CAPACITY].map(|_| T::default()),
33 overflow: None,
34 count: 0,
35 }
36 }
37}
38
39impl<
40 T: Default + Clone + PartialEq,
41 const MAX_INLINE_CAPACITY: usize,
42 const INITIAL_OVERFLOW_CAPACITY: usize,
43 > GrowableArray<T, MAX_INLINE_CAPACITY, INITIAL_OVERFLOW_CAPACITY>
44{
45 #[allow(dead_code)]
47 pub(crate) fn new() -> Self {
48 Self::default()
49 }
50
51 #[allow(dead_code)]
56 #[inline]
57 pub(crate) fn push(&mut self, value: T) {
58 if self.count < MAX_INLINE_CAPACITY {
59 self.inline[self.count] = value;
60 self.count += 1;
61 } else {
62 self.overflow
63 .get_or_insert_with(|| Vec::with_capacity(INITIAL_OVERFLOW_CAPACITY))
64 .push(value);
65 }
66 }
67
68 #[allow(dead_code)]
72 #[inline]
73 pub(crate) fn get(&self, index: usize) -> Option<&T> {
74 if index < self.count {
75 Some(&self.inline[index])
76 } else if let Some(ref overflow) = self.overflow {
77 overflow.get(index - MAX_INLINE_CAPACITY)
78 } else {
79 None
80 }
81 }
82
83 #[allow(dead_code)]
85 #[inline]
86 pub(crate) fn len(&self) -> usize {
87 self.count + self.overflow.as_ref().map_or(0, Vec::len)
88 }
89
90 #[allow(dead_code)]
97 #[inline]
98 pub(crate) fn iter(&self) -> impl Iterator<Item = &T> {
99 if self.overflow.is_none() || self.overflow.as_ref().unwrap().is_empty() {
100 self.inline.iter().take(self.count).chain([].iter()) } else {
103 self.inline
104 .iter()
105 .take(self.count)
106 .chain(self.overflow.as_ref().unwrap().iter())
107 }
108 }
109}
110
111impl<T: Default + Clone + PartialEq, const INLINE_CAPACITY: usize> IntoIterator
113 for GrowableArray<T, INLINE_CAPACITY>
114{
115 type Item = T;
116 type IntoIter = GrowableArrayIntoIter<T, INLINE_CAPACITY>;
117
118 fn into_iter(self) -> Self::IntoIter {
119 GrowableArrayIntoIter::<T, INLINE_CAPACITY>::new(self)
120 }
121}
122
123#[derive(Debug)]
126pub(crate) struct GrowableArrayIntoIter<
127 T: Default + Clone + PartialEq,
128 const INLINE_CAPACITY: usize,
129> {
130 iter: std::iter::Chain<
131 std::iter::Take<std::array::IntoIter<T, INLINE_CAPACITY>>,
132 std::vec::IntoIter<T>,
133 >,
134}
135
136impl<T: Default + Clone + PartialEq, const INLINE_CAPACITY: usize>
137 GrowableArrayIntoIter<T, INLINE_CAPACITY>
138{
139 fn new(source: GrowableArray<T, INLINE_CAPACITY>) -> Self {
140 Self {
141 iter: Self::get_iterator(source),
142 }
143 }
144
145 fn get_iterator(
146 source: GrowableArray<T, INLINE_CAPACITY>,
147 ) -> std::iter::Chain<
148 std::iter::Take<std::array::IntoIter<T, INLINE_CAPACITY>>,
149 std::vec::IntoIter<T>,
150 > {
151 if source.overflow.is_none() || source.overflow.as_ref().unwrap().is_empty() {
152 source
153 .inline
154 .into_iter()
155 .take(source.count)
156 .chain(Vec::<T>::new())
157 } else {
158 source
159 .inline
160 .into_iter()
161 .take(source.count)
162 .chain(source.overflow.unwrap())
163 }
164 }
165}
166
167impl<T: Default + Clone + PartialEq, const INITIAL_CAPACITY: usize> Iterator
168 for GrowableArrayIntoIter<T, INITIAL_CAPACITY>
169{
170 type Item = T;
171
172 fn next(&mut self) -> Option<Self::Item> {
173 self.iter.next()
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use crate::growable_array::{
180 GrowableArray, DEFAULT_INITIAL_OVERFLOW_CAPACITY, DEFAULT_MAX_INLINE_CAPACITY,
181 };
182 use opentelemetry::logs::AnyValue;
183 use opentelemetry::Key;
184
185 type KeyValuePair = Option<(Key, AnyValue)>;
186
187 #[test]
188 fn test_push_and_get() {
189 let mut collection = GrowableArray::<i32>::new();
190 for i in 0..15 {
191 collection.push(i);
192 }
193 for i in 0..15 {
194 assert_eq!(collection.get(i), Some(&(i as i32)));
195 }
196 }
197
198 #[test]
199 fn test_len() {
200 let mut collection = GrowableArray::<i32>::new();
201 for i in 0..15 {
202 collection.push(i);
203 }
204 assert_eq!(collection.len(), 15);
205 }
206
207 #[test]
208 fn test_into_iter() {
209 let mut collection = GrowableArray::<i32>::new();
210 for i in 0..15 {
211 collection.push(i);
212 }
213 let mut iter = collection.into_iter();
214 for i in 0..15 {
215 assert_eq!(iter.next(), Some(i));
216 }
217 assert_eq!(iter.next(), None);
218 }
219
220 #[test]
221 fn test_ref_iter() {
222 let mut collection = GrowableArray::<i32>::new();
223 for i in 0..15 {
224 collection.push(i);
225 }
226 let iter = collection.iter();
227 let mut count = 0;
228 for value in iter {
229 assert_eq!(*value, count);
230 count += 1;
231 }
232 assert_eq!(count, 15);
233 }
234
235 #[test]
236 fn test_key_value_pair_storage_growable_array() {
237 let mut collection = GrowableArray::<KeyValuePair>::new();
238
239 let key1 = Key::from("key1");
240 let value1 = AnyValue::String("value1".into());
241 let key2 = Key::from("key2");
242 let value2 = AnyValue::Int(42);
243
244 collection.push(Some((key1.clone(), value1.clone())));
245 collection.push(Some((key2.clone(), value2.clone())));
246
247 assert_eq!(
248 collection
249 .get(0)
250 .and_then(|kv| kv.as_ref().map(|kv| (&kv.0, &kv.1))),
251 Some((&key1, &value1))
252 );
253 assert_eq!(
254 collection
255 .get(1)
256 .and_then(|kv| kv.as_ref().map(|kv| (&kv.0, &kv.1))),
257 Some((&key2, &value2))
258 );
259 assert_eq!(collection.len(), 2);
260
261 let mut iter = collection.into_iter();
263 assert_eq!(iter.next(), Some(Some((key1, value1))));
264 assert_eq!(iter.next(), Some(Some((key2, value2))));
265 assert_eq!(iter.next(), None);
266 }
267
268 #[test]
269 fn test_empty_attributes() {
270 let collection = GrowableArray::<KeyValuePair>::new();
271 assert_eq!(collection.len(), 0);
272 assert_eq!(collection.get(0), None);
273
274 let mut iter = collection.into_iter();
275 assert_eq!(iter.next(), None);
276 }
277
278 #[test]
279 fn test_less_than_max_stack_capacity() {
280 let mut collection = GrowableArray::<i32>::new();
281 for i in 0..DEFAULT_MAX_INLINE_CAPACITY - 1 {
282 collection.push(i as i32);
283 }
284 assert_eq!(collection.len(), DEFAULT_MAX_INLINE_CAPACITY - 1);
285
286 for i in 0..DEFAULT_MAX_INLINE_CAPACITY - 1 {
287 assert_eq!(collection.get(i), Some(&(i as i32)));
288 }
289 assert_eq!(collection.get(DEFAULT_MAX_INLINE_CAPACITY - 1), None);
290 assert_eq!(collection.get(DEFAULT_MAX_INLINE_CAPACITY), None);
291
292 let mut iter = collection.into_iter();
293 for i in 0..DEFAULT_MAX_INLINE_CAPACITY - 1 {
294 assert_eq!(iter.next(), Some(i as i32));
295 }
296 assert_eq!(iter.next(), None);
297 }
298
299 #[test]
300 fn test_exactly_max_stack_capacity() {
301 let mut collection = GrowableArray::<i32>::new();
302 for i in 0..DEFAULT_MAX_INLINE_CAPACITY {
303 collection.push(i as i32);
304 }
305 assert_eq!(collection.len(), DEFAULT_MAX_INLINE_CAPACITY);
306
307 for i in 0..DEFAULT_MAX_INLINE_CAPACITY {
308 assert_eq!(collection.get(i), Some(&(i as i32)));
309 }
310 assert_eq!(collection.get(DEFAULT_MAX_INLINE_CAPACITY), None);
311
312 let mut iter = collection.into_iter();
313 for i in 0..DEFAULT_MAX_INLINE_CAPACITY {
314 assert_eq!(iter.next(), Some(i as i32));
315 }
316 assert_eq!(iter.next(), None);
317 }
318
319 #[test]
320 fn test_exceeds_stack_but_not_initial_vec_capacity() {
321 let mut collection = GrowableArray::<i32>::new();
322 for i in 0..(DEFAULT_MAX_INLINE_CAPACITY + DEFAULT_INITIAL_OVERFLOW_CAPACITY - 1) {
323 collection.push(i as i32);
324 }
325 assert_eq!(
326 collection.len(),
327 DEFAULT_MAX_INLINE_CAPACITY + DEFAULT_INITIAL_OVERFLOW_CAPACITY - 1
328 );
329
330 for i in 0..(DEFAULT_MAX_INLINE_CAPACITY + DEFAULT_INITIAL_OVERFLOW_CAPACITY - 1) {
331 assert_eq!(collection.get(i), Some(&(i as i32)));
332 }
333 assert_eq!(
334 collection.get(DEFAULT_MAX_INLINE_CAPACITY + DEFAULT_INITIAL_OVERFLOW_CAPACITY - 1),
335 None
336 );
337 assert_eq!(
338 collection.get(DEFAULT_MAX_INLINE_CAPACITY + DEFAULT_INITIAL_OVERFLOW_CAPACITY),
339 None
340 );
341
342 let mut iter = collection.into_iter();
343 for i in 0..(DEFAULT_MAX_INLINE_CAPACITY + DEFAULT_INITIAL_OVERFLOW_CAPACITY - 1) {
344 assert_eq!(iter.next(), Some(i as i32));
345 }
346 assert_eq!(iter.next(), None);
347 }
348
349 #[test]
350 fn test_exceeds_both_stack_and_initial_vec_capacities() {
351 let mut collection = GrowableArray::<i32>::new();
352 for i in 0..(DEFAULT_MAX_INLINE_CAPACITY + DEFAULT_INITIAL_OVERFLOW_CAPACITY + 5) {
353 collection.push(i as i32);
354 }
355 assert_eq!(
356 collection.len(),
357 DEFAULT_MAX_INLINE_CAPACITY + DEFAULT_INITIAL_OVERFLOW_CAPACITY + 5
358 );
359
360 for i in 0..(DEFAULT_MAX_INLINE_CAPACITY + DEFAULT_INITIAL_OVERFLOW_CAPACITY + 5) {
361 assert_eq!(collection.get(i), Some(&(i as i32)));
362 }
363 assert_eq!(
364 collection.get(DEFAULT_MAX_INLINE_CAPACITY + DEFAULT_INITIAL_OVERFLOW_CAPACITY + 5),
365 None
366 );
367
368 let mut iter = collection.into_iter();
369 for i in 0..(DEFAULT_MAX_INLINE_CAPACITY + DEFAULT_INITIAL_OVERFLOW_CAPACITY + 5) {
370 assert_eq!(iter.next(), Some(i as i32));
371 }
372 assert_eq!(iter.next(), None);
373 }
374}