Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub trait PointerItem {
/// 将一个裸指针转化为原指针
///
/// # Safety
/// 裸指针必须是通过into_raw生成得到的,同时需要注意所有权的恢复
/// 裸指针必须是由同类型trait里的into_raw方法生成得到的,需要注意此时所有权的恢复
unsafe fn from_raw(ptr: *const u8) -> Self;
}

Expand Down Expand Up @@ -58,12 +58,14 @@ pub(crate) trait ItemEntry {
Self: 'a;

/// 由原类型生成usize,消耗原类型所有权,该usize将直接存入XArray的XEntry。
/// 用户需要确保生产的usize符合XArray对item entry的要求,即如果原类型是pointer的话
/// 后两位为00,如果原类型是usize之类的value的话末位为1.
fn into_raw(self) -> usize;

/// 由usize恢复原类型,恢复所有权
///
/// # Safety
/// 传入的raw必须是由into_raw生成的
/// 传入的raw必须是由同类型trait内对应方法into_raw生成的
unsafe fn from_raw(raw: usize) -> Self;

/// 读取该类型对应的XEntry,返回用户需要的读取类型
Expand Down Expand Up @@ -114,6 +116,10 @@ pub(crate) struct Node {}

/// XArray中有所有权的Entry,只有两种Type,Item以及Node,分别对应ItemEntry以及指向Node的Entry
/// 指向Node的Entry目前有统一的结构类型,也就是Arc<RwLock<XNode<I>>>。
/// OwnedEntry目前只会在三种情况下生成:
/// - store时由传入的item生成
/// - 创建新的Node节点时生成
/// - replace XArray上的XEntry时,将XEntry恢复成原来的OwnedEntry (该XEntry是由OwnedEntry生成的)
#[derive(Eq)]
#[repr(transparent)]
pub struct OwnedEntry<I: ItemEntry, Type> {
Expand Down
6 changes: 4 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#![feature(pointer_is_aligned)]
use core::prelude::v1;
use std::sync::Arc;

use entry::*;
use mark::*;
use node::*;
use state::*;
use std::sync::Arc;
use xarray::*;

mod entry;
Expand Down Expand Up @@ -39,4 +38,7 @@ fn main() {
println!("load usize: {:?}", v1);
let v2 = xarray_usize.load(8);
println!("load usize: {:?}", v2);
xarray_usize.remove(8);
let v2 = xarray_usize.load(8);
println!("load usize: {:?}", v2);
}
8 changes: 6 additions & 2 deletions src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,14 @@ impl<I: ItemEntry> XNode<I> {
pub(crate) fn set_item_entry(
&mut self,
offset: u8,
entry: OwnedEntry<I, Item>,
entry: Option<OwnedEntry<I, Item>>,
) -> Option<OwnedEntry<I, Item>> {
let old_entry = OwnedEntry::<I, Item>::from_raw(self.slots[offset as usize]);
self.slots[offset as usize] = OwnedEntry::<I, Item>::into_raw(entry);
let new_entry = entry
.map(|entry| OwnedEntry::<I, Item>::into_raw(entry))
.unwrap_or(XEntry::EMPTY);
self.slots[offset as usize] = new_entry;

old_entry
}

Expand Down
7 changes: 3 additions & 4 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,16 @@ impl<I: ItemEntry, M: XMark> State<I, M> {
pub fn store(
&mut self,
xa: &mut XArray<I, M>,
entry: OwnedEntry<I, Item>,
entry: Option<OwnedEntry<I, Item>>,
) -> Option<OwnedEntry<I, Item>> {
let op_entry = self.create(xa);
// TODO: Multi-index entry
if *op_entry == entry {
return Some(entry);
if entry.as_ref().is_some_and(|entry| *op_entry == *entry) {
return entry;
}
let node = self.node.get().unwrap();
let mut node_write = node.write().unwrap();
let old_entry = node_write.set_item_entry(self.offset, entry);
let k = node_write.entry(self.offset);
return old_entry;
}

Expand Down
22 changes: 16 additions & 6 deletions src/xarray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub const CHUNK_MASK: usize = CHUNK_SIZE - 1;
/// The XArray is an abstract data type which behaves like a very large array of items.
/// Items here must be a 8 bytes object, like pointers or `u64`.
/// it allows you to sensibly go to the next or previous entry in a cache-efficient manner.
/// Normal pointers may be stored in the XArray directly. They must be 4-byte aligned
/// Normal pointers may be stored in the XArray directly. They must be 4-byte aligned.
///
/// # Example
///
Expand Down Expand Up @@ -50,16 +50,21 @@ impl<I: ItemEntry, M: XMark> XArray<I, M> {
pub fn load<'a>(&'a self, index: u64) -> Option<I::Target<'a>> {
let mut cursor = self.cursor(index);
let entry = cursor.current();
unsafe { Some(I::load_item(entry)) }
if entry.is_item() {
unsafe { Some(I::load_item(entry)) }
}
else {
None
}
}

pub fn store(&mut self, index: u64, value: I) {
self.cursor_mut(index).store(value);
}

// pub fn remove(&mut self, index: u64) {
// self.cursor_mut(index).remove();
// }
pub fn remove(&mut self, index: u64) {
self.cursor_mut(index).remove();
}

pub fn cursor<'a>(&'a self, index: u64) -> Cursor<'a, I, M> {
Cursor {
Expand Down Expand Up @@ -105,7 +110,12 @@ impl<'a, I: ItemEntry, M: XMark> CursorMut<'a, I, M> {

pub fn store(&mut self, item: I) {
let Self { xa, xas } = self;
xas.store(xa, OwnedEntry::from_item(item));
xas.store(xa, Some(OwnedEntry::from_item(item)));
}

pub fn remove(&mut self) {
let Self { xa, xas } = self;
xas.store(xa, None);
}

pub fn key(&mut self) -> u64 {
Expand Down