Skip to content

Commit

Permalink
Merge branch 'read-header'
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Dec 18, 2022
2 parents fbce7bb + 8c9c243 commit 3d01252
Show file tree
Hide file tree
Showing 44 changed files with 1,208 additions and 336 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions git-odb/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ mod impls {
use git_object::{Data, Kind};
use git_pack::cache::Object;

use crate::find::Header;
use crate::{pack::data::entry::Location, Cache};

impl<S> crate::Write for Cache<S>
Expand Down Expand Up @@ -167,6 +168,17 @@ mod impls {
}
}

impl<S> crate::Header for Cache<S>
where
S: crate::Header,
{
type Error = S::Error;

fn try_header(&self, id: impl AsRef<oid>) -> Result<Option<Header>, Self::Error> {
self.inner.try_header(id)
}
}

impl<S> git_pack::Find for Cache<S>
where
S: git_pack::Find,
Expand Down
98 changes: 56 additions & 42 deletions git-odb/src/find.rs
Original file line number Diff line number Diff line change
@@ -1,45 +1,3 @@
/// A way to indicate if a lookup, despite successful, was ambiguous or yielded exactly
/// one result in the particular index.
// TODO: find better name, ambiguous with git_pack::index::PrefixLookupResult (entry_index inside)
pub type PrefixLookupResult = Result<git_hash::ObjectId, ()>;

/// A potentially ambiguous prefix for use with `Handle::disambiguate_prefix()`.
#[derive(Debug, Copy, Clone)]
pub struct PotentialPrefix {
id: git_hash::ObjectId,
hex_len: usize,
}

impl PotentialPrefix {
/// Create a new potentially ambiguous prefix from an `id` and the desired minimal `hex_len`.
///
/// It is considered ambiguous until it's disambiguated by validating that there is only a single object
/// matching this prefix.
pub fn new(id: impl Into<git_hash::ObjectId>, hex_len: usize) -> Result<Self, git_hash::prefix::Error> {
let id = id.into();
git_hash::Prefix::new(id, hex_len)?;
Ok(PotentialPrefix { id, hex_len })
}

/// Transform ourselves into a `Prefix` with our current hex lengths.
pub fn to_prefix(&self) -> git_hash::Prefix {
git_hash::Prefix::new(self.id, self.hex_len).expect("our hex-len to always be in bounds")
}

pub(crate) fn inc_hex_len(&mut self) {
self.hex_len += 1;
assert!(self.hex_len <= self.id.kind().len_in_hex());
}

pub(crate) fn id(&self) -> &git_hash::oid {
&self.id
}

pub(crate) fn hex_len(&self) -> usize {
self.hex_len
}
}

///
pub mod existing {
use git_hash::ObjectId;
Expand Down Expand Up @@ -90,3 +48,59 @@ pub mod existing_iter {
ObjectKind { expected: git_object::Kind },
}
}

/// An object header informing about object properties, without it being fully decoded in the process.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Header {
/// The object was not packed, but is currently located in the loose object portion of the database.
///
/// As packs are searched first, this means that in this very moment, the object whose header we retrieved is unique
/// in the object database.
Loose {
/// The kind of the object.
kind: git_object::Kind,
/// The size of the object's data in bytes.
size: u64,
},
/// The object was present in a pack.
///
/// Note that this does not imply it is unique in the database, as it might be present in more than one pack and even
/// as loose object.
Packed(git_pack::data::decode::header::Outcome),
}

mod header {
use super::Header;

impl Header {
/// Return the object kind of the object we represent.
pub fn kind(&self) -> git_object::Kind {
match self {
Header::Packed(out) => out.kind,
Header::Loose { kind, .. } => *kind,
}
}
/// Return the size of the object in bytes.
pub fn size(&self) -> u64 {
match self {
Header::Packed(out) => out.object_size,
Header::Loose { size, .. } => *size,
}
}
}

impl From<git_pack::data::decode::header::Outcome> for Header {
fn from(packed_header: git_pack::data::decode::header::Outcome) -> Self {
Header::Packed(packed_header)
}
}

impl From<(usize, git_object::Kind)> for Header {
fn from((object_size, kind): (usize, git_object::Kind)) -> Self {
Header::Loose {
kind,
size: object_size as u64,
}
}
}
}
2 changes: 1 addition & 1 deletion git-odb/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub mod find;
/// An object database equivalent to `/dev/null`, dropping all objects stored into it.
mod traits;

pub use traits::{Find, FindExt, Write};
pub use traits::{Find, FindExt, Header, HeaderExt, Write};

/// A thread-local handle to access any object.
pub type Handle = Cache<store::Handle<OwnShared<Store>>>;
Expand Down
Loading

0 comments on commit 3d01252

Please sign in to comment.