Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Store complete inside bits and add more examples #1397

Merged
merged 2 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions src/layers/complete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,16 +292,21 @@ impl<A: Accessor> LayeredAccessor for CompleteReaderAccessor<A> {
}

async fn stat(&self, path: &str, args: OpStat) -> Result<RpStat> {
self.inner
.stat(path, args)
.await
.map(|v| v.map_metadata(|m| m.with_complete()))
self.inner.stat(path, args).await.map(|v| {
v.map_metadata(|m| {
let bit = m.bit();
m.with_bit(bit | ObjectMetadataKey::Complete)
})
})
}

fn blocking_stat(&self, path: &str, args: OpStat) -> Result<RpStat> {
self.inner
.blocking_stat(path, args)
.map(|v| v.map_metadata(|m| m.with_complete()))
self.inner.blocking_stat(path, args).map(|v| {
v.map_metadata(|m| {
let bit = m.bit();
m.with_bit(bit | ObjectMetadataKey::Complete)
})
})
}

async fn list(&self, path: &str, args: OpList) -> Result<(RpList, Self::Pager)> {
Expand Down
35 changes: 18 additions & 17 deletions src/object/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ use crate::*;
/// a.k.a., `Entry`'s content length could be `None`.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ObjectMetadata {
/// Mark if this metadata is complete or not.
complete: bool,
/// bit stores current key store.
bit: FlagSet<ObjectMetadataKey>,

Expand All @@ -55,11 +53,15 @@ pub struct ObjectMetadata {
impl ObjectMetadata {
/// Create a new object metadata
pub fn new(mode: ObjectMode) -> Self {
Self {
// If mode is dir, we will set complete to true.
complete: mode == ObjectMode::DIR,
bit: ObjectMetadataKey::Mode.into(),
// Mode is required to be set for object metadata.
let mut bit = ObjectMetadataKey::Mode.into();
// If object mode is dir, we should always mark it as complete.
if mode == ObjectMode::DIR {
bit |= ObjectMetadataKey::Complete
}

Self {
bit,
mode,

content_length: None,
Expand All @@ -72,22 +74,17 @@ impl ObjectMetadata {
}
}

/// If this object metadata if complete
pub(crate) fn is_complete(&self) -> bool {
self.complete
}

/// Make this object metadata if complete.
pub(crate) fn with_complete(mut self) -> Self {
self.complete = true;
self
}

/// Get the bit from object metadata.
pub(crate) fn bit(&self) -> FlagSet<ObjectMetadataKey> {
self.bit
}

/// Set bit with given.
pub(crate) fn with_bit(mut self, bit: impl Into<FlagSet<ObjectMetadataKey>>) -> Self {
self.bit = bit.into();
self
}

/// Object mode represent this object's mode.
pub fn mode(&self) -> ObjectMode {
self.mode
Expand Down Expand Up @@ -358,6 +355,10 @@ flags! {
/// the meta has been stored, we will return directly. If no, we will
/// call `stat` internally to fecth the metadata.
pub enum ObjectMetadataKey: u64 {
/// The special object metadata key that used to mark this object
/// already contains all metadata.
Complete,

/// Key for mode.
Mode,
/// Key for content disposition.
Expand Down
109 changes: 91 additions & 18 deletions src/object/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1237,18 +1237,39 @@ impl Object {
///
/// # Examples
///
/// ## Query already cached metadata
///
/// By query metadata with `None`, we can only query in-memory metadata
/// cache. In this way, we can make sure that no API call will send.
///
/// ```
/// # use anyhow::Result;
/// # use opendal::Operator;
/// use opendal::ErrorKind;
/// #
/// # #[tokio::main]
/// # async fn test(op: Operator) -> Result<()> {
/// let meta = op.object("test").metadata(None).await?;
/// let _ = meta.content_length();
/// let _ = meta.content_type();
/// # Ok(())
/// # }
/// ```
///
/// ## Query content length and content type
///
/// ```
/// # use anyhow::Result;
/// # use futures::io;
/// # use opendal::Operator;
/// use opendal::ErrorKind;
/// use opendal::ObjectMetadataKey;
/// #
/// # #[tokio::main]
/// # async fn test(op: Operator) -> Result<()> {
/// let meta = op
/// .object("test")
/// .metadata({
/// use opendal::ObjectMetadataKey::*;
/// use ObjectMetadataKey::*;
/// ContentLength | ContentType
/// })
/// .await?;
Expand All @@ -1257,15 +1278,34 @@ impl Object {
/// # Ok(())
/// # }
/// ```
///
/// ## Query all metadata
///
/// By query metadata with `Complete`, we can make sure that we have fetched all metadata of this object.
///
/// ```
/// # use anyhow::Result;
/// # use opendal::Operator;
/// use opendal::ErrorKind;
/// use opendal::ObjectMetadataKey;
/// #
/// # #[tokio::main]
/// # async fn test(op: Operator) -> Result<()> {
/// let meta = op
/// .object("test")
/// .metadata({ ObjectMetadataKey::Complete })
/// .await?;
/// let _ = meta.content_length();
/// let _ = meta.content_type();
/// # Ok(())
/// # }
/// ```
pub async fn metadata(
&mut self,
flags: impl Into<FlagSet<ObjectMetadataKey>>,
) -> Result<Arc<ObjectMetadata>> {
if let Some(meta) = &self.meta {
if meta.is_complete() {
return Ok(meta.clone());
}
if meta.bit().contains(flags) {
if meta.bit().contains(flags) || meta.bit().contains(ObjectMetadataKey::Complete) {
return Ok(meta.clone());
}
}
Expand Down Expand Up @@ -1302,21 +1342,57 @@ impl Object {
///
/// # Examples
///
/// ## Query already cached metadata
///
/// By query metadata with `None`, we can only query in-memory metadata
/// cache. In this way, we can make sure that no API call will send.
///
/// ```
/// # use anyhow::Result;
/// # use futures::io;
/// # use opendal::Operator;
/// use opendal::ErrorKind;
/// #
/// # #[tokio::main]
/// # async fn test(op: Operator) -> Result<()> {
/// # fn test(op: Operator) -> Result<()> {
/// let meta = op.object("test").blocking_metadata(None)?;
/// let _ = meta.content_length();
/// let _ = meta.content_type();
/// # Ok(())
/// # }
/// ```
///
/// ## Query content length and content type
///
/// ```
/// # use anyhow::Result;
/// # use opendal::Operator;
/// use opendal::ErrorKind;
/// use opendal::ObjectMetadataKey;
/// #
/// # fn test(op: Operator) -> Result<()> {
/// let meta = op.object("test").blocking_metadata({
/// use ObjectMetadataKey::*;
/// ContentLength | ContentType
/// })?;
/// let _ = meta.content_length();
/// let _ = meta.content_type();
/// # Ok(())
/// # }
/// ```
///
/// ## Query all metadata
///
/// By query metadata with `Complete`, we can make sure that we have fetched all metadata of this object.
///
/// ```
/// # use anyhow::Result;
/// # use opendal::Operator;
/// use opendal::ErrorKind;
/// use opendal::ObjectMetadataKey;
/// #
/// # fn test(op: Operator) -> Result<()> {
/// let meta = op
/// .object("test")
/// .metadata({
/// use opendal::ObjectMetadataKey::*;
/// ContentLength | ContentType
/// })
/// .await?;
/// .blocking_metadata({ ObjectMetadataKey::Complete })?;
/// let _ = meta.content_length();
/// let _ = meta.content_type();
/// # Ok(())
Expand All @@ -1327,10 +1403,7 @@ impl Object {
flags: impl Into<FlagSet<ObjectMetadataKey>>,
) -> Result<Arc<ObjectMetadata>> {
if let Some(meta) = &self.meta {
if meta.is_complete() {
return Ok(meta.clone());
}
if meta.bit().contains(flags) {
if meta.bit().contains(flags) || meta.bit().contains(ObjectMetadataKey::Complete) {
return Ok(meta.clone());
}
}
Expand Down