extern crate alloc;
use remdb::types::RecordHeader;
use remdb::{database, table, Result};
static mut DB_MEMORY: [u8; 2097152] = [0u8; 2097152];
table!(
TEST_TABLE,
100, primary_key: id,
secondary_index: name,
fields: {
id: u64,
name: str(20),
value: u32
}
);
database!(
TEST_DB,
tables: [TEST_TABLE]
);
fn main() -> Result<()> {
struct SimplePlatform;
impl remdb::platform::Platform for SimplePlatform {
fn get_timestamp(&self) -> u64 {
0
}
fn get_timestamp_us(&self) -> u64 {
0
}
fn spin_lock(&self, lock: &mut u32) {
while unsafe {
core::sync::atomic::AtomicU32::from_ptr(lock as *mut u32)
.compare_exchange(
0,
1,
core::sync::atomic::Ordering::Acquire,
core::sync::atomic::Ordering::Relaxed,
)
.is_err()
} {
core::hint::spin_loop();
}
}
fn spin_unlock(&self, lock: &mut u32) {
unsafe {
core::sync::atomic::AtomicU32::from_ptr(lock as *mut u32)
.store(0, core::sync::atomic::Ordering::Release);
}
}
fn compiler_barrier(&self) {
core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst);
}
fn full_memory_barrier(&self) {
core::sync::atomic::fence(core::sync::atomic::Ordering::SeqCst);
}
fn memcpy(&self, dest: *mut u8, src: *const u8, size: usize) {
unsafe {
core::ptr::copy_nonoverlapping(src, dest, size);
}
}
fn memset(&self, dest: *mut u8, value: u8, size: usize) {
unsafe {
core::ptr::write_bytes(dest, value, size);
}
}
fn delay_ms(&self, ms: u32) {
let start = std::time::Instant::now();
while start.elapsed().as_millis() < ms as u128 {
core::hint::spin_loop();
}
}
fn delay_us(&self, us: u32) {
let start = std::time::Instant::now();
while start.elapsed().as_micros() < us as u128 {
core::hint::spin_loop();
}
}
fn file_open(
&self,
path: &str,
mode: remdb::platform::FileMode,
) -> remdb::platform::FileResult<remdb::platform::FileHandle> {
use std::fs::OpenOptions;
let file = match mode {
remdb::platform::FileMode::Read => OpenOptions::new().read(true).open(path),
remdb::platform::FileMode::Write => OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(path),
remdb::platform::FileMode::ReadWrite => OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(path),
remdb::platform::FileMode::Append => {
OpenOptions::new().append(true).create(true).open(path)
}
};
match file {
Ok(file) => {
let file_ptr = Box::into_raw(Box::new(file)) as remdb::platform::FileHandle;
Ok(file_ptr)
}
Err(_) => Err(()),
}
}
fn file_close(
&self,
handle: remdb::platform::FileHandle,
) -> remdb::platform::FileResult<()> {
let _file = unsafe { Box::from_raw(handle as *mut std::fs::File) };
Ok(())
}
fn file_write(
&self,
handle: remdb::platform::FileHandle,
buffer: *const u8,
size: usize,
) -> remdb::platform::FileResult<usize> {
use std::io::Write;
let file = unsafe { &mut *(handle as *mut std::fs::File) };
let slice = unsafe { std::slice::from_raw_parts(buffer, size) };
match file.write(slice) {
Ok(n) => Ok(n),
Err(_) => Err(()),
}
}
fn file_read(
&self,
handle: remdb::platform::FileHandle,
buffer: *mut u8,
size: usize,
) -> remdb::platform::FileResult<usize> {
use std::io::Read;
let file = unsafe { &mut *(handle as *mut std::fs::File) };
let slice = unsafe { std::slice::from_raw_parts_mut(buffer, size) };
match file.read(slice) {
Ok(n) => Ok(n),
Err(_) => Err(()),
}
}
fn file_seek(
&self,
handle: remdb::platform::FileHandle,
offset: i64,
whence: remdb::platform::SeekWhence,
) -> remdb::platform::FileResult<u64> {
use std::io::Seek;
let file = unsafe { &mut *(handle as *mut std::fs::File) };
let seek_from = match whence {
remdb::platform::SeekWhence::SeekSet => std::io::SeekFrom::Start(offset as u64),
remdb::platform::SeekWhence::SeekCur => std::io::SeekFrom::Current(offset),
remdb::platform::SeekWhence::SeekEnd => std::io::SeekFrom::End(offset),
};
match file.seek(seek_from) {
Ok(pos) => Ok(pos),
Err(_) => Err(()),
}
}
fn file_remove(&self, path: &str) -> remdb::platform::FileResult<()> {
use std::fs::remove_file;
match remove_file(path) {
Ok(_) => Ok(()),
Err(_) => Err(()),
}
}
fn file_size(&self, path: &str) -> remdb::platform::FileResult<usize> {
use std::fs::metadata;
match metadata(path) {
Ok(meta) => Ok(meta.len() as usize),
Err(_) => Err(()),
}
}
fn crc32(&self, data: *const u8, size: usize) -> u32 {
let slice = unsafe { std::slice::from_raw_parts(data, size) };
let mut checksum = 0u32;
for &byte in slice {
checksum ^= byte as u32;
}
checksum
}
}
static SIMPLE_PLATFORM: SimplePlatform = SimplePlatform;
unsafe {
let _ = remdb::memory::allocator::init_global_allocator(
DB_MEMORY.as_mut_ptr(),
DB_MEMORY.len(),
);
remdb::platform::init_platform(&SIMPLE_PLATFORM);
let db = remdb::init_global_db(&TEST_DB)?;
println!("插入测试数据...");
println!("TEST_TABLE.fields.len() = {}", TEST_TABLE.fields.len());
for i in 0..10 {
#[repr(align(8))]
struct AlignedRecord([u8; 32]); let mut record = AlignedRecord([0; 32]);
let table = db.get_table_mut(0)?;
let id_value = remdb::Value { u64: i as u64 };
table.set_field(record.0.as_mut_ptr(), 0, &id_value)?;
let name = format!("item_{}", i);
let name_value = remdb::Value {
string: {
let mut s = [0u8; 64];
for (j, c) in name.as_bytes().iter().enumerate() {
if j < s.len() {
s[j] = *c;
} else {
break;
}
}
s
},
};
table.set_field(record.0.as_mut_ptr(), 1, &name_value)?;
let value_value = remdb::Value {
u32: (i * 100) as u32,
};
table.set_field(record.0.as_mut_ptr(), 2, &value_value)?;
let record_id = table.insert(record.0.as_ptr())?;
println!("插入记录ID: {}", record_id);
}
println!("保存快照到 snapshot.remd...");
db.save_snapshot("snapshot.remd")?;
println!("快照保存成功");
Ok(())
}
}