parent
a3eb88e601
commit
d66c0d6833
@ -0,0 +1,49 @@ |
||||
use std::sync::Arc; |
||||
use std::path::PathBuf; |
||||
|
||||
use tokio::fs; |
||||
use tokio::prelude::*; |
||||
|
||||
use crate::error::Error; |
||||
use crate::server::Garage; |
||||
use crate::proto::*; |
||||
use crate::data::*; |
||||
|
||||
fn block_dir(garage: &Garage, hash: &Hash) -> PathBuf { |
||||
let mut path = garage.system.config.data_dir.clone(); |
||||
path.push(hex::encode(&hash.as_slice()[0..1])); |
||||
path.push(hex::encode(&hash.as_slice()[1..2])); |
||||
path |
||||
} |
||||
|
||||
pub async fn write_block(garage: Arc<Garage>, hash: &Hash, data: &[u8]) -> Result<Message, Error> { |
||||
garage.fs_lock.lock().await; |
||||
|
||||
let mut path = block_dir(&garage, hash); |
||||
fs::create_dir_all(&path).await?; |
||||
|
||||
path.push(hex::encode(hash)); |
||||
if fs::metadata(&path).await.is_ok() { |
||||
return Ok(Message::Ok) |
||||
} |
||||
|
||||
let mut f = fs::File::create(path).await?; |
||||
f.write_all(data).await?; |
||||
drop(f); |
||||
|
||||
Ok(Message::Ok) |
||||
} |
||||
|
||||
pub async fn read_block(garage: Arc<Garage>, hash: &Hash) -> Result<Message, Error> { |
||||
let mut path = block_dir(&garage, hash); |
||||
path.push(hex::encode(hash)); |
||||
|
||||
let mut f = fs::File::open(path).await?; |
||||
let mut data = vec![]; |
||||
f.read_to_end(&mut data).await?; |
||||
|
||||
Ok(Message::PutBlock(PutBlockMessage{ |
||||
hash: hash.clone(), |
||||
data, |
||||
})) |
||||
} |
@ -0,0 +1,71 @@ |
||||
use std::sync::Arc; |
||||
use serde::{Serialize, Deserialize}; |
||||
use async_trait::async_trait; |
||||
use tokio::sync::RwLock; |
||||
|
||||
use crate::data::*; |
||||
use crate::table::*; |
||||
use crate::server::Garage; |
||||
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] |
||||
pub struct Version { |
||||
// Primary key
|
||||
pub version: UUID, |
||||
|
||||
// Actual data: the blocks for this version
|
||||
pub deleted: bool, |
||||
pub blocks: Vec<VersionBlock>, |
||||
|
||||
// Back link to bucket+key so that we can figure if
|
||||
// this was deleted later on
|
||||
pub bucket: String, |
||||
pub key: String, |
||||
} |
||||
|
||||
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] |
||||
pub struct VersionBlock { |
||||
pub offset: u64, |
||||
pub hash: Hash, |
||||
} |
||||
|
||||
impl Entry<Hash, EmptySortKey> for Version { |
||||
fn partition_key(&self) -> &Hash { |
||||
&self.version |
||||
} |
||||
fn sort_key(&self) -> &EmptySortKey { |
||||
&EmptySortKey |
||||
} |
||||
|
||||
fn merge(&mut self, other: &Self) { |
||||
if other.deleted { |
||||
self.deleted = true; |
||||
self.blocks.clear(); |
||||
} else if !self.deleted { |
||||
for bi in other.blocks.iter() { |
||||
match self.blocks.binary_search_by(|x| x.offset.cmp(&bi.offset)) { |
||||
Ok(_) => (), |
||||
Err(pos) => { |
||||
self.blocks.insert(pos, bi.clone()); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub struct VersionTable { |
||||
pub garage: RwLock<Option<Arc<Garage>>>, |
||||
} |
||||
|
||||
#[async_trait] |
||||
impl TableFormat for VersionTable { |
||||
type P = Hash; |
||||
type S = EmptySortKey; |
||||
type E = Version; |
||||
|
||||
async fn updated(&self, old: Option<&Self::E>, new: &Self::E) { |
||||
//unimplemented!()
|
||||
// TODO
|
||||
} |
||||
} |
Loading…
Reference in new issue