@@ -44,17 +44,15 @@ impl RollingBuffer {
4444 }
4545
4646 /// Truncate the buffer, dropping the first `truncate_len` bytes.
47- pub fn truncate_to ( & mut self , truncate_len : usize , arena : & mut Arena ) {
47+ pub fn truncate_up_to_included ( & mut self , truncate_len : usize , arena : & mut Arena ) {
4848 if truncate_len >= self . range . len ( ) {
4949 self . clear ( arena) ;
5050 return ;
5151 }
5252 let num_pages = num_pages_required ( ( self . range . start + truncate_len) ..self . range . end ) ;
5353 assert ! ( num_pages <= self . page_ids. len( ) ) ;
5454 let num_pages_to_drop = self . page_ids . len ( ) - num_pages;
55- let new_start = self . range . start + truncate_len - num_pages_to_drop * PAGE_SIZE ;
56- let new_end = self . range . end - num_pages_to_drop * PAGE_SIZE ;
57- self . range = new_start..new_end;
55+ self . range . start = self . range . start + truncate_len;
5856 if num_pages_to_drop > 0 {
5957 for page_id in self . page_ids . drain ( ..( self . page_ids . len ( ) - num_pages) ) {
6058 arena. release_page ( page_id) ;
@@ -92,26 +90,35 @@ impl RollingBuffer {
9290 & ' slf self ,
9391 range : Range < usize > ,
9492 arena : & ' a Arena ,
95- ) -> impl Buf + ' slf {
96- let start = ( self . range . start + range. start ) . min ( self . range . end ) ;
97- let end = ( self . range . start + range. end ) . clamp ( start, self . range . end ) ;
98- let len = end - start;
99- let skip_pages = start / PAGE_SIZE ;
93+ ) -> PagesBuf < ' slf > {
94+ let Range { start, end} = range;
95+ assert ! ( start >= self . range. start) ;
96+ assert ! ( end <= self . range. end) ;
97+ if end <= start {
98+ return PagesBuf {
99+ arena,
100+ start_offset : 0 ,
101+ page_ids : & [ ] ,
102+ remaining_len : 0 ,
103+ } ;
104+ }
105+ let start_page_id = start / PAGE_SIZE ;
106+ let start_inner_page_id = self . range . start / PAGE_SIZE ;
107+ let skip_pages = start_page_id - start_inner_page_id;
100108 let start_offset = start % PAGE_SIZE ;
101109 PagesBuf {
102110 arena,
103111 start_offset,
104112 page_ids : & self . page_ids [ skip_pages..] ,
105- remaining_len : len ,
113+ remaining_len : end - start ,
106114 }
107- . take ( len)
108115 }
109116
110117 pub fn get_range_buf < ' slf , ' a : ' slf , R > (
111118 & ' slf self ,
112119 range_bounds : R ,
113120 arena : & ' a Arena ,
114- ) -> impl Buf + ' slf
121+ ) -> PagesBuf < ' slf >
115122 where
116123 R : RangeBounds < usize > + ' static ,
117124 {
@@ -123,69 +130,49 @@ impl RollingBuffer {
123130 let end = match range_bounds. end_bound ( ) {
124131 Bound :: Included ( pos) => pos + 1 ,
125132 Bound :: Excluded ( pos) => * pos,
126- Bound :: Unbounded => self . len ( ) ,
133+ Bound :: Unbounded => self . range . end
127134 } ;
128135 self . get_range_buf_aux ( start..end, arena)
129136 }
130-
131- pub fn get_range < ' slf , ' a : ' slf , R > (
132- & ' slf self ,
133- range_bounds : R ,
134- arena : & ' a Arena ,
135- ) -> impl Iterator < Item = & ' a [ u8 ] > + ' slf
136- where
137- R : RangeBounds < usize > + ' static ,
138- {
139- let start = match range_bounds. start_bound ( ) {
140- Bound :: Included ( pos) => * pos,
141- Bound :: Excluded ( pos) => pos + 1 ,
142- Bound :: Unbounded => 0 ,
143- } ;
144- let end = match range_bounds. end_bound ( ) {
145- Bound :: Included ( pos) => pos + 1 ,
146- Bound :: Excluded ( pos) => * pos,
147- Bound :: Unbounded => self . len ( ) ,
148- } ;
149- self . get_range_aux ( start..end, arena)
150- }
151-
152- pub fn get_range_aux < ' slf , ' a : ' slf > (
153- & ' slf self ,
154- range : Range < usize > ,
155- arena : & ' a Arena ,
156- ) -> impl Iterator < Item = & ' a [ u8 ] > + ' slf {
157- let start = ( self . range . start + range. start ) . min ( self . range . end ) ;
158- let end = ( self . range . start + range. end ) . clamp ( start, self . range . end ) ;
159- let mut remaining_len = end - start;
160- let skip_pages = start / PAGE_SIZE ;
161- let mut start_in_page = start % PAGE_SIZE ;
162- self . page_ids [ skip_pages..]
163- . iter ( )
164- . copied ( )
165- . map ( move |page_id| {
166- let page = & arena. page ( page_id) [ start_in_page..] ;
167- start_in_page = 0 ;
168- let page_len = page. len ( ) . min ( remaining_len) ;
169- remaining_len -= page_len;
170- & page[ ..page_len]
171- } )
172- . take_while ( |page| !page. is_empty ( ) )
173- }
174137}
175138
176- struct PagesBuf < ' a > {
139+ #[ derive( Clone , Copy ) ]
140+ pub struct PagesBuf < ' a > {
177141 arena : & ' a Arena ,
178142 page_ids : & ' a [ PageId ] ,
179143 start_offset : usize ,
180144 remaining_len : usize ,
181145}
182146
183- impl < ' a > Buf for PagesBuf < ' a > {
184- fn remaining ( & self ) -> usize {
185- self . remaining_len
147+ impl < ' a > std:: fmt:: Debug for PagesBuf < ' a > {
148+ fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
149+ let mut buf = self . clone ( ) ;
150+ let mut vec = Vec :: with_capacity ( self . remaining_len ) ;
151+ while buf. has_remaining ( ) {
152+ let chunk = buf. chunk ( ) ;
153+ vec. extend_from_slice ( chunk) ;
154+ buf. advance ( chunk. len ( ) ) ;
155+ }
156+ vec. as_slice ( ) . fmt ( f)
186157 }
158+ }
187159
188- fn chunk ( & self ) -> & [ u8 ] {
160+ impl < ' a > PagesBuf < ' a > {
161+ pub fn to_cow ( mut self ) -> std:: borrow:: Cow < ' a , [ u8 ] > {
162+ if self . page_ids . len ( ) <= 1 {
163+ let chunk = self . chunk_with_lifetime ( ) ;
164+ return std:: borrow:: Cow :: Borrowed ( chunk) ;
165+ }
166+ let mut buf = Vec :: with_capacity ( self . remaining_len ) ;
167+ while self . has_remaining ( ) {
168+ let chunk = self . chunk_with_lifetime ( ) ;
169+ buf. extend_from_slice ( chunk) ;
170+ self . advance ( chunk. len ( ) ) ;
171+ }
172+ std:: borrow:: Cow :: Owned ( buf)
173+ }
174+
175+ fn chunk_with_lifetime ( & self ) -> & ' a [ u8 ] {
189176 let Some ( first_page_id) = self . page_ids . first ( ) . copied ( ) else {
190177 return & [ ] ;
191178 } ;
@@ -197,6 +184,26 @@ impl<'a> Buf for PagesBuf<'a> {
197184 }
198185 }
199186
187+ }
188+
189+ impl < ' a > Buf for PagesBuf < ' a > {
190+ fn remaining ( & self ) -> usize {
191+ self . remaining_len
192+ }
193+
194+ fn chunk ( & self ) -> & [ u8 ] {
195+ // let Some(first_page_id) = self.page_ids.first().copied() else {
196+ // return &[];
197+ // };
198+ // let current_page = &self.arena.page(first_page_id)[self.start_offset..];
199+ // if current_page.len() > self.remaining_len {
200+ // ¤t_page[..self.remaining_len]
201+ // } else {
202+ // current_page
203+ // }
204+ self . chunk_with_lifetime ( )
205+ }
206+
200207 fn advance ( & mut self , mut cnt : usize ) {
201208 while cnt > 0 {
202209 if self . page_ids . is_empty ( ) {
@@ -235,16 +242,15 @@ mod tests {
235242 let mut arena = Arena :: default ( ) ;
236243 let text = b"hello happy tax payer" ;
237244 for truncate_len in 0 ..text. len ( ) {
238- let expected = & text[ truncate_len..] ;
239245 let mut rolling_buffer = RollingBuffer :: new ( ) ;
240246 rolling_buffer. extend_from_slice ( & b"hello" [ ..] , & mut arena) ;
241247 rolling_buffer. extend_from_slice ( & b" happy" [ ..] , & mut arena) ;
242248 rolling_buffer. extend_from_slice ( & b" tax payer" [ ..] , & mut arena) ;
243- rolling_buffer. truncate_to ( truncate_len, & mut arena) ;
244- for start in 0 ..expected . len ( ) {
245- for end in start..expected . len ( ) {
249+ rolling_buffer. truncate_up_to_included ( truncate_len, & mut arena) ;
250+ for start in truncate_len..text . len ( ) {
251+ for end in start..text . len ( ) {
246252 let bytes: Vec < u8 > = to_vec ( rolling_buffer. get_range_buf ( start..end, & arena) ) ;
247- assert_eq ! ( & expected [ start..end] , & bytes[ ..] ) ;
253+ assert_eq ! ( & text [ start..end] , & bytes[ ..] ) ;
248254 }
249255 }
250256 }
0 commit comments