6UVFCERMGSGNRWCVC3GWO5HWV6MSWE433DXBJVC7KRPP6LLJLCSQC
H3FVSQIQGFCFKCPXVOSFHP4OSUOBBURJESCZNGQTNDAAD3WQSBEQC
OTWDDJE7TTE73D6BGF4ZN6BH2NFUFLPME2VJ3CPALH463UGWLEIQC
OP6SVMOD2GTQ7VNJ4E5KYFG4MIYA7HBMXJTADALMZH4PY7OQRMZQC
6DMPXOAT5GQ3BQQOMUZN2GMBQPRA4IB7CCPHTQTIFGO3KWWAKF3QC
WS4ZQM4RMIHZ6XZKSDQJGHN5SSSWFL4H236USOPUA33S6RC53RFAC
QEUTVAZ4F4EJXRDMWDMYXF6XEDMX7YPVG4IIXEKPIR3K54E5W5OAC
DV4A2LR7Q5LAEGAQHLO34PZCHGJUHPAMRZFGT7GUFNKVQKPJNOYQC
EAAYH6BQWDK52EC5RG3BEZQU3FJPN5RRRN4U5KDKDVPKXBVJMNDAC
X3QVVQIS7B7L3XYZAWL3OOBUXOJ6RMOKQ45YMLLGAHYPEEKZ45ZAC
ONES3V466GLO5CXKRF5ENK7VFOQPWM3YXLVRGWB56V5SH3W7XNBQC
PXF3R6SVXJXN2NMLMWNY5OFV5QYVE2VZTLGIZDZVK5ZVLFTVSSWQC
UAQX27N4PI4LHEW6LSHJETIE5MV7JTEMPLTJFYUBMYVPC43H7VOAC
S4V4QZ5CF5LUDYWNR2UMWH6CHJDJ5FPGAZCQYM5GY7FJMJV4NN4QC
YWFYZNLZ5JHLIFVBRKZK4TSWVPROUPRG77ZB5M7UHT2OKPL4ZSRQC
unsafe fn read<T, K: Representable + ?Sized, V: Representable + ?Sized>(txn: &T, k: *const u8) -> (*const u8, *const u8) {
unsafe fn read<T, K: Representable + ?Sized, V: Representable + ?Sized>(
txn: &T,
k: *const u8,
) -> (*const u8, *const u8) {
#[derive(Debug)]
#[repr(C)]
pub struct Header {
n: u16,
data: u16,
crc: u32,
left_page: u64,
}
impl Header {
pub fn init(&mut self) {
self.n = (1u16).to_le(); // dirty page
self.data = 4096_u16.to_le();
self.crc = 0;
self.left_page = 0;
}
pub fn n(&self) -> u16 {
u16::from_le(self.n) >> 4
}
pub fn set_n(&mut self, n: u16) {
let dirty = u16::from_le(self.n) & 1;
self.n = ((n << 4) | dirty).to_le()
}
pub fn is_dirty(&self) -> bool {
u16::from_le(self.n) & 1 != 0
}
pub fn left_page(&self) -> u64 {
u64::from_le(self.left_page)
}
pub fn set_left_page(&mut self, l: u64) {
self.left_page = l.to_le()
}
pub fn data(&self) -> u16 {
u16::from_le(self.data)
}
pub fn set_data(&mut self, d: u16) {
self.data = d.to_le()
}
pub fn decr(&mut self, s: usize) {
self.left_page = (self.left_page() - s as u64).to_le();
}
pub fn set_occupied(&mut self, size: u64) {
self.left_page = ((self.left_page() & !0xfff) | size).to_le()
}
pub fn incr(&mut self, s: usize) {
self.left_page = (self.left_page() + s as u64).to_le();
}
pub fn is_leaf(&self) -> bool {
u64::from_le(self.left_page) <= 0xfff
}
pub fn clean(&mut self) {
self.n = (u16::from_le(self.n) & 0xfff).to_le()
}
}
pub const HDR: usize = core::mem::size_of::<Header>();
pub fn header<'a>(page: crate::Page<'a>) -> &'a Header {
unsafe { &*(page.data.as_ptr() as *const Header) }
}
pub fn header_mut(page: &mut crate::MutPage) -> &mut Header {
unsafe { &mut *(page.0.data as *mut Header) }
}
fn extra_size<K: Representable + ?Sized, V: Representable + ?Sized>() -> usize;
fn can_alloc<K: Representable + ?Sized, V: Representable + ?Sized>(hdr: &Header, size: usize) -> bool;
fn can_compact<K: Representable + ?Sized, V: Representable + ?Sized>(hdr: &Header, size: usize) -> bool;
fn alloc<K: Representable+?Sized, V: Representable+?Sized>(hdr: &mut Header, size: usize, align: usize) -> u16;
fn extra_size() -> usize;
fn can_alloc(hdr: &Header, size: usize) -> bool;
fn can_compact(hdr: &Header, size: usize) -> bool;
fn alloc(hdr: &mut Header, size: usize, align: usize) -> u16;
fn can_alloc<K: Representable + ?Sized, V: Representable + ?Sized>(hdr: &Header, size: usize) -> bool {
debug!("can_alloc: {:?} {:?} {:?}", hdr.n(), size, hdr.data());
HDR + (hdr.n() as usize) * 2 + 2 + size <= hdr.data() as usize
fn can_alloc(hdr: &Header, size: usize) -> bool {
(HDR as usize) + (hdr.n() as usize) * 2 + 2 + size < hdr.data() as usize
fn can_compact<K: Representable + ?Sized, V: Representable + ?Sized>(hdr: &Header, size: usize) -> bool {
debug!("can_compact: {:?} {:?}", hdr.left_page(), size);
HDR + ((hdr.left_page() & 0xfff) as usize) + 2 + size <= 4096
fn can_compact(hdr: &Header, size: usize) -> bool {
debug!(
"can_compact, internal: {:?} {:?} {:?}",
HDR,
hdr.left_page() & 0xfff,
size
);
(HDR as usize) + (hdr.n() as usize) * 2 + ((hdr.left_page() & 0xfff) as usize) + 2 + size
<= 4096
fn alloc<K: Representable+?Sized, V: Representable+?Sized>(hdr: &mut Header, size: usize, align: usize) -> u16 {
debug!("alloc = {:?} {:?}", hdr.data(), size);
let mut data = hdr.data() - size as u16;
data &= !((align - 1) as u16);
hdr.set_data(data);
fn alloc(hdr: &mut Header, size: usize, align: usize) -> u16 {
assert_eq!(size % align, 0);
let data = hdr.data();
hdr.set_data(data - size as u16);
fn can_compact<K: Representable + ?Sized, V: Representable + ?Sized>(hdr: &Header, size: usize) -> bool {
debug!("can_compact: {:?} {:?}", hdr.left_page(), size);
(HDR as usize) + ((hdr.left_page() & 0xfff) as usize) + 8 + size < 4096
fn can_compact(hdr: &Header, size: usize) -> bool {
debug!(
"can_compact, internal: {:?} {:?} {:?}",
HDR,
hdr.left_page() & 0xfff,
size
);
(HDR as usize) + (hdr.n() as usize) * 8 + ((hdr.left_page() & 0xfff) as usize) + 8 + size
<= 4096
fn alloc<K: Representable+?Sized, V: Representable+?Sized>(hdr: &mut Header, size: usize, align: usize) -> u16 {
let mut data = hdr.data() - size as u16;
data -= data % (align as u16);
hdr.set_data(data);
fn alloc(hdr: &mut Header, size: usize, align: usize) -> u16 {
assert_eq!(size % align, 0);
let data = hdr.data();
hdr.set_data(data - size as u16);
impl<
K: Representable + core::fmt::Debug,
V: Representable + core::fmt::Debug,
> super::BTreeMutPage<K, V> for Page<K, V>
impl<K: Representable + core::fmt::Debug, V: Representable + core::fmt::Debug>
super::BTreeMutPage<K, V> for Page<K, V>
fn extra_size<T, K: Representable, V: Representable>() -> usize;
fn can_alloc<T, K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool;
fn can_compact<T, K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool;
fn can_alloc<K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool;
fn can_compact<K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool;
fn extra_size<T, K: Representable, V: Representable>() -> usize {
0
}
fn can_alloc<T, K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool {
fn can_alloc<K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool {
fn extra_size<T, K: Representable, V: Representable>() -> usize {
8
}
fn can_alloc<T, K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool {
fn can_alloc<K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool {
fn can_compact<T, K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool {
(HDR as usize) + ((hdr.left_page() & 0xfff) as usize) + 8 + size < 4096
fn can_compact<K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool {
debug!(
"can_compact, internal: {:?} {:?} {:?}",
HDR,
hdr.left_page() & 0xfff,
size
);
(HDR as usize) + (hdr.n() as usize) * 8 + ((hdr.left_page() & 0xfff) as usize) + 8 + size
<= 4096
unsafe fn unchecked_current<'a, T: LoadPage>(txn: &T, p: Page<'a>, c: &Self::Cursor) -> (&'a K, &'a V, u64);
fn current<'a, T: LoadPage>(txn: &T, p: Page<'a>, c: &Self::Cursor) -> Option<(&'a K, &'a V, u64)> {
unsafe fn unchecked_current<'a, T: LoadPage>(
txn: &T,
p: Page<'a>,
c: &Self::Cursor,
) -> (&'a K, &'a V, u64);
fn current<'a, T: LoadPage>(
txn: &T,
p: Page<'a>,
c: &Self::Cursor,
) -> Option<(&'a K, &'a V, u64)> {
pub struct Concat<'a, K: Representable+?Sized, V: Representable+?Sized, P: BTreePage<K, V>>
{
pub struct Concat<'a, K: Representable + ?Sized, V: Representable + ?Sized, P: BTreePage<K, V>> {
fn modify_rc<
T: AllocPage + LoadPage,
K: Representable,
V: Representable,
P: BTreePage<K, V>,
>(
fn modify_rc<T: AllocPage + LoadPage, K: Representable, V: Representable, P: BTreePage<K, V>>(
pub struct PageCursor<K: Representable+?Sized, V: Representable+?Sized, P: BTreePage<K, V>>
{
pub struct PageCursor<K: Representable + ?Sized, V: Representable + ?Sized, P: BTreePage<K, V>> {
impl<'a, K: Representable+?Sized, V: Representable+?Sized, P: BTreePage<K, V>>
Cursor<K, V, P>
{
impl<'a, K: Representable + ?Sized, V: Representable + ?Sized, P: BTreePage<K, V>> Cursor<K, V, P> {
impl<K: Representable+?Sized, V: Representable+?Sized, P: BTreePage<K, V>>
Cursor<K, V, P>
{
impl<K: Representable + ?Sized, V: Representable + ?Sized, P: BTreePage<K, V>> Cursor<K, V, P> {
pub fn next<'a, T: LoadPage>(
&mut self,
txn: &'a mut T,
) -> Result<Option<(&K, &V)>, T::Error> {
pub fn next<'a, T: LoadPage>(&mut self, txn: &'a mut T) -> Result<Option<(&K, &V)>, T::Error> {
#[test]
fn sized_vs_unsized() {
env_logger::try_init().unwrap_or(());
let env = Env::new_anon(409_600_000, 1).unwrap();
let mut txn = Env::mut_txn_begin(&env).unwrap();
let now = std::time::SystemTime::now();
let mut db = create_db_::<MutTxn<&Env, ()>, u64, u64, P<u64, u64>>(&mut txn).unwrap();
let n = 22_014u64;
for i in 0..n {
debug!("=================== {:?}", i);
put(&mut txn, &mut db, &i, &i).unwrap();
}
debug!("===========================");
crate::debug::debug(&txn, &[&db], "debug0", true);
put(&mut txn, &mut db, &n, &n).unwrap();
crate::debug::debug(&txn, &[&db], "debug", true);
println!("sized: {:?}", now.elapsed());
let mut refs = BTreeMap::new();
add_refs(&txn, &db, &mut refs).unwrap();
let mut n = 0;
for (p, r) in refs.iter() {
if *r >= 2 {
error!("{:?} referenced twice", p);
n += 1
}
}
assert_eq!(n, 0);
/*
let mut db = create_db_::<MutTxn<&Env, ()>, u64, u64, UP<u64, u64>>(&mut txn).unwrap();
let now = std::time::SystemTime::now();
let n = 100_000u64;
for i in 0..n {
put(&mut txn, &mut db, &i, &i).unwrap();
}
println!("unsized: {:?}", now.elapsed());
*/
}