1use std::{cell::RefCell, marker::PhantomData};
73
74#[doc(hidden)]
75#[cfg(feature = "serde")]
76pub use serde;
77
78pub trait Key: Clone + Copy + From<DefaultKey> + Into<DefaultKey> {
82 fn index(self) -> usize;
84}
85
86#[derive(Clone, Copy, Debug)]
88pub struct DefaultKey {
89 chunk_idx: u32,
90 value_idx: u32,
91}
92
93impl DefaultKey {
94 fn new(chunk_idx: usize, value_idx: usize) -> Self {
95 Self {
96 chunk_idx: u32::try_from(chunk_idx)
97 .expect("Overflow in chunk number. Too many chunks."),
98 value_idx: u32::try_from(value_idx)
99 .expect("Overflow in index number. Too many values."),
100 }
101 }
102
103 fn chunk_idx(self) -> usize {
104 self.chunk_idx as usize
105 }
106
107 fn value_idx(self) -> usize {
108 self.value_idx as usize
109 }
110}
111
112#[cfg(feature = "serde")]
113impl serde::Serialize for DefaultKey {
114 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
115 where
116 S: serde::Serializer,
117 {
118 self.value_idx.serialize(serializer)
119 }
120}
121
122#[cfg(feature = "serde")]
123impl<'de> serde::Deserialize<'de> for DefaultKey {
124 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
125 where
126 D: serde::Deserializer<'de>,
127 {
128 let value_idx = u32::deserialize(deserializer)?;
129 Ok(Self {
130 chunk_idx: 0,
131 value_idx,
132 })
133 }
134}
135
136impl Key for DefaultKey {
137 fn index(self) -> usize {
138 self.value_idx()
139 }
140}
141
142impl std::fmt::Display for DefaultKey {
143 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144 self.value_idx.fmt(f)
145 }
146}
147
148impl std::hash::Hash for DefaultKey {
149 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
150 self.value_idx.hash(state);
151 }
152}
153
154impl PartialEq for DefaultKey {
155 fn eq(&self, other: &Self) -> bool {
156 self.value_idx == other.value_idx
157 }
158}
159
160impl Eq for DefaultKey {}
161
162impl PartialOrd for DefaultKey {
163 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
164 self.value_idx.partial_cmp(&other.value_idx)
165 }
166}
167
168impl Ord for DefaultKey {
169 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
170 self.value_idx.cmp(&other.value_idx)
171 }
172}
173
174#[macro_export]
200macro_rules! new_key_types {
201 ($(#[$meta:meta])* $vis:vis struct $name:ident; $($other:tt)*) => {
202 $(#[$meta])*
203 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
204 #[repr(transparent)]
205 $vis struct $name($crate::DefaultKey);
206
207 const _: () = {
208 #[automatically_derived]
209 impl ::std::convert::From<$crate::DefaultKey> for $name {
210 fn from(key: $crate::DefaultKey) -> Self {
211 Self(key)
212 }
213 }
214
215 #[automatically_derived]
216 impl ::std::convert::From<$name> for $crate::DefaultKey {
217 fn from(key: $name) -> Self {
218 key.0
219 }
220 }
221
222 #[automatically_derived]
223 impl $crate::Key for $name {
224 fn index(self) -> usize {
225 self.0.index()
226 }
227 }
228
229 $crate::private_key_type_impl_serde!($name);
230 };
231
232 $crate::new_key_types!($($other)*);
233 };
234
235 () => {}
237}
238
239#[macro_export]
240#[doc(hidden)]
241#[cfg(not(feature = "serde"))]
242macro_rules! private_key_type_impl_serde {
243 ($name:ident) => {};
244}
245
246#[macro_export]
247#[doc(hidden)]
248#[cfg(feature = "serde")]
249macro_rules! private_key_type_impl_serde {
250 ($name:ident) => {
251 impl $crate::serde::Serialize for $name {
252 fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error>
253 where
254 S: $crate::serde::Serializer,
255 {
256 use $crate::serde::Serialize;
257 self.0.serialize(serializer)
258 }
259 }
260
261 impl<'de> $crate::serde::Deserialize<'de> for $name {
262 fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
263 where
264 D: $crate::serde::Deserializer<'de>,
265 {
266 use $crate::serde::Deserialize;
267 $crate::DefaultKey::deserialize(deserializer).map($name)
268 }
269 }
270 };
271}
272
273pub const DEFAULT_CAPACITY: usize = 32;
275
276const NORMAL_PAGE_SIZE: usize = 4096;
280const HUGE_PAGE_SIZE: usize = 2 * 1024 * 1024;
281
282#[derive(Clone, Debug)]
283struct Chunk<T> {
284 start: usize,
285 storage: Vec<T>,
286}
287
288impl<T> Chunk<T> {
289 fn new(start: usize, capacity: usize) -> Self {
290 Self {
291 start,
292 storage: Vec::with_capacity(capacity),
293 }
294 }
295}
296
297#[derive(Clone, Debug)]
298struct SharedVecInner<T> {
299 chunks: Vec<Chunk<T>>,
300}
301
302#[derive(Clone, Debug)]
304pub struct SharedVec<T, K: Key = DefaultKey> {
305 inner: RefCell<SharedVecInner<T>>,
306 _phantom_key: PhantomData<K>,
307}
308
309impl<T, K: Key> SharedVec<T, K> {
310 #[must_use]
312 pub fn new() -> Self {
313 Self::with_capacity(DEFAULT_CAPACITY)
314 }
315
316 #[must_use]
319 pub fn with_capacity(capacity: usize) -> Self {
320 let page_capacity = NORMAL_PAGE_SIZE / std::mem::size_of::<T>();
321 let capacity = std::cmp::max(page_capacity, capacity);
322 Self {
323 inner: RefCell::new(SharedVecInner {
324 chunks: vec![Chunk::new(0, capacity)],
325 }),
326 _phantom_key: PhantomData,
327 }
328 }
329
330 pub fn push(&self, value: T) -> (K, &T) {
332 self.push_with(|_| value)
333 }
334
335 pub fn push_with<F: FnOnce(K) -> T>(&self, func: F) -> (K, &T) {
346 self.try_push_with(func).unwrap_or_else(|func| {
347 self.grow(1);
348 match self.try_push_with(func) {
349 Ok(result) => result,
350 Err(_) => {
351 unreachable!("There should be space because we just grew the `SharedVec`.")
352 }
353 }
354 })
355 }
356
357 pub fn try_push(&self, value: T) -> Result<(K, &T), T> {
364 match self.try_push_with(|_| value) {
365 Ok(result) => Ok(result),
366 Err(func) => {
367 Err(func(K::from(DefaultKey::new(0, 0))))
371 }
372 }
373 }
374
375 pub fn try_push_with<F: FnOnce(K) -> T>(&self, func: F) -> Result<(K, &T), F> {
379 let mut inner = self.inner.borrow_mut();
380 let chunk_idx = inner.chunks.len() - 1;
381 let active = inner
382 .chunks
383 .last_mut()
384 .expect("There should be at least one chunk in the `SharedVec`.");
385 let offset = active.storage.len();
386 if offset < active.storage.capacity() {
387 let value_idx = active.start + offset;
388 let key = K::from(DefaultKey::new(chunk_idx, value_idx));
389 active.storage.push(func(key));
390 debug_assert!(offset < active.storage.len());
391 let reference = unsafe { &*active.storage.as_ptr().add(offset) };
396 Ok((key, reference))
397 } else {
398 Err(func)
399 }
400 }
401
402 pub fn len(&self) -> usize {
404 let inner = self.inner.borrow();
405 let active = inner
406 .chunks
407 .last()
408 .expect("There should be at least one chunk in the SharedVec.");
409 (active.start as usize) + active.storage.len()
410 }
411
412 pub fn is_empty(&self) -> bool {
414 self.len() == 0
415 }
416
417 pub fn get(&self, key: K) -> Option<&T> {
423 let key: DefaultKey = key.into();
424 self.raw_get(key.chunk_idx(), key.value_idx())
425 .or_else(|| self.get_slow(key))
426 }
427
428 #[cold]
430 fn get_slow(&self, key: DefaultKey) -> Option<&T> {
431 let key: DefaultKey = self.key_from_index(key.index())?.into();
432 self.raw_get(key.chunk_idx(), key.value_idx())
433 }
434
435 pub fn get_mut(&mut self, key: K) -> Option<&mut T> {
439 let key: DefaultKey = key.into();
440 match self.raw_get_mut(key.chunk_idx(), key.value_idx()) {
441 Ok(r) => Some(r),
442 Err(this) => this.get_mut_slow(key),
443 }
444 }
445
446 #[cold]
448 fn get_mut_slow(&mut self, key: DefaultKey) -> Option<&mut T> {
449 let key: DefaultKey = self.key_from_index(key.index())?.into();
450 self.raw_get_mut(key.chunk_idx(), key.value_idx()).ok()
451 }
452
453 pub fn key_from_index(&self, index: usize) -> Option<K> {
458 let inner = self.inner.borrow();
459 let chunk_idx = inner
460 .chunks
461 .binary_search_by_key(&index, |chunk| chunk.start)
462 .unwrap_or_else(|idx| idx - 1);
463 let chunk = &inner.chunks[chunk_idx];
464 if index - chunk.start < chunk.storage.len() {
465 Some(K::from(DefaultKey::new(chunk_idx, index)))
466 } else {
467 None
468 }
469 }
470
471 pub fn into_vec(self) -> Vec<T> {
475 let mut result = Vec::with_capacity(self.len());
476 let inner = self.inner.into_inner();
477 for mut chunk in inner.chunks {
478 result.append(&mut chunk.storage);
479 }
480 result
481 }
482
483 pub fn iter(&self) -> Iter<T, K> {
485 Iter {
486 sharedvec: self,
487 chunk_idx: 0,
488 value_idx: 0,
489 }
490 }
491
492 #[cold]
494 fn grow(&self, additional: usize) {
495 let mut inner = self.inner.borrow_mut();
496 let active = inner
497 .chunks
498 .last()
499 .expect("There should be at least one chunk in the SharedVec.");
500 debug_assert!(
501 active.storage.len() == active.storage.capacity(),
502 "The active chunk is not full yet?"
503 );
504 let start = active.start + active.storage.len();
505 let capacity = std::cmp::max(
506 additional,
507 std::cmp::min(
508 active.storage.capacity() * 2,
509 HUGE_PAGE_SIZE / std::mem::size_of::<T>(),
510 ),
511 );
512 inner.chunks.push(Chunk::new(start, capacity));
513 }
514
515 fn raw_get(&self, chunk: usize, index: usize) -> Option<&T> {
517 self.inner.borrow().chunks.get(chunk).and_then(|chunk| {
518 let offset = index - (chunk.start as usize);
519 if offset < chunk.storage.len() {
520 Some(unsafe { &*chunk.storage.as_ptr().add(offset) })
522 } else {
523 None
524 }
525 })
526 }
527
528 fn raw_get_mut(&mut self, chunk: usize, index: usize) -> Result<&mut T, &mut Self> {
534 let option = self
535 .inner
536 .borrow_mut()
537 .chunks
538 .get_mut(chunk)
539 .and_then(|chunk| {
540 let offset = index - (chunk.start as usize);
541 if offset < chunk.storage.len() {
542 Some(unsafe { &mut *(chunk.storage.as_mut_ptr().add(offset)) })
545 } else {
546 None
547 }
548 });
549 option.ok_or(self)
550 }
551}
552
553impl<T, K: Key> From<SharedVec<T, K>> for Vec<T> {
554 fn from(sharedvec: SharedVec<T, K>) -> Self {
555 sharedvec.into_vec()
556 }
557}
558
559impl<T, K: Key> From<Vec<T>> for SharedVec<T, K> {
560 fn from(chunk: Vec<T>) -> Self {
561 Self {
562 inner: RefCell::new(SharedVecInner {
563 chunks: vec![Chunk {
564 start: 0,
565 storage: chunk,
566 }],
567 }),
568 _phantom_key: PhantomData,
569 }
570 }
571}
572
573impl<T, K: Key> Default for SharedVec<T, K> {
574 fn default() -> Self {
575 Self::new()
576 }
577}
578
579impl<'p, T, K: Key> IntoIterator for &'p SharedVec<T, K> {
580 type Item = (K, &'p T);
581
582 type IntoIter = Iter<'p, T, K>;
583
584 fn into_iter(self) -> Self::IntoIter {
585 self.iter()
586 }
587}
588
589impl<T, K: Key> IntoIterator for SharedVec<T, K> {
590 type Item = (K, T);
591
592 type IntoIter = IntoIter<T, K>;
593
594 fn into_iter(self) -> Self::IntoIter {
595 IntoIter {
596 chunks: self.inner.into_inner().chunks.into_iter(),
597 active: None,
598 chunk_idx: 0,
599 value_idx: 0,
600 _phantom_key: PhantomData,
601 }
602 }
603}
604
605impl<T, K: Key> FromIterator<T> for SharedVec<T, K> {
606 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
607 let iter = iter.into_iter();
608 let (lower_bound, upper_bound) = iter.size_hint();
609 let capacity = upper_bound.unwrap_or(lower_bound);
610 let sharedvec = SharedVec::with_capacity(capacity);
611 for value in iter {
612 sharedvec.push(value);
613 }
614 sharedvec
615 }
616}
617
618impl<T, K: Key> std::ops::Index<K> for SharedVec<T, K> {
619 type Output = T;
620
621 fn index(&self, key: K) -> &Self::Output {
622 self.get(key)
623 .expect("No value has been stored for the given key.")
624 }
625}
626
627impl<T, K: Key> std::ops::IndexMut<K> for SharedVec<T, K> {
628 fn index_mut(&mut self, key: K) -> &mut Self::Output {
629 self.get_mut(key)
630 .expect("No value has been stored for the given key.")
631 }
632}
633
634#[cfg(feature = "serde")]
635impl<T: serde::Serialize, K: Key> serde::Serialize for SharedVec<T, K> {
636 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
637 where
638 S: serde::Serializer,
639 {
640 use serde::ser::SerializeSeq;
641 let mut seq = serializer.serialize_seq(Some(self.len()))?;
642 for (_, value) in self.iter() {
643 seq.serialize_element(value)?;
644 }
645 seq.end()
646 }
647}
648
649#[cfg(feature = "serde")]
650impl<'de, T: serde::Deserialize<'de>, K: Key> serde::Deserialize<'de> for SharedVec<T, K> {
651 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
652 where
653 D: serde::Deserializer<'de>,
654 {
655 Ok(Vec::deserialize(deserializer)?.into())
656 }
657}
658
659pub struct IntoIter<T, K: Key> {
661 chunks: std::vec::IntoIter<Chunk<T>>,
662 active: Option<std::vec::IntoIter<T>>,
663 chunk_idx: usize,
664 value_idx: usize,
665 _phantom_key: PhantomData<K>,
666}
667
668impl<T, K: Key> Iterator for IntoIter<T, K> {
669 type Item = (K, T);
670
671 fn next(&mut self) -> Option<Self::Item> {
672 loop {
673 if let Some(chunk) = &mut self.active {
674 if let Some(value) = chunk.next() {
675 let result = Some((
676 K::from(DefaultKey::new(self.chunk_idx, self.value_idx)),
677 value,
678 ));
679 self.value_idx += 1;
680 break result;
681 }
682 self.active = None;
683 self.chunk_idx += 1;
684 }
685 if let Some(chunk) = self.chunks.next() {
686 self.active = Some(chunk.storage.into_iter());
687 } else {
688 break None;
689 }
690 }
691 }
692}
693
694pub struct Iter<'p, T, K: Key> {
696 sharedvec: &'p SharedVec<T, K>,
697 chunk_idx: usize,
698 value_idx: usize,
699}
700
701impl<'p, T, K: Key> Iterator for Iter<'p, T, K> {
702 type Item = (K, &'p T);
703
704 fn next(&mut self) -> Option<Self::Item> {
705 loop {
706 let inner = self.sharedvec.inner.borrow();
707 if self.chunk_idx >= inner.chunks.len() {
708 break None;
709 }
710 if let Some(value) = self.sharedvec.raw_get(self.chunk_idx, self.value_idx) {
711 let result = Some((
712 K::from(DefaultKey::new(self.chunk_idx, self.value_idx)),
713 value,
714 ));
715 self.value_idx += 1;
716 break result;
717 }
718 self.chunk_idx += 1;
719 }
720 }
721
722 fn size_hint(&self) -> (usize, Option<usize>) {
723 (self.sharedvec.len(), None)
725 }
726
727 fn count(self) -> usize {
728 self.sharedvec.len() - self.value_idx
729 }
730}
731
732#[cfg(test)]
733mod tests {
734 use super::*;
735
736 #[test]
737 pub fn test_many() {
738 let sharedvec = SharedVec::<usize>::new();
739 let values = (0..10_000)
740 .map(|value| sharedvec.push(value))
741 .collect::<Vec<_>>();
742 for (expected, (key, _)) in values.iter().enumerate() {
743 assert_eq!(sharedvec[*key], expected)
744 }
745 for (expected, (key, value_ref)) in sharedvec.iter().enumerate() {
746 assert_eq!(key.index(), expected);
747 assert_eq!(*value_ref, expected);
748 assert_eq!(sharedvec[key], expected);
749 }
750 }
751}