Skip to content

Commit

Permalink
Separated digest and encoding usage of legacy_encoding methods into t…
Browse files Browse the repository at this point in the history
…wo methods

Add digest_encoding method to spfs graph objects. Removed annotation writing from Layer's legacy_encoding, but not its digest_encoding.

size_for_legacy_encoding methods remain unchanged.

Signed-off-by: David Gilligan-Cook <dcook@imageworks.com>
  • Loading branch information
dcookspi committed Jun 6, 2024
1 parent fb88f32 commit 4296d8b
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 4 deletions.
9 changes: 9 additions & 0 deletions crates/spfs/src/graph/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,15 @@ impl<'buf> encoding::Digestible for Entry<'buf> {
}

impl<'buf> Entry<'buf> {
pub(super) fn digest_encode(&self, mut writer: &mut impl std::io::Write) -> Result<()> {
encoding::write_digest(&mut writer, self.object())?;
self.kind().encode(&mut writer)?;
encoding::write_uint64(&mut writer, self.mode() as u64)?;
encoding::write_uint64(&mut writer, self.size_for_legacy_encode())?;
encoding::write_string(writer, self.name())?;
Ok(())
}

pub(super) fn legacy_encode(&self, mut writer: &mut impl std::io::Write) -> Result<()> {
encoding::write_digest(&mut writer, self.object())?;
self.kind().encode(&mut writer)?;
Expand Down
16 changes: 15 additions & 1 deletion crates/spfs/src/graph/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ impl Layer {
children
}

pub(super) fn legacy_encode(&self, mut writer: &mut impl std::io::Write) -> Result<()> {
pub(super) fn digest_encode(&self, mut writer: &mut impl std::io::Write) -> Result<()> {
// Includes any annotations regardless of whether EncodingFormat setting
let annotations = self.annotations();
let result = if let Some(manifest_digest) = self.manifest() {
let manifest_result =
Expand All @@ -144,6 +145,19 @@ impl Layer {

result
}

pub(super) fn legacy_encode(&self, writer: &mut impl std::io::Write) -> Result<()> {
// Legacy encoded layers do not support writing annotations
let result = if let Some(manifest_digest) = self.manifest() {
encoding::write_digest(writer, manifest_digest).map_err(Error::Encoding)
} else {
Err(Error::String(
"Invalid Layer object for legacy encoding, it has no manifest data".to_string(),
))
};

result
}
}

impl std::hash::Hash for Layer {
Expand Down
13 changes: 13 additions & 0 deletions crates/spfs/src/graph/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,19 @@ impl Manifest {
manifest
}

pub(super) fn digest_encode(&self, mut writer: &mut impl std::io::Write) -> Result<()> {
self.root().digest_encode(&mut writer)?;
// this method encodes the root tree first, and does not
// include it in the count of remaining trees since at least
// one root is always required
encoding::write_uint64(&mut writer, self.proto().trees().len() as u64 - 1)?;
// skip the root tree when saving the rest
for tree in self.iter_trees().skip(1) {
tree.digest_encode(writer)?;
}
Ok(())
}

pub(super) fn legacy_encode(&self, mut writer: &mut impl std::io::Write) -> Result<()> {
self.root().legacy_encode(&mut writer)?;
// this method encodes the root tree first, and does not
Expand Down
6 changes: 3 additions & 3 deletions crates/spfs/src/graph/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,9 @@ impl<T: ObjectProto> encoding::Digestible for FlatObject<T> {
}
}
match variant {
Enum::Platform(obj) => obj.legacy_encode(&mut hasher)?,
Enum::Layer(obj) => obj.legacy_encode(&mut hasher)?,
Enum::Manifest(obj) => obj.legacy_encode(&mut hasher)?,
Enum::Platform(obj) => obj.digest_encode(&mut hasher)?,
Enum::Layer(obj) => obj.digest_encode(&mut hasher)?,
Enum::Manifest(obj) => obj.digest_encode(&mut hasher)?,
Enum::Blob(_obj) => unreachable!("handled above"),
}
Ok(hasher.digest())
Expand Down
13 changes: 13 additions & 0 deletions crates/spfs/src/graph/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,19 @@ impl Platform {
self.iter_bottom_up().copied().collect()
}

pub(super) fn digest_encode(&self, mut writer: &mut impl std::io::Write) -> Result<()> {
// use a vec to know the name ahead of time and
// avoid iterating the stack twice
let digests = self.iter_bottom_up().collect::<Vec<_>>();
encoding::write_uint64(&mut writer, digests.len() as u64)?;
// for historical reasons, and to remain backward-compatible, platform
// stacks are stored in reverse (top-down) order
for digest in digests.into_iter().rev() {
encoding::write_digest(&mut writer, digest)?;
}
Ok(())
}

pub(super) fn legacy_encode(&self, mut writer: &mut impl std::io::Write) -> Result<()> {
// use a vec to know the name ahead of time and
// avoid iterating the stack twice
Expand Down
12 changes: 12 additions & 0 deletions crates/spfs/src/graph/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ impl<'buf> Tree<'buf> {
self.entries().find(|entry| entry.name() == name.as_ref())
}

pub(super) fn digest_encode(&self, mut writer: &mut impl std::io::Write) -> Result<()> {
let mut entries: Vec<_> = self.entries().collect();
encoding::write_uint64(&mut writer, entries.len() as u64)?;
// this is not the default sort mode for entries but
// matches the existing compatible encoding order
entries.sort_unstable_by_key(|e| e.name());
for entry in entries.into_iter() {
entry.digest_encode(writer)?;
}
Ok(())
}

pub(super) fn legacy_encode(&self, mut writer: &mut impl std::io::Write) -> Result<()> {
let mut entries: Vec<_> = self.entries().collect();
encoding::write_uint64(&mut writer, entries.len() as u64)?;
Expand Down

0 comments on commit 4296d8b

Please sign in to comment.