diff --git a/src/core/id.rs b/src/core/id.rs index f2a78ed..4a8be5d 100644 --- a/src/core/id.rs +++ b/src/core/id.rs @@ -32,33 +32,33 @@ impl fmt::Display for MizeId { } } -pub trait IntoMizeId { - fn to_mize_id(self, instance: &Instance) -> MizeId; +pub trait IntoMizeId { + fn to_mize_id(self, instance: &Instance) -> MizeId; } -impl IntoMizeId for &str { - fn to_mize_id(self, instance: &Instance) -> MizeId { +impl IntoMizeId for &str { + fn to_mize_id(self, instance: &Instance) -> MizeId { instance.id_from_string(self.to_owned()) } } -impl IntoMizeId for String { - fn to_mize_id(self, instance: &Instance) -> MizeId { +impl IntoMizeId for String { + fn to_mize_id(self, instance: &Instance) -> MizeId { instance.id_from_string(self) } } -impl IntoMizeId for &String { - fn to_mize_id(self, instance: &Instance) -> MizeId { +impl IntoMizeId for &String { + fn to_mize_id(self, instance: &Instance) -> MizeId { instance.id_from_string(self.to_owned()) } } -impl IntoMizeId for Vec { - fn to_mize_id(self, instance: &Instance) -> MizeId { +impl IntoMizeId for Vec { + fn to_mize_id(self, instance: &Instance) -> MizeId { instance.id_from_vec_string(self) } } -impl IntoMizeId for &[&str] { - fn to_mize_id(self, instance: &Instance) -> MizeId { +impl IntoMizeId for &[&str] { + fn to_mize_id(self, instance: &Instance) -> MizeId { let mut vec: Vec = Vec::new(); for i in self { vec.push((*i).to_owned()) @@ -66,8 +66,8 @@ impl IntoMizeId for &[&str] { instance.id_from_vec_string(vec) } } -impl IntoMizeId for Vec<&str> { - fn to_mize_id(self, instance: &Instance) -> MizeId { +impl IntoMizeId for Vec<&str> { + fn to_mize_id(self, instance: &Instance) -> MizeId { let mut vec: Vec = Vec::new(); for i in self { vec.push((*i).to_owned()) @@ -75,8 +75,8 @@ impl IntoMizeId for Vec<&str> { instance.id_from_vec_string(vec) } } -impl IntoMizeId for MizeId { - fn to_mize_id(self, instance: &Instance) -> MizeId { +impl IntoMizeId for MizeId { + fn to_mize_id(self, instance: &Instance) -> MizeId { self } } diff --git a/src/core/instance/mod.rs b/src/core/instance/mod.rs index a248743..9a85c96 100644 --- a/src/core/instance/mod.rs +++ b/src/core/instance/mod.rs @@ -25,12 +25,11 @@ pub mod subscription; static MSG_CHANNEL_SIZE: usize = 200; /// The Instance type is the heart of the mize system -#[derive(Clone)] -pub struct Instance { +pub struct Instance { // question vec of stores??? // would mean replication logic and such things is handeled by the instance // i think it would be better thogh to then implement a ReplicatedStore - pub store: S, + pub store: Box, peers: Arc>>>, subs: Arc>>, pub id_pool: VecStringPool, @@ -45,16 +44,16 @@ pub enum RealmId { } */ -impl Instance { - pub fn empty() -> Instance { +impl Instance { + pub fn empty() -> Instance { let store = MemStore::new(); let id_pool = VecStringPool::default(); let peers = Arc::new(Mutex::new(Vec::new())); let subs = Arc::new(Mutex::new(HashMap::new())); - let mut instance = Instance {store, peers, subs, id_pool }; + let mut instance = Instance { store: Box::new(store), peers, subs, id_pool }; return instance; } - pub fn new() -> MizeResult> { + pub fn new() -> MizeResult { trace!("[ {} ] Instance::new()", "CALL".yellow()); let mut instance = Instance::empty(); @@ -78,7 +77,7 @@ impl Instance { Ok(()) } - pub fn with_config(config: ItemData) -> MizeResult> { + pub fn with_config(config: ItemData) -> MizeResult { trace!("[ {} ] Instance::with_config()", "CALL".yellow()); trace!("config: {}", config); let mut instance = Instance::empty(); @@ -94,20 +93,35 @@ impl Instance { Ok(instance) } + + pub fn migrate_to_store(&mut self, new_store: Box) -> MizeResult<()> { + let old_store = &self.store; + + for id in old_store.id_iter()? { + let data = self.store.get_value_data_full(self.id_from_string(id?))?; + + let id_of_new_store = new_store.new_id()?; + new_store.set(self.id_from_string(id_of_new_store), data.to_owned())?; + }; + + self.store = new_store; + + Ok(()) + } } -impl Instance { - pub fn new_item(&self) -> MizeResult> { +impl Instance { + pub fn new_item(&self) -> MizeResult { let id = self.id_from_string(self.store.new_id()?); return Ok(Item::new(id, &self)); } - pub fn get>(&self, id: I) -> MizeResult> { + pub fn get(&self, id: I) -> MizeResult { let id = id.to_mize_id(self); return Ok(Item::new(id, &self)); } - pub fn set, V: Into>(&mut self, id: I, value: V) -> MizeResult<()> { + pub fn set>(&mut self, id: I, value: V) -> MizeResult<()> { let id = id.to_mize_id(self); let item_data = value.into(); let mut item = self.get(id.clone())?; @@ -115,7 +129,7 @@ impl Instance { Ok(()) } - pub fn new_id>(&self, value: T) -> MizeId { + pub fn new_id(&self, value: T) -> MizeId { value.to_mize_id(self) } @@ -130,22 +144,9 @@ impl Instance { //fn from(value: T) -> Self { //} //} - pub fn migrate_to_store(&mut self, new_store: New) -> MizeResult> { - let old_store = self.store; - - for id in old_store.id_iter()? { - let data = self.store.get_value_data_full(self.id_from_string(id))?; - - let id_of_new_store = new_store.new_id()?; - new_store.set(self.id_from_string(id_of_new_store), data.to_owned())?; - }; - - self.store = new_store as S; - Ok(Instance { store: new_store, subs: self.subs, peers: self.peers, id_pool: self.id_pool }) - } } -impl fmt::Debug for Instance { +impl fmt::Debug for Instance { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Mize Instance with subs: {:?}", self.subs,) } diff --git a/src/core/instance/store.rs b/src/core/instance/store.rs index ef4d440..bd816cc 100644 --- a/src/core/instance/store.rs +++ b/src/core/instance/store.rs @@ -15,14 +15,14 @@ pub trait Store { // is implemented, so that there can be a multithreaded implementation //fn get(self, id: MizeId) -> MizeResult> where Self: Sized; - fn set>(&self, id: MizeId, data: T) -> MizeResult<()>; + fn set(&self, id: MizeId, data: ItemData) -> MizeResult<()>; // in the future should implement transactions, .... // funcs to do with links, backlinks - fn get_links(&self, item: Item) -> MizeResult> where Self: Sized; + fn get_links(&self, item: Item) -> MizeResult>; - fn get_backlinks(&self, item: Item) -> MizeResult> where Self: Sized; + fn get_backlinks(&self, item: Item) -> MizeResult>; fn new_id(&self) -> MizeResult; @@ -30,6 +30,40 @@ pub trait Store { fn get_value_data_full(&self, id: MizeId) -> MizeResult; - fn id_iter(&self) -> MizeResult + '_>; + fn id_iter(&self) -> MizeResult; + + fn next_id(&self, prev_id: &str) -> MizeResult>; + + fn first_id(&self) -> MizeResult; +} + +pub struct IdIter { + cur_id: String, + store: Box, +} + +impl IdIter { + pub fn new(store: Box) -> MizeResult { + Ok(IdIter { cur_id: store.first_id()?, store }) + } +} + +impl Iterator for IdIter { + type Item = MizeResult; + + fn next(&mut self) -> Option { + match self.store.next_id(&self.cur_id) { + Err(err) => { + Some(Err(err)) + }, + Ok(Some(new_id)) => { + self.cur_id = new_id.clone(); + Some(Ok(new_id)) + }, + Ok(None) => { + None + }, + } + } } diff --git a/src/core/item.rs b/src/core/item.rs index e7aacdd..f875ce1 100644 --- a/src/core/item.rs +++ b/src/core/item.rs @@ -18,9 +18,9 @@ use ciborium::Value as CborValue; // a item always has to do with a Instance, which takes care of how it is updated #[derive(Debug)] -pub struct Item<'a, S: Store + Sized> { +pub struct Item<'a> { id: MizeId, - pub instance: &'a Instance + pub instance: &'a Instance } // without an Instance it is not an item, but only the "data of an item" @@ -28,12 +28,12 @@ pub struct Item<'a, S: Store + Sized> { #[derive(Debug, Clone)] pub struct ItemData ( pub CborValue ); -impl Item<'_, S> { +impl Item<'_> { pub fn id(&self) -> MizeId { self.id.clone() } - pub fn new(id: MizeId, instance: &Instance) -> Item { + pub fn new(id: MizeId, instance: &Instance) -> Item { Item { id, instance } } @@ -41,14 +41,17 @@ impl Item<'_, S> { // this will call from the instance which gets the value from the store self.instance.store.get_value_raw(self.id()) } + pub fn value_string(&self) -> MizeResult { let raw = self.value_raw()?; String::from_utf8(raw.clone()) .mize_result_msg(format!("failed to convert raw value from item '{}' into a utf-8 string. raw value was: '{:02X?}'", self.id(), raw)) } + pub fn as_data_full(&self) -> MizeResult { self.instance.store.get_value_data_full(self.id()) } + pub fn merge>(&mut self, mut value: V) -> MizeResult<()> { let mut old_data = self.instance.store.get_value_data_full(self.id())?; @@ -61,7 +64,7 @@ impl Item<'_, S> { } } -impl Display for Item<'_, S> { +impl<'a> Display for Item<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let item_data = self.as_data_full().map_err(|_| std::fmt::Error)?; write!(f, "{}", item_data); diff --git a/src/core/memstore.rs b/src/core/memstore.rs index a631918..099450a 100644 --- a/src/core/memstore.rs +++ b/src/core/memstore.rs @@ -7,7 +7,7 @@ use log::trace; use colored::Colorize; use crate::id::MizeId; -use crate::instance::store::Store; +use crate::instance::store::{Store, IdIter}; use crate::error::{MizeError, MizeResult, IntoMizeResult}; use crate::item::{Item, ItemData}; use crate::instance::Instance; @@ -26,18 +26,18 @@ struct MemStoreInner { } impl Store for MemStore { - fn set>(&self, id: MizeId, data: T) -> MizeResult<()> { + fn set(&self, id: MizeId, data: ItemData) -> MizeResult<()> { let mut inner = self.inner.lock()?; - inner.map.insert(id_to_u64(id)?, data.into()); + inner.map.insert(id_to_u64(id)?, data); return Ok(()) } - fn get_links(&self, item: Item) -> MizeResult> { + fn get_links(&self, item: Item) -> MizeResult> { let inner = self.inner.lock()?; Ok(Vec::new()) } - fn get_backlinks(&self, item: Item) -> MizeResult> { + fn get_backlinks(&self, item: Item) -> MizeResult> { let inner = self.inner.lock()?; Ok(Vec::new()) @@ -80,11 +80,36 @@ impl Store for MemStore { return Ok(ret_data); } - fn id_iter(&self) -> MizeResult + '_> { + fn id_iter(&self) -> MizeResult { + + IdIter::new(Box::new(self.to_owned())) + } + + fn next_id(&self, prev_id_str: &str) -> MizeResult> { let inner = self.inner.lock()?; - let keys: Vec = inner.map.keys().map(|v| format!("{}", v)).collect(); - return Ok(keys.into_iter()); + let mut id = str_to_u64(prev_id_str)?; + + loop { + + id += 1; + + if id > inner.next_id { + return Ok(None); + } + + if inner.map.contains_key(&id) { + return Ok(Some(format!("{}", id))); + + } else { + // try id +1 + continue; + } + } + } + + fn first_id(&self) -> MizeResult { + Ok("0".to_owned()) } } @@ -96,9 +121,12 @@ impl MemStore { } fn id_to_u64(id: MizeId) -> MizeResult { - id.store_part() - .parse() - .mize_result_msg(format!("Could not parse the store_part of mizeid {} into a u64 for the MemStore", id)) + str_to_u64(id.store_part()) +} + +fn str_to_u64(id_str: &str) -> MizeResult { + id_str.parse() + .mize_result_msg(format!("Could not parse the store_part of mizeid {} into a u64 for the MemStore", id_str)) } pub fn get_raw_from_cbor<'a>(value: &'a CborValue, path: Vec<&String>) -> MizeResult<&'a [u8]> { diff --git a/src/platform/os/fsstore.rs b/src/platform/os/fsstore.rs index 9ccc189..77b7127 100644 --- a/src/platform/os/fsstore.rs +++ b/src/platform/os/fsstore.rs @@ -5,6 +5,7 @@ use sysinfo::{System, Pid, ProcessRefreshKind, RefreshKind}; use std::io::Write; use ciborium::Value as CborValue; +use crate::instance::store::IdIter; use crate::item::IntoItemData; use crate::memstore::MemStore; use crate::{core::instance::store::Store, mize_err}; @@ -57,17 +58,17 @@ impl Store for FileStore { return Ok(id_string); } - fn set>(&self, id: MizeId, data: T) -> MizeResult<()> { + fn set(&self, id: MizeId, data: ItemData) -> MizeResult<()> { let file = OpenOptions::new().write(true).create(true).open(self.path.join("store").join(id.store_part()))?; - ciborium::into_writer(data.into().cbor(), file)?; + ciborium::into_writer(data.cbor(), file)?; Ok(()) } - fn get_links(&self, item: Item) -> MizeResult> { + fn get_links(&self, item: Item) -> MizeResult> { Ok(Vec::new()) } - fn get_backlinks(&self, item: Item) -> MizeResult> { + fn get_backlinks(&self, item: Item) -> MizeResult> { Ok(Vec::new()) } @@ -100,8 +101,14 @@ impl Store for FileStore { return Ok(ret_data); } - fn id_iter(&self) -> MizeResult + '_> { - Ok(vec!["1".to_owned(), "2".to_owned()].into_iter()) + fn id_iter(&self) -> MizeResult { + todo!() + } + fn next_id(&self, prev_id: &str) -> MizeResult> { + todo!() + } + fn first_id(&self) -> MizeResult { + Ok("0".to_owned()) } } diff --git a/src/platform/os/mod.rs b/src/platform/os/mod.rs index 36d9ef3..27ee21a 100644 --- a/src/platform/os/mod.rs +++ b/src/platform/os/mod.rs @@ -19,7 +19,7 @@ mod fsstore; //mod unix-socket; -pub fn os_instance_init(instance: Instance) -> MizeResult> { +pub fn os_instance_init(instance: &mut Instance) -> MizeResult<()> { // this is the code, that runs to initialize an Instance on a system with an os present. ////// load MIZE_CONFIG_FILE as the instance, which is item 0 @@ -63,8 +63,8 @@ pub fn os_instance_init(instance: Instance) -> MizeResult