parent
2aa996f01e
commit
508c7bf177
@ -0,0 +1,133 @@ |
|||||||
|
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
|
||||||
|
// All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0
|
||||||
|
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
|
||||||
|
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||||
|
// at your option. All files in the project carrying such
|
||||||
|
// notice may not be copied, modified, or distributed except
|
||||||
|
// according to those terms.
|
||||||
|
|
||||||
|
//! Commit Storage (Object Key/Col/Value Mapping)
|
||||||
|
|
||||||
|
use std::collections::HashMap; |
||||||
|
use std::collections::HashSet; |
||||||
|
|
||||||
|
use ng_net::types::*; |
||||||
|
use ng_repo::errors::StorageError; |
||||||
|
use ng_repo::kcv_storage::*; |
||||||
|
use ng_repo::types::*; |
||||||
|
|
||||||
|
use serde_bare::to_vec; |
||||||
|
|
||||||
|
use crate::server_broker::CommitInfo; |
||||||
|
use crate::server_broker::EventInfo; |
||||||
|
|
||||||
|
pub struct CommitStorage<'a> { |
||||||
|
key: Vec<u8>, |
||||||
|
event: ExistentialValue<Option<EventInfo>>, |
||||||
|
storage: &'a dyn KCVStorage, |
||||||
|
} |
||||||
|
|
||||||
|
impl<'a> IModel for CommitStorage<'a> { |
||||||
|
fn key(&self) -> &Vec<u8> { |
||||||
|
&self.key |
||||||
|
} |
||||||
|
fn storage(&self) -> &dyn KCVStorage { |
||||||
|
self.storage |
||||||
|
} |
||||||
|
fn class(&self) -> &Class { |
||||||
|
&Self::CLASS |
||||||
|
} |
||||||
|
fn existential(&mut self) -> Option<&mut dyn IExistentialValue> { |
||||||
|
Some(&mut self.event) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl<'a> CommitStorage<'a> { |
||||||
|
const PREFIX: u8 = b'e'; |
||||||
|
|
||||||
|
// Topic properties
|
||||||
|
pub const EVENT: ExistentialValueColumn = ExistentialValueColumn::new(b'e'); |
||||||
|
pub const HOME_PINNED: SingleValueColumn<Self, bool> = SingleValueColumn::new(b'p'); |
||||||
|
|
||||||
|
// Commit -> Acks
|
||||||
|
pub const ACKS: MultiValueColumn<Self, ObjectId> = MultiValueColumn::new(b'a'); |
||||||
|
// Commit -> Deps
|
||||||
|
pub const DEPS: MultiValueColumn<Self, ObjectId> = MultiValueColumn::new(b'd'); |
||||||
|
// Commit -> Files
|
||||||
|
pub const FILES: MultiValueColumn<Self, ObjectId> = MultiValueColumn::new(b'f'); |
||||||
|
// Commit -> Causal future commits
|
||||||
|
pub const FUTURES: MultiValueColumn<Self, ObjectId> = MultiValueColumn::new(b'c'); |
||||||
|
|
||||||
|
pub const CLASS: Class<'a> = Class::new( |
||||||
|
"Commit", |
||||||
|
Some(Self::PREFIX), |
||||||
|
Some(&Self::EVENT), |
||||||
|
&[&Self::HOME_PINNED as &dyn ISingleValueColumn], |
||||||
|
&[ |
||||||
|
&Self::ACKS as &dyn IMultiValueColumn, |
||||||
|
&Self::DEPS, |
||||||
|
&Self::FILES, |
||||||
|
&Self::FUTURES, |
||||||
|
], |
||||||
|
); |
||||||
|
|
||||||
|
pub fn new(id: &ObjectId, overlay: &OverlayId, storage: &'a dyn KCVStorage) -> Self { |
||||||
|
let mut key: Vec<u8> = Vec::with_capacity(33 + 33); |
||||||
|
key.append(&mut to_vec(overlay).unwrap()); |
||||||
|
key.append(&mut to_vec(id).unwrap()); |
||||||
|
CommitStorage { |
||||||
|
key, |
||||||
|
event: ExistentialValue::<Option<EventInfo>>::new(), |
||||||
|
storage, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn load( |
||||||
|
id: &ObjectId, |
||||||
|
overlay: &OverlayId, |
||||||
|
storage: &'a dyn KCVStorage, |
||||||
|
) -> Result<CommitInfo, StorageError> { |
||||||
|
let mut opening = CommitStorage::new(id, overlay, storage); |
||||||
|
let props = opening.load_props()?; |
||||||
|
let existential = col(&Self::EVENT, &props)?; |
||||||
|
opening.event.set(&existential)?; |
||||||
|
Ok(CommitInfo { |
||||||
|
event: existential, |
||||||
|
home_pinned: col(&Self::HOME_PINNED, &props).unwrap_or(false), |
||||||
|
acks: Self::ACKS.get_all(&mut opening)?, |
||||||
|
deps: Self::DEPS.get_all(&mut opening)?, |
||||||
|
files: Self::FILES.get_all(&mut opening)?, |
||||||
|
futures: Self::FUTURES.get_all(&mut opening)?, |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn open( |
||||||
|
id: &ObjectId, |
||||||
|
overlay: &OverlayId, |
||||||
|
storage: &'a dyn KCVStorage, |
||||||
|
) -> Result<CommitStorage<'a>, StorageError> { |
||||||
|
let mut opening = CommitStorage::new(id, overlay, storage); |
||||||
|
opening.check_exists()?; |
||||||
|
Ok(opening) |
||||||
|
} |
||||||
|
pub fn create( |
||||||
|
id: &ObjectId, |
||||||
|
overlay: &OverlayId, |
||||||
|
event: &Option<EventInfo>, |
||||||
|
storage: &'a mut dyn KCVStorage, |
||||||
|
) -> Result<CommitStorage<'a>, StorageError> { |
||||||
|
let mut creating = CommitStorage::new(id, overlay, storage); |
||||||
|
if creating.exists() { |
||||||
|
return Err(StorageError::AlreadyExists); |
||||||
|
} |
||||||
|
creating.event.set(event)?; |
||||||
|
ExistentialValue::save(&creating, event)?; |
||||||
|
|
||||||
|
Ok(creating) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn event(&mut self) -> &Option<EventInfo> { |
||||||
|
self.event.get().unwrap() |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue