Q7DRIBBRE4MNG4NP3PVIXAJF5PQYLFWYIVK2O4VVLEO6XY3BOSFQC
T73WR2BX2QDQ6APOREBXUKNH52FDLJNBGWPQUYB2TAF2PT7XCL2AC
MSRWB47YP6L5BVTS53QQPBOHY5SXTSTR5KD6IIF35UWCTEUOCQWQC
7P43FPFAXMDYUIQV7U2DGPN4UI3RNHYFWEUEA22UBDSQTYBJRAQQC
H3FVSQIQGFCFKCPXVOSFHP4OSUOBBURJESCZNGQTNDAAD3WQSBEQC
OFINGD26ZWCRDVVDI2ZIBLMHXKEMJA6MRNLANJYUHQPIJLPA7J2AC
XEU2QVLCHPYOOD4TQIPEEVYOVSFMKFPLJYWEJYXYJAZ7S54KWDZAC
6UVFCERMGSGNRWCVC3GWO5HWV6MSWE433DXBJVC7KRPP6LLJLCSQC
KX3WVNZW5KHVEH6EOQTZ4RBEFFJ3SGF5I467X3JWZ74PURRK4HVAC
LROAI3NBBSCU4T2YA6EHJYKKKL75AU5A7C7WIRCGIQ56S6HPLRXQC
AOX2XQISHGWNNAFBYRN44Q6AWG7H5DPBK5YMFHK42HQNZ2TMHEJQC
WS4ZQM4RMIHZ6XZKSDQJGHN5SSSWFL4H236USOPUA33S6RC53RFAC
OP6SVMOD2GTQ7VNJ4E5KYFG4MIYA7HBMXJTADALMZH4PY7OQRMZQC
DV4A2LR7Q5LAEGAQHLO34PZCHGJUHPAMRZFGT7GUFNKVQKPJNOYQC
EAAYH6BQWDK52EC5RG3BEZQU3FJPN5RRRN4U5KDKDVPKXBVJMNDAC
OTWDDJE7TTE73D6BGF4ZN6BH2NFUFLPME2VJ3CPALH463UGWLEIQC
QEUTVAZ4F4EJXRDMWDMYXF6XEDMX7YPVG4IIXEKPIR3K54E5W5OAC
X3QVVQIS7B7L3XYZAWL3OOBUXOJ6RMOKQ45YMLLGAHYPEEKZ45ZAC
UAQX27N4PI4LHEW6LSHJETIE5MV7JTEMPLTJFYUBMYVPC43H7VOAC
// We're never in a leaf if we're doing this.
let new = Self::del(txn, page, mutable, c, l)?;
Self::put(txn, new.0, true, c, k0, v0, k1v1, l, r)
assert!(c.cur >= 0);
assert!(!c.is_leaf);
put::put::<_, _, _, Internal>(txn, page, mutable, true, c.cur as usize, k0, v0, k1v1, l, r)
let off = (page.data.add(HDR) as *mut u64).offset(n - 1);
*off = (l | (u64::from_le(*off) & 0xfff)).to_le();
if l > 0 {
let off = (new.0.data.add(HDR) as *mut u64).offset(n - 1);
*off = (l | (u64::from_le(*off) & 0xfff)).to_le();
} else {
let hdr = header(page.as_page());
let left = hdr.left_page() & !0xfff;
*(new.0.data.add(HDR) as *mut u64).offset(-1) = left.to_le();
}
return Ok(Op::Put(Put::Ok(Ok {
page: Self::del(
txn,
m.modified.page,
m.modified.mutable,
&m.modified.c1,
m.modified.l,
)?,
freed: 0,
})));
let (page, freed) = Self::del(
txn,
m.modified.page,
m.modified.mutable,
&m.modified.c1,
m.modified.l,
)?;
return Ok(Op::Put(Put::Ok(Ok { page, freed })));
unsafe {
if c.is_leaf {
2 + entry_size::<K, V>(page.data.as_ptr().add(u16::from_le(
*(page.data.as_ptr().add(HDR) as *const u16).offset(c.cur),
) as usize))
} else {
8 + entry_size::<K, V>(page.data.as_ptr().add(
(u64::from_le(*(page.data.as_ptr().add(HDR) as *const u64).offset(c.cur))
& 0xfff) as usize,
))
}
if c.is_leaf {
Leaf::current_size::<K, V>(page, c.cur)
} else {
Internal::current_size::<K, V>(page, c.cur)
)?
};
let lc = PageCursor::after(m.modified.page.as_page());
if let Put::Ok(Ok { page, freed }) =
<Page<K, V>>::put(txn, new_left.0, true, &lc, m.mid.0, m.mid.1, None, 0, rl)?
{
)?;
new_left = page
page
};
let lc = PageCursor::after(m.modified.page.as_page());
if let Put::Ok(Ok { page, freed }) =
<Page<K, V>>::put(txn, new_left.0, true, &lc, m.mid.0, m.mid.1, None, 0, rl)?
{
assert_eq!(page.0.offset, new_left.0.offset);
assert_eq!(freed, 0);
let (new_right, k, v): (_, &K, &V) = unsafe {
(
<Page<K, V>>::del(txn, m.other, m.other_is_mutable, &rc, r)?,
core::mem::transmute(k),
core::mem::transmute(v),
)
};
if new_right.0.offset != m.other.offset {
let (new_right, freed) = <Page<K, V>>::del(txn, m.other, m.other_is_mutable, &rc, r)?;
let (k, v): (&K, &V) = unsafe { (core::mem::transmute(k), core::mem::transmute(v)) };
if freed > 0 {
)?
};
if let Put::Ok(Ok { page, freed }) =
<Page<K, V>>::put(txn, new_right.0, true, &rc, m.mid.0, m.mid.1, None, r0, rl)?
{
)?;
let new_left = <Page<K, V>>::del(txn, m.other, m.other_is_mutable, &lc, 0)?;
if new_left.0.offset != m.other.offset {
let (new_left, freed) = <Page<K, V>>::del(txn, m.other, m.other_is_mutable, &lc, 0)?;
if freed > 0 {
if replace {
assert!(!hdr.is_leaf());
unsafe {
let p = page.0.data;
let ptr = p.add(HDR + n as usize * 8) as *mut u64;
let off = (u64::from_le(*ptr) & 0xfff) as usize;
let kv_ptr = p.add(off);
let size = entry_size::<K, V>(kv_ptr);
core::ptr::copy(ptr.offset(1), ptr, hdr.n() as usize - n as usize - 1);
header_mut(&mut page).decr(size)
}
}
(HDR as usize) + (hdr.n() as usize) * 2 + ((hdr.left_page() & 0xfff) as usize) + 2 + size
<= PAGE_SIZE
(HDR as isize) + (hdr.n() as isize) * 2 + ((hdr.left_page() & 0xfff) as isize) + 2 + size
<= PAGE_SIZE as isize
// We're never in a leaf if we're doing this.
let new = Self::del(txn, page, mutable, c, l)?;
Self::put(txn, new.0, true, c, k0, v0, k1v1, l, r)
if r == 0 {
put::put::<_, _, _, Leaf>(txn, page, mutable, true, c.cur as usize, k0, v0, k1v1, 0, 0)
} else {
put::put::<_, _, _, Internal>(
txn,
page,
mutable,
true,
c.cur as usize,
k0,
v0,
k1v1,
l,
r,
)
}
let off = (page.data.add(HDR) as *mut u64).offset(n - 1);
*off = (l | (u64::from_le(*off) & 0xfff)).to_le();
debug!("offset {:?}", n);
if l > 0 {
let off = (new.0.data.add(HDR) as *mut u64).offset(n - 1);
*off = (l | (u64::from_le(*off) & 0xfff)).to_le();
debug!("set offset {:?} {:?}", *off, l);
} else {
let hdr = header(page.as_page());
let left = hdr.left_page() & !0xfff;
*(new.0.data.add(HDR) as *mut u64).offset(-1) = left.to_le();
}
return Ok(Op::Put(Put::Ok(Ok {
page: Self::del(
txn,
m.modified.page,
m.modified.mutable,
&m.modified.c1,
m.modified.l,
)?,
freed: 0,
})));
let (page, freed) = Self::del(
txn,
m.modified.page,
m.modified.mutable,
&m.modified.c1,
m.modified.l,
)?;
return Ok(Op::Put(Put::Ok(Ok { page, freed })));
unsafe {
(
<Page<K, V>>::del(txn, m.other, m.other_is_mutable, &rc, r)?,
core::mem::transmute(k),
core::mem::transmute(v),
)
let (page, freed) = <Page<K, V>>::del(txn, m.other, m.other_is_mutable, &rc, r)?;
if freed > 0 {
let hdr = &*header(m.other.as_page());
let b = if hdr.is_dirty() { 1 } else { 0 };
freed_[1] = freed | b;
)?
};
if let Put::Ok(Ok { page, freed }) =
<Page<K, V>>::put(txn, new_right.0, true, &rc, m.mid.0, m.mid.1, None, r0, rl)?
{
)?;
let new_left = <Page<K, V>>::del(txn, m.other, m.other_is_mutable, &lc, 0)?;
if new_left.0.offset != m.other.offset {
let (new_left, freed) = <Page<K, V>>::del(txn, m.other, m.other_is_mutable, &lc, 0)?;
if freed > 0 {
if replace {
assert!(!hdr.is_leaf());
unsafe {
let p = page.0.data;
let ptr = p.add(HDR + n as usize * 8) as *mut u64;
let off = (u64::from_le(*ptr) & 0xfff) as usize;
let kv_ptr = p.add(off);
let size = entry_size::<K, V>(kv_ptr);
core::ptr::copy(ptr.offset(1), ptr, hdr.n() as usize - n as usize - 1);
let hdr = header_mut(&mut page);
hdr.decr(size);
hdr.set_n(hdr.n() - 1);
}
}
let page = Self::del(txn, m.page, m.mutable, &m.c1, m.l)?;
Ok(Put::Ok(Ok {
freed: if page.0.offset != m.page.offset {
m.page.offset
} else {
0
},
page,
}))
let (page, freed) = Self::del(txn, m.page, m.mutable, &m.c1, m.l)?;
Ok(Put::Ok(Ok { freed, page }))
let mut values = Vec::with_capacity(n as usize);
for i in 0..n {
put(&mut txn, &mut db, &i, &i).unwrap();
if i != i0 {
values.push(i);
}
}
let db2 = fork_db(&mut txn, &db).unwrap();
del(&mut txn, &mut db, &i0, None).unwrap();
assert_eq!(
btree::iter(&txn, &db, None)
.unwrap()
.map(|kv| *kv.unwrap().0)
.collect::<Vec<_>>(),
values
);
}
#[test]
pub fn del_internal() {
env_logger::try_init().unwrap_or(());
let env = Env::new_anon(409600000, 1).unwrap();
let mut txn = Env::mut_txn_begin(&env).unwrap();
let mut db: Db<u64, u64> = create_db(&mut txn).unwrap();
let n = 300 as u64;
let i0 = 127 as u64;