Fork channel

Create a new channel as a copy of main.

Rename channel

Rename main to:

Delete channel

Delete main? This cannot be undone.

main.rs
mod skiplist;
fn main() {
    let mut page = [0u8; 4096];
    let mut total_put = std::time::Duration::from_secs(0);
    let mut total_lookup = std::time::Duration::from_secs(0);
    for _ in 0..1_000_000 {
        let mut p = MutPage {
            p: page.as_mut_ptr()
        };
        unsafe {
            p.init();
            let now = std::time::SystemTime::now();
            for i in 0..170 {
                p.put(i * i, i * i * i, 0);
            }
            total_put += now.elapsed().unwrap();
            let now = std::time::SystemTime::now();
            for i in 0..170 {
                let v = p.lookup(i * i);
                assert_eq!(v, Some(i * i * i));
            }
            total_lookup += now.elapsed().unwrap();
        }
    }
    println!("linked-list: {:?} {:?}", total_put, total_lookup);
    let mut total_put = std::time::Duration::from_secs(0);
    let mut total_lookup = std::time::Duration::from_secs(0);
    for _ in 0..1_000_000 {
        let mut p = MutPage {
            p: page.as_mut_ptr()
        };
        unsafe {
            p.init();
            for i in 0..170 {
                let now = std::time::SystemTime::now();
                p.put_ord(i * i, i * i * i, 0);
                total_put += now.elapsed().unwrap();
            }
            let now = std::time::SystemTime::now();
            for i in 0..170 {
                let v = p.lookup_ord(i * i);
                assert_eq!(v, Some(i * i * i));
            }
            total_lookup += now.elapsed().unwrap();
        }
    }
    println!("ordered-vec: {:?} {:?}", total_put, total_lookup);

    let mut rng = 0;
    let mut total_put = std::time::Duration::from_secs(0);
    let mut total_lookup = std::time::Duration::from_secs(0);
    for _ in 0..1_000_000 {
        let mut p = MutPage {
            p: page.as_mut_ptr()
        };
        p.init_skiplist_page();
        let mut c = skiplist::SkipCursor::new();
        let now = std::time::SystemTime::now();
        for i in 0..100 {
            c.reset();
            skiplist::set_cursor(&p, &mut c, i * i);
            skiplist::skiplist_insert_after_cursor(&mut p, &mut rng, &mut c, i*i, i*i*i, 0);
        }
        total_put += now.elapsed().unwrap();
        let now = std::time::SystemTime::now();
        for i in 0..100 {
            c.reset();
            skiplist::set_cursor(&p, &mut c, i * i);
        }
        total_lookup += now.elapsed().unwrap();
    }
    println!("skip-list: {:?} {:?}", total_put, total_lookup);
}

struct MutPage {
    p: *mut u8,
}

impl MutPage {
    pub unsafe fn init(&mut self) {
        let p = self.p as *mut u64;
        *(p.offset(1)) = 0;
        self.set_size(16);
        self.set_first_free(16);
    }
    pub fn size(&self) -> u16 {
        unsafe {
            u16::from_le(*(self.p as *mut u16).offset(2))
        }
    }
    pub fn set_size(&self, n: u16) {
        unsafe {
            *(self.p as *mut u16).offset(2) = n.to_le()
        }
    }
    pub fn set_first_free(&self, n: u16) {
        unsafe {
            *(self.p as *mut u16).offset(3) = n.to_le()
        }
    }
    pub fn first_free(&self) -> u16 {
        unsafe {
            u16::from_le(*(self.p as *mut u16).offset(3))
        }
    }

    pub unsafe fn put(&mut self, k0: u64, v0: u64, rr: u64) {
        let rn0 = u64::from_le(*self.offset(8));
        let mut n0 = (rn0 & 0xfff) as isize;
        let mut i = n0;
        n0 = 8;
        while i != 0 {
            let k = u64::from_le(*self.offset(i + 8));
            if k0 < k {
                let rn = u64::from_le(*self.offset(i));
                let n = (rn & 0xfff) as isize;
                n0 = i;
                i = n
            } else if k0 == k {
                return
            } else {
                // Insérer ici.
                let off = self.alloc(24);
                let r0 = *self.offset(n0) & !0xfff;
                *self.offset(n0) = r0 | (off as u64);
                *self.offset(off as isize) = rr | (i as u64);
                *self.offset(off as isize + 8) = k0.to_le();
                *self.offset(off as isize + 16) = v0.to_le();
                return
            }
        }
        let off = self.alloc(24);
        let r0 = *self.offset(n0) & !0xfff;
        *self.offset(n0) = r0 | (off as u64);
        *self.offset(off as isize) = rr.to_le();
        *self.offset(off as isize + 8) = k0.to_le();
        *self.offset(off as isize + 16) = v0.to_le();
    }

    unsafe fn offset(&self, i: isize) -> *mut u64 {
        self.p.offset(i) as *mut u64
    }

    pub fn alloc(&mut self, n: u16) -> u16 {
        self.set_size(self.size() + n);
        let result = self.first_free();
        assert!(result + n <= 4096);
        self.set_first_free(result + n);
        result
    }

    pub unsafe fn lookup(&self, k0: u64) -> Option<u64> {
        let rn0 = u64::from_le(*self.offset(8));
        let mut i = (rn0 & 0xfff) as isize;
        while i != 0 {
            let k = u64::from_le(*self.offset(i + 8));
            if k0 < k {
                let rn = u64::from_le(*self.offset(i));
                let n = (rn & 0xfff) as isize;
                i = n
            } else if k0 == k {
                return Some(u64::from_le(*self.offset(i + 16)))
            } else {
                return None
            }
        }
        None
    }
}


impl MutPage {
    pub unsafe fn lookup_ord_(&mut self, k0: u64) -> (u16, u16) {
        let mut a = 0;
        let mut b = (self.size() - 16) / 24;
        while a < b {
            let mid = (a + b) / 2;
            let k = *(self.p.offset((16 + mid * 24 + 8) as isize) as *mut u64);
            if k < k0 {
                if a == mid {
                    break
                }
                a = mid
            } else if k == k0 {
                a = mid;
                b = mid;
                break
            } else {
                b = mid
            }
        }
        (16 + a * 24, 16 + b * 24)
    }
    pub unsafe fn lookup_ord(&mut self, k0: u64) -> Option<u64> {
        let (off, _) = self.lookup_ord_(k0);
        let off = off as isize;
        let k = *(self.p.offset(off + 8) as *mut u64);
        if k == k0 {
            Some(*(self.p.offset(off + 16) as *mut u64))
        } else {
            None
        }
    }
    pub unsafe fn put_ord(&mut self, k0: u64, v0: u64, _rr: u64) {
        let size = self.size();
        let (_, off) = self.lookup_ord_(k0);
        if size > off {
            std::ptr::copy(self.p.offset(off as isize), self.p.offset(off as isize + 24), (size - off) as usize);
        }
        *self.offset(off as isize + 8) = k0.to_le();
        *self.offset(off as isize + 16) = v0.to_le();
        self.set_size(size + 24);
    }

}