use std::io::{ErrorKind, Result};
use aws_sdk_s3::Client;
use crate::config::HyperFileConfig;
use crate::meta_loader::s3::S3BlockLoader;
use crate::staging::{Staging, StagingIntercept, config::StagingConfig, s3::S3Staging};
use crate::node_cache::localdisk::LocalDiskNodeCache;
use super::file::HyperFile;
use super::flags::HyperFileFlags;
use super::mode::HyperFileMode;
pub struct Hyper<'a> {
pub(crate) inner: HyperFile<'a, S3Staging, S3BlockLoader, LocalDiskNodeCache>,
}
impl<'a: 'static> Hyper<'a> {
pub(crate) async fn do_open_or_create(client: Client, file_config: HyperFileConfig, flags: HyperFileFlags, mode: HyperFileMode, create: bool) -> Result<Self>
{
if create && flags.is_excl() {
return Self::create(client, file_config, flags, mode).await;
}
match Self::open(client.clone(), file_config.clone(), flags.clone()).await {
Ok(hyper) => {
return Ok(hyper);
},
Err(e) => {
if create && e.kind() == ErrorKind::NotFound {
return Self::create(client, file_config, flags, mode).await;
}
return Err(e);
}
}
}
pub async fn open(client: Client, file_config: HyperFileConfig, flags: HyperFileFlags) -> Result<Self>
{
let staging = S3Staging::from(&client, file_config.staging.clone(), file_config.runtime.clone()).await?;
let loader = staging.to_block_loader();
let node_cache = LocalDiskNodeCache::from(&file_config.node_cache).await;
let mut file = HyperFile::<S3Staging, S3BlockLoader, LocalDiskNodeCache>::open(staging, loader, node_cache, file_config, flags.clone()).await?;
if flags.is_trunc() && flags.write {
file.truncate(0).await?;
}
Ok(Self {
inner: file,
})
}
pub async fn create(client: Client, file_config: HyperFileConfig, flags: HyperFileFlags, mode: HyperFileMode) -> Result<Self>
{
let staging = S3Staging::create(&client, file_config.staging.clone(), file_config.runtime.clone()).await?;
let loader = staging.to_block_loader();
let node_cache = LocalDiskNodeCache::from(&file_config.node_cache).await;
let file = HyperFile::<S3Staging, S3BlockLoader, LocalDiskNodeCache>::new(staging, loader, node_cache, file_config, flags, mode).await?;
Ok(Self {
inner: file,
})
}
pub async fn create_with_interceptor(client: Client, file_config: HyperFileConfig, flags: HyperFileFlags, mode: HyperFileMode, interceptor: impl StagingIntercept<S3Staging> + 'static) -> Result<Self>
{
let mut staging = S3Staging::create(&client, file_config.staging.clone(), file_config.runtime.clone()).await?;
staging.interceptor(interceptor);
let loader = staging.to_block_loader();
let node_cache = LocalDiskNodeCache::from(&file_config.node_cache).await;
let file = HyperFile::<S3Staging, S3BlockLoader, LocalDiskNodeCache>::new(staging, loader, node_cache, file_config, flags, mode).await?;
Ok(Self {
inner: file,
})
}
pub async fn stat_fast(client: Client, file_config: HyperFileConfig) -> Result<libc::stat>
{
let staging = S3Staging::from(&client, file_config.staging.clone(), file_config.runtime.clone()).await?;
HyperFile::<S3Staging, S3BlockLoader, LocalDiskNodeCache>::stat_fast(staging).await
}
pub async fn update_stat_fast(client: Client, file_config: HyperFileConfig, stat: &libc::stat) -> Result<libc::stat>
{
let staging = S3Staging::from(&client, file_config.staging.clone(), file_config.runtime.clone()).await?;
HyperFile::<S3Staging, S3BlockLoader, LocalDiskNodeCache>::update_stat_fast(staging, stat).await
}
}
impl<'a: 'static> Hyper<'a> {
pub fn staging_config(&self) -> &StagingConfig {
self.inner.staging_config()
}
pub fn with_staging_interceptor(&mut self, i: impl StagingIntercept<S3Staging> + 'static) {
self.inner.staging_interceptor(i)
}
#[doc(hidden)]
pub fn dirty_block_count(&self) -> usize {
self.inner.dirty_block_count()
}
#[doc(hidden)]
pub fn is_attr_dirty(&self) -> bool {
self.inner.is_attr_dirty()
}
#[doc(hidden)]
pub fn is_bmap_dirty(&self) -> bool {
self.inner.is_bmap_dirty()
}
#[doc(hidden)]
pub fn in_memory_last_cno(&self) -> u64 {
self.inner.in_memory_last_cno()
}
#[doc(hidden)]
pub fn in_memory_last_ondisk_cno(&self) -> u64 {
self.inner.in_memory_last_ondisk_cno()
}
pub fn read_timing(&self) -> &crate::file::ReadTiming {
self.inner.read_timing()
}
pub fn read_timing_reset(&self) {
self.inner.read_timing_reset()
}
#[doc(hidden)]
pub fn flush_timing(&self) -> &crate::file::FlushTiming {
self.inner.flush_timing()
}
#[doc(hidden)]
pub fn flush_timing_reset(&self) {
self.inner.flush_timing_reset()
}
}