Skip to content

Commit

Permalink
document loose::Object entirely
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Oct 10, 2020
1 parent b9e0a87 commit d5eef9c
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 1 deletion.
1 change: 1 addition & 0 deletions git-odb/src/loose/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! An object database storing each object in a zlib compressed file with its hash in the path
const HEADER_READ_COMPRESSED_BYTES: usize = 256;
const HEADER_READ_UNCOMPRESSED_BYTES: usize = 512;

Expand Down
12 changes: 11 additions & 1 deletion git-odb/src/loose/object/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,25 @@ pub enum Error {
},
}

// Decoding and streaming
impl loose::Object {
/// **Note**: Blobs are loaded into memory and are made available that way.
/// Decode the object to make it's fields accessible in case of Trees, Tags and Commits.
///
/// This is a zero-copy operation with data read from disk if needed and stored in memory.
/// The returned [`borrowed::Object`] references this data where possible.
///
/// **Note**: Blobs are also loaded into memory and are made available that way.
/// Consider using `stream()` if large Blobs are expected.
pub fn decode(&mut self) -> Result<borrowed::Object<'_>, Error> {
self.decompress_all()?;
let bytes = &self.decompressed_data[self.header_size..];
Ok(borrowed::Object::from_bytes(self.kind, bytes)?)
}

/// Returns an implementation of [`std::io::Read`], which decompresses the objects data on the fly.
///
/// **Note**: This is most useful for big blobs as these won't be read into memory in full. Use [`decode()`][loose::Object::decode()] for
/// Trees, Tags and Commits instead for convenient access to their payload.
pub fn stream(&mut self) -> Result<stream::Reader<'_>, Error> {
match &self.path {
Some(path) => Ok(stream::Reader::from_read(
Expand Down
5 changes: 5 additions & 0 deletions git-odb/src/loose/object/header.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! loose object header encoding and decoding
use byteorder::WriteBytesExt;
use git_object as object;

Expand All @@ -15,6 +16,9 @@ pub enum Error {
ObjectHeader(#[from] object::Error),
}

/// Decode a loose object header, being `<kind> <size>\0`, returns ([`Kind`][object::Kind], `size`, `consumed bytes`).
///
/// `size` is the uncompressed size of the payload in bytes.
pub fn decode(input: &[u8]) -> Result<(object::Kind, u64, usize), Error> {
let header_end = input
.iter()
Expand Down Expand Up @@ -46,6 +50,7 @@ fn kind_to_bytes_with_space(object: object::Kind) -> &'static [u8] {
}
}

/// Encode the objects `Kind` and `size` into a format suitable for use with [`decode()`].
pub fn encode(object: object::Kind, size: u64, mut out: impl std::io::Write) -> Result<usize, std::io::Error> {
let mut written = out.write(kind_to_bytes_with_space(object))?;
written += itoa::write(&mut out, size)?;
Expand Down
3 changes: 3 additions & 0 deletions git-odb/src/loose/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ use git_object as object;
use smallvec::SmallVec;
use std::path::PathBuf;

/// A representation of a loose object on disk, which is fully or partially read into memory
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
pub struct Object {
/// The kind of object
pub kind: object::Kind,
/// The uncompressed size of the object's data/payload
pub size: usize,
pub(crate) decompressed_data: SmallVec<[u8; HEADER_READ_UNCOMPRESSED_BYTES]>,
pub(crate) compressed_data: SmallVec<[u8; HEADER_READ_COMPRESSED_BYTES]>,
Expand Down
1 change: 1 addition & 0 deletions git-odb/src/loose/object/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub enum Reader<'a> {
Buffer(&'a [u8]),
}

/// A [`Read`][std::io::Read] implementation for reading from a file or from borrowed data.
impl<'a> Reader<'a> {
pub fn from_read(header_size: usize, file: std::fs::File) -> Reader<'a> {
Reader::File(header_size, InflateReader::from_read(std::io::BufReader::new(file)))
Expand Down
3 changes: 3 additions & 0 deletions git-odb/src/loose/object/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ pub enum Error {
}

impl loose::Object {
/// Generate the git hash of this object, reading it in the process, and compare it with the given `desired` [Id][borrowed::Id].
///
/// Returns an error with the actual id if the hashes don't match.
pub fn verify_checksum(&mut self, desired: borrowed::Id<'_>) -> Result<(), Error> {
let mut sink = HashWrite::new(io::sink(), desired.kind());
let (kind, size) = (self.kind, self.size);
Expand Down

0 comments on commit d5eef9c

Please sign in to comment.