1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
//! Represents data structures outside of kitsune, on the "host" side,
//! i.e. methods which would be called via ghost_actors, i.e. Holochain.
//!
//! XXX: These traits are an artifact of the original prototype of the quantized gossip
//! algorithm, which started as its own crate separate from the rest of Kitsune,
//! and created these traits to build up a suitable interface from scratch.
//! Eventually these should be better integrated with the existing KitsuneP2pEvent
//! interface, and the KitsuneHost interface: the integration of those two is
//! still a work in progress, and these traits should be considered as part of
//! that work.
use std::sync::Arc;
use must_future::MustBoxFuture;
use crate::{
arq::ArqSet,
hash::AgentKey,
op::*,
region::*,
region_set::*,
spacetime::{GossipParams, TelescopingTimes, TimeQuantum, Topology},
test_utils::OpData,
Arq,
};
/// All methods involved in accessing the op store, to be implemented by the host.
// TODO: make async
pub trait AccessOpStore<O: OpRegion<D>, D: RegionDataConstraints = RegionData>: Send {
/// Query the actual ops inside a region
fn query_op_data(&self, region: &RegionCoords) -> Vec<Arc<O>>;
/// Query the RegionData of a region, including the hash of all ops, size, and count
fn query_region_data(&self, region: &RegionCoords) -> D;
/// Fetch a set of Regions (the coords and the data) given the set of coords
fn fetch_region_set(
&self,
coords: RegionCoordSetLtcs,
) -> MustBoxFuture<Result<RegionSetLtcs<D>, ()>>;
/// Integrate incoming ops, updating the necessary stores
fn integrate_ops<Ops: Clone + Iterator<Item = Arc<O>>>(&mut self, ops: Ops);
/// Integrate a single op
fn integrate_op(&mut self, op: Arc<O>) {
self.integrate_ops([op].into_iter())
}
/// Get the GossipParams associated with this store
fn gossip_params(&self) -> GossipParams;
/// Get the Topology associated with this store
fn topo(&self) -> &Topology;
/// Get the RegionSet for this node, suitable for gossiping
fn region_set(&self, arq_set: ArqSet, now: TimeQuantum) -> RegionSet<D> {
let coords = RegionCoordSetLtcs::new(TelescopingTimes::new(now), arq_set);
coords
.into_region_set_infallible(|(_, coords)| self.query_region_data(&coords))
.into()
}
}
/// All methods involved in accessing the peer store, to be implemented by the host.
// TODO: make async
pub trait AccessPeerStore {
/// Get the arq for an agent
fn get_agent_arq(&self, agent: &AgentKey) -> Arq;
/// Get the set of all arqs for this node
fn get_arq_set(&self) -> ArqSet;
}
/// Represents all methods implemented by the host.
pub trait HostAccess<O: OpRegion<D>, D: RegionDataConstraints = RegionData>:
AccessOpStore<O, D> + AccessPeerStore
{
}
impl<T, O: OpRegion<D>, D: RegionDataConstraints> HostAccess<O, D> for T where
T: AccessOpStore<O, D> + AccessPeerStore
{
}
/// Represents all methods implemented by the host.
pub trait HostAccessTest: HostAccess<OpData, RegionData> {}
impl<T> HostAccessTest for T where T: HostAccess<OpData, RegionData> {}