mirror of
https://github.com/deuxfleurs-org/garage.git
synced 2026-08-27 15:37:03 +00:00
New model for buckets
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::crdt::crdt::*;
|
||||
|
||||
/// Deletable object (once deleted, cannot go back)
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub enum Deletable<T> {
|
||||
Present(T),
|
||||
Deleted,
|
||||
}
|
||||
|
||||
impl<T: Crdt> Deletable<T> {
|
||||
/// Create a new deletable object that isn't deleted
|
||||
pub fn present(v: T) -> Self {
|
||||
Self::Present(v)
|
||||
}
|
||||
/// Create a new deletable object that is deleted
|
||||
pub fn delete() -> Self {
|
||||
Self::Deleted
|
||||
}
|
||||
/// As option
|
||||
pub fn as_option(&self) -> Option<&T> {
|
||||
match self {
|
||||
Self::Present(v) => Some(v),
|
||||
Self::Deleted => None,
|
||||
}
|
||||
}
|
||||
/// As option, mutable
|
||||
pub fn as_option_mut(&mut self) -> Option<&mut T> {
|
||||
match self {
|
||||
Self::Present(v) => Some(v),
|
||||
Self::Deleted => None,
|
||||
}
|
||||
}
|
||||
/// Into option
|
||||
pub fn into_option(self) -> Option<T> {
|
||||
match self {
|
||||
Self::Present(v) => Some(v),
|
||||
Self::Deleted => None,
|
||||
}
|
||||
}
|
||||
/// Is object deleted?
|
||||
pub fn is_deleted(&self) -> bool {
|
||||
matches!(self, Self::Deleted)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Option<T>> for Deletable<T> {
|
||||
fn from(v: Option<T>) -> Self {
|
||||
v.map(Self::Present).unwrap_or(Self::Deleted)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Deletable<T>> for Option<T> {
|
||||
fn from(v: Deletable<T>) -> Option<T> {
|
||||
match v {
|
||||
Deletable::Present(v) => Some(v),
|
||||
Deletable::Deleted => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Crdt> Crdt for Deletable<T> {
|
||||
fn merge(&mut self, other: &Self) {
|
||||
if let Deletable::Present(v) = self {
|
||||
match other {
|
||||
Deletable::Deleted => *self = Deletable::Deleted,
|
||||
Deletable::Present(v2) => v.merge(v2),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,6 +82,11 @@ where
|
||||
&self.v
|
||||
}
|
||||
|
||||
/// Take the value inside the CRDT (discards the timesamp)
|
||||
pub fn take(self) -> T {
|
||||
self.v
|
||||
}
|
||||
|
||||
/// Get a mutable reference to the CRDT's value
|
||||
///
|
||||
/// This is usefull to mutate the inside value without changing the LWW timestamp.
|
||||
|
||||
@@ -30,8 +30,8 @@ pub struct LwwMap<K, V> {
|
||||
|
||||
impl<K, V> LwwMap<K, V>
|
||||
where
|
||||
K: Ord,
|
||||
V: Crdt,
|
||||
K: Clone + Ord,
|
||||
V: Clone + Crdt,
|
||||
{
|
||||
/// Create a new empty map CRDT
|
||||
pub fn new() -> Self {
|
||||
@@ -73,6 +73,10 @@ where
|
||||
};
|
||||
Self { vals: new_vals }
|
||||
}
|
||||
|
||||
pub fn update_in_place(&mut self, k: K, new_v: V) {
|
||||
self.merge(&self.update_mutator(k, new_v));
|
||||
}
|
||||
/// Takes all of the values of the map and returns them. The current map is reset to the
|
||||
/// empty map. This is very usefull to produce in-place a new map that contains only a delta
|
||||
/// that modifies a certain value:
|
||||
@@ -158,8 +162,8 @@ where
|
||||
|
||||
impl<K, V> Default for LwwMap<K, V>
|
||||
where
|
||||
K: Ord,
|
||||
V: Crdt,
|
||||
K: Clone + Ord,
|
||||
V: Clone + Crdt,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
|
||||
@@ -12,12 +12,14 @@
|
||||
mod bool;
|
||||
#[allow(clippy::module_inception)]
|
||||
mod crdt;
|
||||
mod deletable;
|
||||
mod lww;
|
||||
mod lww_map;
|
||||
mod map;
|
||||
|
||||
pub use self::bool::*;
|
||||
pub use crdt::*;
|
||||
pub use deletable::*;
|
||||
pub use lww::*;
|
||||
pub use lww_map::*;
|
||||
pub use map::*;
|
||||
|
||||
Reference in New Issue
Block a user