Skip to content

Commit 0f8e59d

Browse files
committed
feat: add remove tuples
1 parent efe3a04 commit 0f8e59d

1 file changed

Lines changed: 83 additions & 0 deletions

File tree

src/page/paging.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)