ab_core_primitives/pieces/
flat_pieces.rs1use crate::pieces::cow_bytes::CowBytes;
2use crate::pieces::{InnerPiece, Piece};
3use crate::segments::RecordedHistorySegment;
4use alloc::boxed::Box;
5use bytes::{Bytes, BytesMut};
6use core::ops::{Deref, DerefMut};
7use core::{fmt, slice};
8#[cfg(feature = "parallel")]
9use rayon::prelude::*;
10
11#[derive(Clone, PartialEq, Eq)]
13pub struct FlatPieces(CowBytes);
14
15impl fmt::Debug for FlatPieces {
16 #[inline]
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 f.debug_struct("FlatPieces").finish_non_exhaustive()
19 }
20}
21
22impl Deref for FlatPieces {
23 type Target = [InnerPiece];
24
25 #[inline]
26 fn deref(&self) -> &Self::Target {
27 let bytes = self.0.as_ref();
28 let pieces = unsafe {
31 slice::from_raw_parts(
32 bytes.as_ptr().cast::<[u8; const { Piece::SIZE }]>(),
33 bytes.len() / Piece::SIZE,
34 )
35 };
36 InnerPiece::slice_from_repr(pieces)
37 }
38}
39
40impl DerefMut for FlatPieces {
41 #[inline]
42 fn deref_mut(&mut self) -> &mut Self::Target {
43 let bytes = self.0.as_mut();
44 let pieces = unsafe {
47 slice::from_raw_parts_mut(
48 bytes.as_mut_ptr().cast::<[u8; const { Piece::SIZE }]>(),
49 bytes.len() / Piece::SIZE,
50 )
51 };
52 InnerPiece::slice_mut_from_repr(pieces)
53 }
54}
55
56impl FlatPieces {
57 #[inline]
59 pub fn new(piece_count: usize) -> Self {
60 Self(CowBytes::Owned(BytesMut::zeroed(piece_count * Piece::SIZE)))
61 }
62
63 #[inline]
71 pub fn pieces(&self) -> Box<dyn ExactSizeIterator<Item = Piece> + '_> {
72 match &self.0 {
73 CowBytes::Shared(bytes) => Box::new(
74 bytes
75 .as_chunks::<const { Piece::SIZE }>()
76 .0
77 .iter()
78 .map(|slice| Piece(CowBytes::Shared(bytes.slice_ref(slice)))),
79 ),
80 CowBytes::Owned(bytes) => Box::new(
81 bytes
82 .as_chunks::<const { Piece::SIZE }>()
83 .0
84 .iter()
85 .map(|slice| Piece(CowBytes::Shared(Bytes::copy_from_slice(slice)))),
86 ),
87 }
88 }
89
90 #[inline]
92 pub fn source_pieces(&self) -> impl ExactSizeIterator<Item = Piece> + '_ {
93 self.pieces().take(RecordedHistorySegment::NUM_RAW_RECORDS)
94 }
95
96 #[inline]
98 pub fn source(&self) -> impl ExactSizeIterator<Item = &'_ InnerPiece> + '_ {
99 self.iter().take(RecordedHistorySegment::NUM_RAW_RECORDS)
100 }
101
102 #[inline]
104 pub fn source_mut(&mut self) -> impl ExactSizeIterator<Item = &'_ mut InnerPiece> + '_ {
105 self.iter_mut()
106 .take(RecordedHistorySegment::NUM_RAW_RECORDS)
107 }
108
109 #[inline]
111 pub fn parity_pieces(&self) -> impl ExactSizeIterator<Item = Piece> + '_ {
112 self.pieces().skip(RecordedHistorySegment::NUM_RAW_RECORDS)
113 }
114
115 #[inline]
117 pub fn parity(&self) -> impl ExactSizeIterator<Item = &'_ InnerPiece> + '_ {
118 self.iter().skip(RecordedHistorySegment::NUM_RAW_RECORDS)
119 }
120
121 #[inline]
123 pub fn parity_mut(&mut self) -> impl ExactSizeIterator<Item = &'_ mut InnerPiece> + '_ {
124 self.iter_mut()
125 .skip(RecordedHistorySegment::NUM_RAW_RECORDS)
126 }
127
128 pub fn to_shared(self) -> Self {
134 Self(match self.0 {
135 CowBytes::Shared(bytes) => CowBytes::Shared(bytes),
136 CowBytes::Owned(bytes) => CowBytes::Shared(bytes.freeze()),
137 })
138 }
139
140 #[inline]
142 #[cfg(feature = "parallel")]
143 pub fn par_source(&self) -> impl IndexedParallelIterator<Item = &'_ InnerPiece> + '_ {
144 self.par_iter()
145 .take(RecordedHistorySegment::NUM_RAW_RECORDS)
146 }
147
148 #[inline]
150 #[cfg(feature = "parallel")]
151 pub fn par_source_mut(
152 &mut self,
153 ) -> impl IndexedParallelIterator<Item = &'_ mut InnerPiece> + '_ {
154 self.par_iter_mut()
155 .take(RecordedHistorySegment::NUM_RAW_RECORDS)
156 }
157
158 #[inline]
160 #[cfg(feature = "parallel")]
161 pub fn par_parity(&self) -> impl IndexedParallelIterator<Item = &'_ InnerPiece> + '_ {
162 self.par_iter()
163 .skip(RecordedHistorySegment::NUM_RAW_RECORDS)
164 }
165
166 #[inline]
168 #[cfg(feature = "parallel")]
169 pub fn par_parity_mut(
170 &mut self,
171 ) -> impl IndexedParallelIterator<Item = &'_ mut InnerPiece> + '_ {
172 self.par_iter_mut()
173 .skip(RecordedHistorySegment::NUM_RAW_RECORDS)
174 }
175}