Sync stuff.

This commit is contained in:
Adam Ierymenko 2021-10-04 09:02:20 -04:00
parent 110df67697
commit 71904d1453
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
6 changed files with 89 additions and 7 deletions

View file

@ -4,3 +4,4 @@ version = "0.1.0"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
parking_lot = "^0"

6
cumberland/src/hasher.rs Normal file
View file

@ -0,0 +1,6 @@
/// Hasher responsible for hashing keys.
pub trait Hasher {
const OUTPUT_SIZE: usize;
fn new() -> Self;
fn digest(&mut self, b: &[u8]) -> [u8; Self::OUTPUT_SIZE];
}

View file

@ -1,7 +1,4 @@
#[cfg(test)] mod store;
mod tests { mod validator;
#[test] mod network;
fn it_works() { mod hasher;
assert_eq!(2 + 2, 4);
}
}

23
cumberland/src/network.rs Normal file
View file

@ -0,0 +1,23 @@
use std::hash::Hash;
/// An interface to a physical network such as TCP/IP or ZeroTier.
pub trait Network {
/// An endpoint address on the network to which messages can be sent.
type Address: Hash + Clone;
/// The maximum message size that can be handled by this Network.
/// Note that the underlying transport must be able to handle sizes of at least 4096.
const MAX_MESSAGE_SIZE: usize;
/// Attempt to send a message to an address.
///
/// The semantics required are similar to UDP in that delivery need not be guaranteed.
/// A return value of false indicates an obvious error such as invalid address.
fn send(&self, to: &Address, data: &[u8]) -> bool;
/// Receive the next incoming message.
///
/// This should block until the next message is available. A return of None indicates
/// that the instance is shutting down.
fn receive(&self) -> Option<(Address, Vec<u8>)>;
}

44
cumberland/src/store.rs Normal file
View file

@ -0,0 +1,44 @@
use std::collections::BTreeMap;
use std::ops::Bound::Included;
use std::sync::Arc;
use parking_lot::Mutex;
/// Trait to be implemented by any data store to be replicated.
pub trait Store {
fn load(&self, key: &[u8]) -> Option<Arc<[u8]>>;
fn store(&self, key: &[u8], value: &[u8]) -> bool;
fn for_each_range<F: FnMut(&[u8], &Arc<[u8]>)>(&self, starting_key: &[u8], ending_key: &[u8], f: F);
fn count(&self, starting_key: &[u8], ending_key: &[u8]) -> Option<u64>;
}
/// A simple BTreeMap backed Store, mostly for testing as it does not persist anything.
#[derive(Clone)]
pub struct BTreeStore(Mutex<BTreeMap<[u8], Arc<[u8]>>>);
impl BTreeStore {
pub fn new() -> Self { Self(Mutex::new(BTreeMap::new())) }
}
impl Store for BTreeStore {
fn load(&self, key: &[u8]) -> Option<Arc<[u8]>> {
let db = self.0.lock();
db.get(key).map(|v| v.clone())
}
fn store(&self, key: &[u8], value: &[u8]) -> bool {
let mut db = self.0.lock();
let _ = db.insert(*key, Arc::from(value));
true
}
fn for_each_range<F: FnMut((&[u8], &Arc<[u8]>))>(&self, starting_key: &[u8], ending_key: &[u8], f: F) {
let db = self.0.lock();
db.range((Included(starting_key), Included(ending_key))).for_each(f)
}
fn count(&self, starting_key: &[u8], ending_key: &[u8]) -> Option<u64> {
let db = self.0.lock();
Some(db.range((Included(starting_key), Included(ending_key))).count() as u64)
}
}

View file

@ -0,0 +1,11 @@
pub trait Validator {
/// Check an entry and return true if it should be stored, returned, or replicated.
fn validate(&self, key: &[u8; 48], value: &[u8]) -> bool;
}
/// A validator that approves everything, mostly for testing.
pub struct NilValidator;
impl Validator for NilValidator {
fn validate(&self, _: &[u8; 48], _: &[u8]) -> bool { true }
}