conflict has overflows

This commit is contained in:
Aode (Lion) 2022-03-16 11:37:35 -05:00
parent ff357a5913
commit 1012fd1001
3 changed files with 82 additions and 54 deletions

View file

@ -3,28 +3,38 @@ use persy_trees::{Db, Tree};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = Db::open("./db.persy")?;
let tree: Tree<String, u8> = db.open_tree("u8-tree")?;
let tree: Tree<String> = db.open_tree("u8-tree")?;
let bytes = vec![5];
println!("Inserting");
let mut tx = tree.transaction()?;
tx.insert("value".into(), 5)?;
tx.insert("value".into(), &bytes)?;
tx.commit()?;
println!("Two transactions");
let mut tx1 = tree.transaction()?;
let mut tx2 = tree.transaction()?;
println!("Two values");
let value1 = tx1.get(&"value".into())?.expect("Value exists");
let value2 = tx2.get(&"value".into())?.expect("Value exists");
tx1.insert("value".into(), value1 + 1)?;
tx2.insert("value".into(), value2 - 1)?;
println!("Two inserts");
tx1.insert("value".into(), &[value1[0] + 1])?;
tx2.insert("value".into(), &[value2[0] - 1])?;
println!("Two commits");
println!("\tfirst");
tx1.commit()?;
println!("\tsecond");
tx2.commit()?;
println!("Final get");
let mut tx = tree.transaction()?;
let value = tx.get(&"value".into())?.expect("Value exists");
println!("value: {}", value);
println!("value: {}", value[0]);
Ok(())
}

View file

@ -1,18 +1,17 @@
use persy::ByteVec;
use persy_trees::{Db, Tree};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = Db::open("./db.persy")?;
let tree: Tree<String, ByteVec> = db.open_tree("some-tree-name")?;
let tree: Tree<String> = db.open_tree("some-tree-name")?;
let mut tx1 = tree.transaction()?;
let mut tx2 = tree.transaction()?;
let put: ByteVec = vec![0, 1, 2, 3, 4].into();
let put = vec![0, 1, 2, 3, 4];
tx1.insert("howdy".into(), put.clone())?;
tx2.insert("meowdy".into(), put.clone())?;
tx1.insert("howdy".into(), &put)?;
tx2.insert("meowdy".into(), &put)?;
let got1 = tx1.get(&"howdy".into())?.expect("We just inserted this");
let got2 = tx2.get(&"meowdy".into())?.expect("We just inserted this");
@ -21,10 +20,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
assert_eq!(got2, put);
for (k, v) in tx1.range(..)? {
println!("{}: {:?}", k, &*v);
let v = v?;
println!("{}: {:?}", k, v);
}
for (k, v) in tx2.range(..)? {
println!("{}: {:?}", k, &*v);
let v = v?;
println!("{}: {:?}", k, v);
}
tx1.commit()?;

View file

@ -1,6 +1,6 @@
use persy::{
Config, IndexId, IndexType, Persy, PersyError, SegmentId, TransactionConfig, TxIndexIter,
TxStrategy, ValueMode, PE,
Config, IndexId, IndexType, Persy, PersyError, PersyId, SegmentId, TransactionConfig,
TxIndexIter, TxStrategy, ValueMode, PE,
};
use std::borrow::Cow;
use std::marker::PhantomData;
@ -22,24 +22,24 @@ pub struct Db {
persy: Persy,
}
pub struct Tree<K, V> {
pub struct Tree<K> {
name: String,
_segment_id: SegmentId,
segment_id: SegmentId,
_index_id: IndexId,
persy: Persy,
_key: PhantomData<K>,
_value: PhantomData<V>,
}
pub struct Transaction<'a, K, V> {
tree: Cow<'a, Tree<K, V>>,
pub struct Transaction<'a, K> {
tree: Cow<'a, Tree<K>>,
tx: persy::Transaction,
}
pub struct Iter<'a, K: IndexType, V: IndexType> {
iter: TxIndexIter<'a, K, V>,
pub struct Iter<'a, K: IndexType> {
iter: TxIndexIter<'a, K, PersyId>,
segment_id: &'a SegmentId,
}
impl Error {
@ -54,10 +54,9 @@ impl Db {
Ok(Self { persy })
}
pub fn open_tree<K, V, N>(&self, tree_name: N) -> Result<Tree<K, V>, Error>
pub fn open_tree<K, N>(&self, tree_name: N) -> Result<Tree<K>, Error>
where
K: IndexType,
V: IndexType,
N: Into<String>,
{
let segment_id;
@ -72,7 +71,7 @@ impl Db {
index_id = tx.solve_index_id(&name)?;
} else {
segment_id = tx.create_segment(&name)?;
tx.create_index::<K, V>(&name, ValueMode::Replace)?;
tx.create_index::<K, PersyId>(&name, ValueMode::Replace)?;
index_id = tx.solve_index_id(&name)?;
}
let tx = tx.prepare()?;
@ -80,19 +79,18 @@ impl Db {
Ok(Tree {
name,
_segment_id: segment_id,
segment_id,
_index_id: index_id,
persy: self.persy.clone(),
_key: PhantomData,
_value: PhantomData,
})
}
}
impl<K, V> Tree<K, V> {
pub fn transaction(&self) -> Result<Transaction<'_, K, V>, Error> {
impl<K> Tree<K> {
pub fn transaction(&self) -> Result<Transaction<'_, K>, Error> {
let tx = self
.persy
.begin_with(TransactionConfig::new().set_strategy(TxStrategy::VersionOnRead))?;
@ -104,26 +102,41 @@ impl<K, V> Tree<K, V> {
}
}
impl<'a, K, V> Transaction<'a, K, V>
impl<'a, K> Transaction<'a, K>
where
K: IndexType,
V: IndexType,
{
pub fn get(&mut self, key: &K) -> Result<Option<V>, Error> {
Ok(self.tx.one(&self.tree.name, key)?)
pub fn get(&mut self, key: &K) -> Result<Option<Vec<u8>>, Error> {
if let Some(id) = self.tx.one(&self.tree.name, key)? {
Ok(self.tx.read(&self.tree.segment_id, &id)?)
} else {
Ok(None)
}
}
pub fn range<R: RangeBounds<K>>(&mut self, range: R) -> Result<Iter<'_, K, V>, Error> {
Ok(Iter::new(self.tx.range(&self.tree.name, range)?))
pub fn range<R: RangeBounds<K>>(&mut self, range: R) -> Result<Iter<'_, K>, Error> {
Ok(Iter::new(
self.tx.range(&self.tree.name, range)?,
&self.tree.segment_id,
))
}
pub fn insert(&mut self, key: K, value: V) -> Result<(), Error> {
self.tx.put(&self.tree.name, key, value)?;
pub fn insert(&mut self, key: K, value: &[u8]) -> Result<(), Error> {
if let Some(id) = self.tx.one(&self.tree.name, &key)? {
self.tx.update(&self.tree.segment_id, &id, value)?;
} else {
let id = self.tx.insert(&self.tree.segment_id, value)?;
self.tx.put(&self.tree.name, key, id)?;
}
Ok(())
}
pub fn remove(&mut self, key: K) -> Result<(), Error> {
self.tx.remove(&self.tree.name, key, None as Option<V>)?;
if let Some(id) = self.tx.one(&self.tree.name, &key)? {
self.tx.delete(&self.tree.segment_id, &id)?;
self.tx
.remove(&self.tree.name, key, None as Option<PersyId>)?;
}
Ok(())
}
@ -137,7 +150,7 @@ where
Ok(())
}
pub fn into_owned(self) -> Transaction<'static, K, V> {
pub fn into_owned(self) -> Transaction<'static, K> {
Transaction {
tree: Cow::Owned(self.tree.into_owned()),
tx: self.tx,
@ -145,61 +158,65 @@ where
}
}
impl<'a, K, V> Iter<'a, K, V>
impl<'a, K> Iter<'a, K>
where
K: IndexType,
V: IndexType,
{
fn new(iter: TxIndexIter<'a, K, V>) -> Self {
Self { iter }
fn new(iter: TxIndexIter<'a, K, PersyId>, segment_id: &'a SegmentId) -> Self {
Self { iter, segment_id }
}
}
impl<'a, K, V> Iterator for Iter<'a, K, V>
impl<'a, K> Iterator for Iter<'a, K>
where
K: IndexType,
V: IndexType,
{
type Item = (K, V);
type Item = (K, Result<Vec<u8>, Error>);
fn next(&mut self) -> Option<Self::Item> {
loop {
let (key, mut values) = self.iter.next()?;
if let Some(value) = values.next() {
return Some((key, value));
if let Some(id) = values.next() {
return match self.iter.tx().read(self.segment_id, &id) {
Ok(Some(value)) => Some((key, Ok(value))),
Ok(None) => continue,
Err(e) => Some((key, Err(e.into()))),
};
}
}
}
}
impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V>
impl<'a, K> DoubleEndedIterator for Iter<'a, K>
where
K: IndexType,
V: IndexType,
{
fn next_back(&mut self) -> Option<Self::Item> {
loop {
let (key, mut values) = self.iter.next_back()?;
if let Some(value) = values.next() {
return Some((key, value));
if let Some(id) = values.next() {
return match self.iter.tx().read(self.segment_id, &id) {
Ok(Some(value)) => Some((key, Ok(value))),
Ok(None) => continue,
Err(e) => Some((key, Err(e.into()))),
};
}
}
}
}
impl<K, V> Clone for Tree<K, V> {
impl<K> Clone for Tree<K> {
fn clone(&self) -> Self {
Self {
name: self.name.clone(),
_segment_id: self._segment_id,
segment_id: self.segment_id,
_index_id: self._index_id.clone(),
persy: self.persy.clone(),
_key: PhantomData,
_value: PhantomData,
}
}
}