diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
commit | c23a457e72abe608715ac76f076f47dc42af07a5 (patch) | |
tree | 2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/gix-ref/src/store/packed | |
parent | Releasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-ref/src/store/packed')
-rw-r--r-- | vendor/gix-ref/src/store/packed/buffer.rs | 14 | ||||
-rw-r--r-- | vendor/gix-ref/src/store/packed/decode.rs | 76 | ||||
-rw-r--r-- | vendor/gix-ref/src/store/packed/decode/tests.rs | 32 | ||||
-rw-r--r-- | vendor/gix-ref/src/store/packed/find.rs | 21 | ||||
-rw-r--r-- | vendor/gix-ref/src/store/packed/iter.rs | 24 | ||||
-rw-r--r-- | vendor/gix-ref/src/store/packed/transaction.rs | 10 |
6 files changed, 101 insertions, 76 deletions
diff --git a/vendor/gix-ref/src/store/packed/buffer.rs b/vendor/gix-ref/src/store/packed/buffer.rs index 6786e4a9f..333be9517 100644 --- a/vendor/gix-ref/src/store/packed/buffer.rs +++ b/vendor/gix-ref/src/store/packed/buffer.rs @@ -20,6 +20,7 @@ pub mod open { use std::path::PathBuf; use memmap2::Mmap; + use winnow::{prelude::*, stream::Offset}; use crate::store_impl::packed; @@ -29,8 +30,7 @@ pub mod open { /// /// In order to allow fast lookups and optimizations, the contents of the packed refs must be sorted. /// If that's not the case, they will be sorted on the fly with the data being written into a memory buffer. - pub fn open(path: impl Into<PathBuf>, use_memory_map_if_larger_than_bytes: u64) -> Result<Self, Error> { - let path = path.into(); + pub fn open(path: PathBuf, use_memory_map_if_larger_than_bytes: u64) -> Result<Self, Error> { let (backing, offset) = { let backing = if std::fs::metadata(&path)?.len() <= use_memory_map_if_larger_than_bytes { packed::Backing::InMemory(std::fs::read(&path)?) @@ -45,10 +45,12 @@ pub mod open { }; let (offset, sorted) = { - let data = backing.as_ref(); - if *data.first().unwrap_or(&b' ') == b'#' { - let (records, header) = packed::decode::header::<()>(data).map_err(|_| Error::HeaderParsing)?; - let offset = records.as_ptr() as usize - data.as_ptr() as usize; + let mut input = backing.as_ref(); + if *input.first().unwrap_or(&b' ') == b'#' { + let header = packed::decode::header::<()> + .parse_next(&mut input) + .map_err(|_| Error::HeaderParsing)?; + let offset = input.offset_from(&backing.as_ref()); (offset, header.sorted) } else { (0, false) diff --git a/vendor/gix-ref/src/store/packed/decode.rs b/vendor/gix-ref/src/store/packed/decode.rs index f8825459e..b4f8e8562 100644 --- a/vendor/gix-ref/src/store/packed/decode.rs +++ b/vendor/gix-ref/src/store/packed/decode.rs @@ -1,12 +1,11 @@ use std::convert::TryInto; use gix_object::bstr::{BStr, ByteSlice}; -use nom::{ - bytes::complete::{tag, take_while}, - combinator::{map, map_res, opt}, - error::{FromExternalError, ParseError}, - sequence::{delimited, preceded, terminated, tuple}, - IResult, +use winnow::{ + combinator::{delimited, opt, preceded, terminated}, + error::{FromExternalError, ParserError}, + prelude::*, + token::take_while, }; use crate::{ @@ -37,46 +36,47 @@ impl Default for Header { } } -fn until_newline<'a, E>(input: &'a [u8]) -> IResult<&'a [u8], &'a BStr, E> +fn until_newline<'a, E>(input: &mut &'a [u8]) -> PResult<&'a BStr, E> where - E: ParseError<&'a [u8]>, + E: ParserError<&'a [u8]>, { - map( - terminated(take_while(|b: u8| b != b'\r' && b != b'\n'), newline), - |not_newline| not_newline.as_bstr(), - )(input) + terminated(take_while(0.., |b: u8| b != b'\r' && b != b'\n'), newline) + .map(ByteSlice::as_bstr) + .parse_next(input) } -pub fn header<'a, E>(input: &'a [u8]) -> IResult<&'a [u8], Header, E> +pub fn header<'a, E>(input: &mut &'a [u8]) -> PResult<Header, E> where - E: ParseError<&'a [u8]>, + E: ParserError<&'a [u8]>, { - let (rest, traits) = preceded(tag(b"# pack-refs with: "), until_newline)(input)?; - - let mut peeled = Peeled::Unspecified; - let mut sorted = false; - for token in traits.as_bstr().split_str(b" ") { - if token == b"fully-peeled" { - peeled = Peeled::Fully; - } else if token == b"peeled" { - peeled = Peeled::Partial; - } else if token == b"sorted" { - sorted = true; - } - } - - Ok((rest, Header { peeled, sorted })) + preceded(b"# pack-refs with: ", until_newline) + .map(|traits| { + let mut peeled = Peeled::Unspecified; + let mut sorted = false; + for token in traits.as_bstr().split_str(b" ") { + if token == b"fully-peeled" { + peeled = Peeled::Fully; + } else if token == b"peeled" { + peeled = Peeled::Partial; + } else if token == b"sorted" { + sorted = true; + } + } + Header { peeled, sorted } + }) + .parse_next(input) } -pub fn reference<'a, E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], crate::name::Error>>( - input: &'a [u8], -) -> IResult<&'a [u8], packed::Reference<'a>, E> { - let (input, (target, name)) = tuple(( - terminated(hex_hash, tag(b" ")), - map_res(until_newline, TryInto::try_into), - ))(input)?; - let (rest, object) = opt(delimited(tag(b"^"), hex_hash, newline))(input)?; - Ok((rest, packed::Reference { name, target, object })) +pub fn reference<'a, E: ParserError<&'a [u8]> + FromExternalError<&'a [u8], crate::name::Error>>( + input: &mut &'a [u8], +) -> PResult<packed::Reference<'a>, E> { + ( + terminated(hex_hash, b" "), + until_newline.try_map(TryInto::try_into), + opt(delimited(b"^", hex_hash, newline)), + ) + .map(|(target, name, object)| packed::Reference { name, target, object }) + .parse_next(input) } #[cfg(test)] diff --git a/vendor/gix-ref/src/store/packed/decode/tests.rs b/vendor/gix-ref/src/store/packed/decode/tests.rs index 6c8f315c1..e864ee999 100644 --- a/vendor/gix-ref/src/store/packed/decode/tests.rs +++ b/vendor/gix-ref/src/store/packed/decode/tests.rs @@ -1,7 +1,7 @@ type Result = std::result::Result<(), Box<dyn std::error::Error>>; mod reference { - use nom::error::VerboseError; + use winnow::{error::TreeError, prelude::*}; use super::Result; use crate::{ @@ -16,9 +16,13 @@ mod reference { #[test] fn invalid() { - assert!(decode::reference::<()>(b"# what looks like a comment",).is_err()); + assert!(decode::reference::<()> + .parse_peek(b"# what looks like a comment",) + .is_err()); assert!( - decode::reference::<()>(b"^e9cdc958e7ce2290e2d7958cdb5aa9323ef35d37\n",).is_err(), + decode::reference::<()> + .parse_peek(b"^e9cdc958e7ce2290e2d7958cdb5aa9323ef35d37\n",) + .is_err(), "lonely peel" ); } @@ -27,7 +31,7 @@ mod reference { fn two_refs_in_a_row() -> Result { let input: &[u8] = b"d53c4b0f91f1b29769c9430f2d1c0bcab1170c75 refs/heads/alternates-after-packs-and-loose ^e9cdc958e7ce2290e2d7958cdb5aa9323ef35d37\neaae9c1bc723209d793eb93f5587fa2604d5cd92 refs/heads/avoid-double-lookup\n"; - let (input, parsed) = decode::reference::<VerboseError<_>>(input)?; + let (input, parsed) = decode::reference::<TreeError<_>>.parse_peek(input).unwrap(); assert_eq!( parsed, @@ -40,7 +44,7 @@ mod reference { assert_eq!(parsed.target(), hex_to_id("d53c4b0f91f1b29769c9430f2d1c0bcab1170c75")); assert_eq!(parsed.object(), hex_to_id("e9cdc958e7ce2290e2d7958cdb5aa9323ef35d37")); - let (input, parsed) = decode::reference::<VerboseError<_>>(input)?; + let (input, parsed) = decode::reference::<TreeError<_>>.parse_peek(input).unwrap(); assert!(input.is_empty(), "exhausted"); assert_eq!( parsed.name, @@ -55,6 +59,7 @@ mod reference { mod header { use gix_object::bstr::ByteSlice; use gix_testtools::to_bstr_err; + use winnow::prelude::*; use super::Result; use crate::store_impl::packed::{ @@ -65,12 +70,15 @@ mod header { #[test] fn invalid() { assert!( - decode::header::<()>(b"# some user comment").is_err(), + decode::header::<()>.parse_peek(b"# some user comment").is_err(), "something the user put there" ); - assert!(decode::header::<()>(b"# pack-refs: ").is_err(), "looks right but isn't"); assert!( - decode::header::<()>(b" # pack-refs with: ").is_err(), + decode::header::<()>.parse_peek(b"# pack-refs: ").is_err(), + "looks right but isn't" + ); + assert!( + decode::header::<()>.parse_peek(b" # pack-refs with: ").is_err(), "does not start with #" ); } @@ -78,7 +86,9 @@ mod header { #[test] fn valid_fully_peeled_stored() -> Result { let input: &[u8] = b"# pack-refs with: peeled fully-peeled sorted \nsomething else"; - let (rest, header) = decode::header::<nom::error::VerboseError<_>>(input).map_err(to_bstr_err)?; + let (rest, header) = decode::header::<winnow::error::TreeError<_, _>> + .parse_peek(input) + .map_err(to_bstr_err)?; assert_eq!(rest.as_bstr(), "something else", "remainder starts after newline"); assert_eq!( @@ -94,7 +104,7 @@ mod header { #[test] fn valid_peeled_unsorted() -> Result { let input: &[u8] = b"# pack-refs with: peeled\n"; - let (rest, header) = decode::header::<()>(input)?; + let (rest, header) = decode::header::<()>.parse_peek(input).unwrap(); assert!(rest.is_empty()); assert_eq!( @@ -110,7 +120,7 @@ mod header { #[test] fn valid_empty() -> Result { let input: &[u8] = b"# pack-refs with: \n"; - let (rest, header) = decode::header::<()>(input)?; + let (rest, header) = decode::header::<()>.parse_peek(input).unwrap(); assert!(rest.is_empty()); assert_eq!( diff --git a/vendor/gix-ref/src/store/packed/find.rs b/vendor/gix-ref/src/store/packed/find.rs index 8c1dcb5b2..002f76b0f 100644 --- a/vendor/gix-ref/src/store/packed/find.rs +++ b/vendor/gix-ref/src/store/packed/find.rs @@ -1,6 +1,7 @@ use std::convert::TryInto; use gix_object::bstr::{BStr, BString, ByteSlice}; +use winnow::prelude::*; use crate::{store_impl::packed, FullNameRef, PartialNameRef}; @@ -40,11 +41,14 @@ impl packed::Buffer { pub(crate) fn try_find_full_name(&self, name: &FullNameRef) -> Result<Option<packed::Reference<'_>>, Error> { match self.binary_search_by(name.as_bstr()) { - Ok(line_start) => Ok(Some( - packed::decode::reference::<()>(&self.as_ref()[line_start..]) - .map_err(|_| Error::Parse)? - .1, - )), + Ok(line_start) => { + let mut input = &self.as_ref()[line_start..]; + Ok(Some( + packed::decode::reference::<()> + .parse_next(&mut input) + .map_err(|_| Error::Parse)?, + )) + } Err((parse_failure, _)) => { if parse_failure { Err(Error::Parse) @@ -90,9 +94,10 @@ impl packed::Buffer { let mut encountered_parse_failure = false; a.binary_search_by_key(&full_name.as_ref(), |b: &u8| { let ofs = b as *const u8 as usize - a.as_ptr() as usize; - let line = &a[search_start_of_record(ofs)..]; - packed::decode::reference::<()>(line) - .map(|(_rest, r)| r.name.as_bstr().as_bytes()) + let mut line = &a[search_start_of_record(ofs)..]; + packed::decode::reference::<()> + .parse_next(&mut line) + .map(|r| r.name.as_bstr().as_bytes()) .map_err(|err| { encountered_parse_failure = true; err diff --git a/vendor/gix-ref/src/store/packed/iter.rs b/vendor/gix-ref/src/store/packed/iter.rs index d9c49956b..03c54a5f8 100644 --- a/vendor/gix-ref/src/store/packed/iter.rs +++ b/vendor/gix-ref/src/store/packed/iter.rs @@ -1,4 +1,9 @@ use gix_object::bstr::{BString, ByteSlice}; +use winnow::{ + combinator::{preceded, rest}, + prelude::*, + stream::Stream as _, +}; use crate::store_impl::{packed, packed::decode}; @@ -14,8 +19,7 @@ impl packed::Buffer { } /// Return an iterator yielding only references matching the given prefix, ordered by reference name. - pub fn iter_prefixed(&self, prefix: impl Into<BString>) -> Result<packed::Iter<'_>, packed::iter::Error> { - let prefix = prefix.into(); + pub fn iter_prefixed(&self, prefix: BString) -> Result<packed::Iter<'_>, packed::iter::Error> { let first_record_with_prefix = self.binary_search_by(prefix.as_bstr()).unwrap_or_else(|(_, pos)| pos); packed::Iter::new_with_prefix(&self.as_ref()[first_record_with_prefix..], Some(prefix)) } @@ -29,9 +33,9 @@ impl<'a> Iterator for packed::Iter<'a> { return None; } - match decode::reference::<()>(self.cursor) { - Ok((rest, reference)) => { - self.cursor = rest; + let start = self.cursor.checkpoint(); + match decode::reference::<()>.parse_next(&mut self.cursor) { + Ok(reference) => { self.current_line += 1; if let Some(ref prefix) = self.prefix { if !reference.name.as_bstr().starts_with_str(prefix) { @@ -42,6 +46,7 @@ impl<'a> Iterator for packed::Iter<'a> { Some(Ok(reference)) } Err(_) => { + self.cursor.reset(start); let (failed_line, next_cursor) = self .cursor .find_byte(b'\n') @@ -82,9 +87,12 @@ impl<'a> packed::Iter<'a> { current_line: 1, }) } else if packed[0] == b'#' { - let (refs, _header) = decode::header::<()>(packed).map_err(|_| Error::Header { - invalid_first_line: packed.lines().next().unwrap_or(packed).into(), - })?; + let mut input = packed; + let refs = preceded(decode::header::<()>, rest) + .parse_next(&mut input) + .map_err(|_| Error::Header { + invalid_first_line: packed.lines().next().unwrap_or(packed).into(), + })?; Ok(packed::Iter { cursor: refs, prefix, diff --git a/vendor/gix-ref/src/store/packed/transaction.rs b/vendor/gix-ref/src/store/packed/transaction.rs index e487e218c..4c503d711 100644 --- a/vendor/gix-ref/src/store/packed/transaction.rs +++ b/vendor/gix-ref/src/store/packed/transaction.rs @@ -27,7 +27,7 @@ impl packed::Transaction { impl std::fmt::Debug for packed::Transaction { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("packed::Transaction") - .field("edits", &self.edits.as_ref().map(|e| e.len())) + .field("edits", &self.edits.as_ref().map(Vec::len)) .field("lock", &self.lock) .finish_non_exhaustive() } @@ -46,7 +46,7 @@ impl packed::Transaction { /// Prepare the transaction by checking all edits for applicability. pub fn prepare( mut self, - edits: impl IntoIterator<Item = RefEdit>, + edits: &mut dyn Iterator<Item = RefEdit>, find: &mut FindObjectFn<'_>, ) -> Result<Self, prepare::Error> { assert!(self.edits.is_none(), "BUG: cannot call prepare(…) more than once"); @@ -102,7 +102,7 @@ impl packed::Transaction { self.closed_lock = self .lock .take() - .map(|l| l.close()) + .map(gix_lock::File::close) .transpose() .map_err(prepare::Error::CloseLock)?; } else { @@ -189,7 +189,7 @@ impl packed::Transaction { } } -fn write_packed_ref(mut out: impl std::io::Write, pref: packed::Reference<'_>) -> std::io::Result<()> { +fn write_packed_ref(out: &mut dyn std::io::Write, pref: packed::Reference<'_>) -> std::io::Result<()> { write!(out, "{} ", pref.target)?; out.write_all(pref.name.as_bstr())?; out.write_all(b"\n")?; @@ -199,7 +199,7 @@ fn write_packed_ref(mut out: impl std::io::Write, pref: packed::Reference<'_>) - Ok(()) } -fn write_edit(mut out: impl std::io::Write, edit: &Edit, lines_written: &mut i32) -> std::io::Result<()> { +fn write_edit(out: &mut dyn std::io::Write, edit: &Edit, lines_written: &mut i32) -> std::io::Result<()> { match edit.inner.change { Change::Delete { .. } => {} Change::Update { |