various_data_file 0.9.1

Store a dainary datas in a file. Use mmap, optimize fragments on delete, and reference identical strings.
Documentation
use file_mmap::FileMmap;
use std::{
    io,
    mem::{size_of, ManuallyDrop},
};

use crate::DataAddress;

pub(super) struct FragmentGetResult {
    pub(super) fragment_id: u64,
    pub(super) string_addr: u64,
}
pub(super) struct Fragment {
    filemmap: FileMmap,
    list: ManuallyDrop<Box<DataAddress>>,
    record_count: ManuallyDrop<Box<u64>>,
}
const DATAADDRESS_SIZE: usize = size_of::<DataAddress>();
const COUNTER_SIZE: usize = size_of::<u64>();
const INIT_SIZE: usize = COUNTER_SIZE + DATAADDRESS_SIZE;
impl Fragment {
    pub fn new(path: &str) -> io::Result<Self> {
        let mut filemmap = FileMmap::new(path)?;
        if filemmap.len()? == 0 {
            filemmap.set_len(INIT_SIZE as u64)?;
        }
        let list = unsafe { filemmap.offset(COUNTER_SIZE as isize) } as *mut DataAddress;
        let counter = filemmap.as_ptr() as *mut u64;
        Ok(Fragment {
            filemmap,
            list: ManuallyDrop::new(unsafe { Box::from_raw(list) }),
            record_count: ManuallyDrop::new(unsafe { Box::from_raw(counter) }),
        })
    }
    pub fn insert(&mut self, ystr: &DataAddress) -> io::Result<u64> {
        **self.record_count += 1;
        let size = INIT_SIZE + DATAADDRESS_SIZE * **self.record_count as usize;
        if self.filemmap.len()? < size as u64 {
            self.filemmap.set_len(size as u64)?;
        }
        unsafe {
            *(&mut **self.list as *mut DataAddress).offset(**self.record_count as isize) =
                ystr.clone();
        }
        Ok(**self.record_count)
    }
    pub unsafe fn release(&mut self, row: u64, len: usize) {
        let mut s = &mut *(&mut **self.list as *mut DataAddress).offset(row as isize);
        s.offset += len as i64;
        s.len -= len as u64;

        if s.len == 0 && row == **self.record_count {
            **self.record_count -= 1;
        }
    }
    pub fn search_blank(&self, len: usize) -> Option<FragmentGetResult> {
        if **self.record_count == 0 {
            None
        } else {
            for i in -(**self.record_count as isize)..0 {
                let index = -i;
                let s = unsafe { &*(&**self.list as *const DataAddress).offset(index) };
                if s.len as usize >= len {
                    return Some(FragmentGetResult {
                        fragment_id: index as u64,
                        string_addr: s.offset as u64,
                    });
                }
            }
            None
        }
    }
}