[pbs-devel] [RFC pxar 4/20] fix #3174: metadata: impl fn to calc byte size

Christian Ebner c.ebner at proxmox.com
Thu Sep 28 10:07:40 CEST 2023


I was giving this some more thought and are not really convinced that sending
this trough an encoder instance, which digests the encoded byte stream and counts
the bytes is the right approach here.

The purpose of this function is to calculate the bytes, which I can easily skip over
*without* having to call any expensive encoding/decoding functionality.
I might get around this by simply calling the decoder on the byte stream, than I do
not need this at all (if I'm not missing something). Might that be the better approach?

Additionally, and maybe even better, I might get rid of this also by letting the
PXAR_APPENDIX_REF offset point to the start of the file payload entry, instead of the
file entry as is now, thereby being able to blindly skip over this already to begin with.
Although I am not sure if that is the best approach for handling the metadata, which should
ideally not be encoded twice, once before the PXAR_APPENDIX_REF and the PXAR_PAYLOAD.

> On 27.09.2023 13:55 CEST Christian Ebner <c.ebner at proxmox.com> wrote:
> 
>  
> > On 27.09.2023 13:38 CEST Wolfgang Bumiller <w.bumiller at proxmox.com> wrote:
> > 
> >  
> > On Fri, Sep 22, 2023 at 09:16:05AM +0200, Christian Ebner wrote:
> > > Add a helper function to calculate the byte size of pxar Metadata
> > > objects, needed to be able to recalculate offsets when creating archives
> > > with appendix sections.
> > > 
> > > Signed-off-by: Christian Ebner <c.ebner at proxmox.com>
> > > ---
> > >  src/lib.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 44 insertions(+)
> > > 
> > > diff --git a/src/lib.rs b/src/lib.rs
> > > index 210c4b1..ed7ba40 100644
> > > --- a/src/lib.rs
> > > +++ b/src/lib.rs
> > > @@ -144,6 +144,50 @@ impl Metadata {
> > >      pub fn builder_from_stat(stat: &libc::stat) -> MetadataBuilder {
> > >          MetadataBuilder::new(0).fill_from_stat(stat)
> > >      }
> > > +
> > > +    /// Calculate the number of bytes when serialized in pxar archive
> > > +    pub fn calculate_byte_len(&self) -> usize {
> > 
> > This looks like a maintenance nightmare with extra sprinkles.
> 
> ;)
> 
> > 
> > Can we instead create a specialized `SeqWrite` type that just counts
> > bytes instead of actually writing anything and call the encoder's
> > `encode_metadata()` with it?
> > (Either by factorizing `encode_metadat()` out further or by creating an
> > actual `EncoderImpl` instance with it...)
> 
> Yes, I will have a look on how to improve this and include this as well in the next version of the patch series, thx for the hints.
> 
> > 
> > > +        let mut bytes = mem::size_of::<format::Header>();
> > > +        bytes += mem::size_of_val(&self.stat);
> > > +        for xattr in &self.xattrs {
> > > +            bytes += mem::size_of::<format::Header>();
> > > +            bytes += mem::size_of_val(xattr);
> > > +        }
> > > +        for acl_user in &self.acl.users {
> > > +            bytes += mem::size_of::<format::Header>();
> > > +            bytes += mem::size_of_val(acl_user);
> > > +        }
> > > +        for acl_group in &self.acl.groups {
> > > +            bytes += mem::size_of::<format::Header>();
> > > +            bytes += mem::size_of_val(acl_group);
> > > +        }
> > > +        if let Some(group_obj) = &self.acl.group_obj {
> > > +            bytes += mem::size_of::<format::Header>();
> > > +            bytes += mem::size_of_val(group_obj);
> > > +        }
> > > +        if let Some(default) = &self.acl.default {
> > > +            bytes += mem::size_of::<format::Header>();
> > > +            bytes += mem::size_of_val(default);
> > > +        }
> > > +        for acl_default_user in &self.acl.default_users {
> > > +            bytes += mem::size_of::<format::Header>();
> > > +            bytes += mem::size_of_val(acl_default_user);
> > > +        }
> > > +        for acl_default_group in &self.acl.default_groups {
> > > +            bytes += mem::size_of::<format::Header>();
> > > +            bytes += mem::size_of_val(acl_default_group);
> > > +        }
> > > +        if let Some(fcaps) = &self.fcaps {
> > > +            bytes += mem::size_of::<format::Header>();
> > > +            bytes += mem::size_of_val(fcaps);
> > > +        }
> > > +        if let Some(quota_project_id) = &self.quota_project_id {
> > > +            bytes += mem::size_of::<format::Header>();
> > > +            bytes += mem::size_of_val(quota_project_id);
> > > +        }
> > > +
> > > +        bytes
> > > +    }
> > >  }
> > >  
> > >  impl From<MetadataBuilder> for Metadata {
> > > -- 
> > > 2.39.2





More information about the pbs-devel mailing list