@@ -157,6 +157,72 @@ impl<'b, T: ValueTrait> Paging<'b, T> {
157157 Ok ( ( tuple_pointer_offset, page_number) )
158158 }
159159
160+ pub fn remove ( & mut self , index : usize ) -> Result < ( ) > {
161+ let tuple_pointer = self . page . read ( index as LocationOffset ) . unwrap ( ) ;
162+
163+ if tuple_pointer. is_none ( ) {
164+ return Ok ( ( ) ) ;
165+ }
166+
167+ let ( mut data, tuple_pointer) = tuple_pointer. unwrap ( ) ;
168+
169+ // if is not overflow item, we can delete it directly
170+ if tuple_pointer
171+ . metadata
172+ . not_has ( TuplePointerFlags :: OverflowItem )
173+ {
174+ self . page . delete ( index as LocationOffset ) ?;
175+ return Ok ( ( ) ) ;
176+ }
177+
178+ loop {
179+ // if is overflow item, we need to read the overflow page
180+ let ( overflow, _) = data. split_at ( OVERFLOW_SIZE ) ;
181+
182+ let overflow = Overflow :: from_bytes ( overflow) ;
183+ let mut page = self . block . read_page ( overflow. page_number as u64 ) . unwrap ( ) ;
184+
185+ let offset = overflow. offset as usize ;
186+
187+ // read the overflow data
188+ let overflow_data = page. read ( offset as LocationOffset ) . unwrap ( ) ;
189+ if overflow_data. is_none ( ) {
190+ return Ok ( ( ) ) ;
191+ }
192+
193+ let ( overflow_data, tuple_pointer) = overflow_data. unwrap ( ) ;
194+
195+ // delete the overflow data
196+ page. delete ( offset as LocationOffset ) ?;
197+ self . block
198+ . write_page ( overflow. page_number as u64 , & page)
199+ . unwrap ( ) ;
200+
201+ // if the overflow page is empty, we can delete it
202+ if page. is_empty ( ) {
203+ self . block . header . free_page_overflow = overflow. page_number ;
204+ self . block . persist_header ( ) . unwrap ( ) ;
205+ }
206+
207+ self . block
208+ . write_page ( self . page_number as u64 , & self . page )
209+ . unwrap ( ) ;
210+
211+ // if the overflow data is not an overflow item, we can break
212+ if tuple_pointer
213+ . metadata
214+ . not_has ( TuplePointerFlags :: OverflowItem )
215+ {
216+ break ;
217+ }
218+
219+ // extend the raw data with the overflow data
220+ data = overflow_data;
221+ }
222+
223+ Ok ( ( ) )
224+ }
225+
160226 pub fn len ( & self ) -> u16 {
161227 self . page . len ( )
162228 }
@@ -271,4 +337,21 @@ mod paging_tests {
271337 let read_value2 = paging2. get ( 0 ) . unwrap ( ) . unwrap ( ) ;
272338 assert_eq ! ( read_value2, value2) ;
273339 }
340+
341+ #[ test]
342+ fn remove_overflow_data ( ) {
343+ let mut block = Block :: new ( "test_data/paging/remove_overflow_data.db" ) . unwrap ( ) ;
344+ let page = PageBuilder :: new ( ) . build ( ) . unwrap ( ) ;
345+ block. write_new_page ( & page) . unwrap ( ) ;
346+
347+ let mut paging = Paging :: < String > :: new ( & mut block, 0 , page) ;
348+
349+ let value = "Hello, world!" . repeat ( 1000 ) ;
350+ paging. write ( value. clone ( ) ) . unwrap ( ) ;
351+
352+ paging. remove ( 0 ) . unwrap ( ) ;
353+
354+ let read_value = paging. get ( 0 ) . unwrap ( ) ;
355+ assert_eq ! ( read_value, None ) ;
356+ }
274357}
0 commit comments