Mercurial > public > mercurial-scm > hg-stable
annotate rust/hg-core/src/revlog/manifest.rs @ 48605:a809f1465a76
filemerge: set default labels a little earlier
By setting the default labels a little earlier, we can rely on them
always being set, as far as I can tell. It may actually even be fine
to rely on that even if we don't set them earlier, but it makes more
sense to me to do it.
Differential Revision: https://phab.mercurial-scm.org/D12015
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Thu, 20 Jan 2022 13:43:43 -0800 |
parents | f2f57724d4eb |
children | bfc117647c71 |
rev | line source |
---|---|
47991
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47985
diff
changeset
|
1 use crate::errors::HgError; |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
46135
diff
changeset
|
2 use crate::repo::Repo; |
45539
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
3 use crate::revlog::revlog::{Revlog, RevlogError}; |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
4 use crate::revlog::Revision; |
47992
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47991
diff
changeset
|
5 use crate::revlog::{Node, NodePrefix}; |
45539
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
6 use crate::utils::hg_path::HgPath; |
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
7 use crate::utils::SliceExt; |
45539
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
8 |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
9 /// A specialized `Revlog` to work with `manifest` data format. |
47985
d44740725b95
rust: Rename Manifest to Manifestlog, ManifestEntry to Manifest
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
10 pub struct Manifestlog { |
45539
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
11 /// The generic `revlog` format. |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
12 revlog: Revlog, |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
13 } |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
14 |
47985
d44740725b95
rust: Rename Manifest to Manifestlog, ManifestEntry to Manifest
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
15 impl Manifestlog { |
45539
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
16 /// Open the `manifest` of a repository given by its root. |
47991
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47985
diff
changeset
|
17 pub fn open(repo: &Repo) -> Result<Self, HgError> { |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
46135
diff
changeset
|
18 let revlog = Revlog::open(repo, "00manifest.i", None)?; |
45539
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
19 Ok(Self { revlog }) |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
20 } |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
21 |
47997
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
22 /// Return the `Manifest` for the given node ID. |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
23 /// |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
24 /// Note: this is a node ID in the manifestlog, typically found through |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
25 /// `ChangelogEntry::manifest_node`. It is *not* the node ID of any |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
26 /// changeset. |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
27 /// |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
28 /// See also `Repo::manifest_for_node` |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
29 pub fn data_for_node( |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
30 &self, |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
31 node: NodePrefix, |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
32 ) -> Result<Manifest, RevlogError> { |
47996
6f579618ea7b
rust: Rename the `Revlog::get_node_rev` method to `rev_from_node`
Simon Sapin <simon.sapin@octobus.net>
parents:
47992
diff
changeset
|
33 let rev = self.revlog.rev_from_node(node)?; |
47997
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
34 self.data_for_rev(rev) |
45539
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
35 } |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
36 |
47997
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
37 /// Return the `Manifest` of a given revision number. |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
38 /// |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
39 /// Note: this is a revision number in the manifestlog, *not* of any |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
40 /// changeset. |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
41 /// |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
42 /// See also `Repo::manifest_for_rev` |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
43 pub fn data_for_rev( |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
44 &self, |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
45 rev: Revision, |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47996
diff
changeset
|
46 ) -> Result<Manifest, RevlogError> { |
48570
f2f57724d4eb
rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents:
48532
diff
changeset
|
47 let bytes = self.revlog.get_rev_data(rev)?.into_owned(); |
47985
d44740725b95
rust: Rename Manifest to Manifestlog, ManifestEntry to Manifest
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
48 Ok(Manifest { bytes }) |
45539
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
49 } |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
50 } |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
51 |
47985
d44740725b95
rust: Rename Manifest to Manifestlog, ManifestEntry to Manifest
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
52 /// `Manifestlog` entry which knows how to interpret the `manifest` data bytes. |
45539
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
53 #[derive(Debug)] |
47985
d44740725b95
rust: Rename Manifest to Manifestlog, ManifestEntry to Manifest
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
54 pub struct Manifest { |
48532
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
55 /// Format for a manifest: flat sequence of variable-size entries, |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
56 /// sorted by path, each as: |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
57 /// |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
58 /// ```text |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
59 /// <path> \0 <hex_node_id> <flags> \n |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
60 /// ``` |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
61 /// |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
62 /// The last entry is also terminated by a newline character. |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
63 /// Flags is one of `b""` (the empty string), `b"x"`, `b"l"`, or `b"t"`. |
45539
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
64 bytes: Vec<u8>, |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
65 } |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
66 |
47985
d44740725b95
rust: Rename Manifest to Manifestlog, ManifestEntry to Manifest
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
67 impl Manifest { |
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
68 pub fn iter( |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
69 &self, |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
70 ) -> impl Iterator<Item = Result<ManifestEntry, HgError>> { |
45539
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
71 self.bytes |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
72 .split(|b| b == &b'\n') |
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
73 .filter(|line| !line.is_empty()) |
48532
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
74 .map(ManifestEntry::from_raw) |
45546
f2de24c2b1f6
hg-core: add `files_with_nodes` to `Manifest`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45539
diff
changeset
|
75 } |
47992
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47991
diff
changeset
|
76 |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47991
diff
changeset
|
77 /// If the given path is in this manifest, return its filelog node ID |
48532
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
78 pub fn find_by_path( |
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
79 &self, |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
80 path: &HgPath, |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
81 ) -> Result<Option<ManifestEntry>, HgError> { |
48532
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
82 use std::cmp::Ordering::*; |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
83 let path = path.as_bytes(); |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
84 // Both boundaries of this `&[u8]` slice are always at the boundary of |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
85 // an entry |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
86 let mut bytes = &*self.bytes; |
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
87 |
48532
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
88 // Binary search algorithm derived from `[T]::binary_search_by` |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
89 // <https://github.com/rust-lang/rust/blob/1.57.0/library/core/src/slice/mod.rs#L2221> |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
90 // except we don’t have a slice of entries. Instead we jump to the |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
91 // middle of the byte slice and look around for entry delimiters |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
92 // (newlines). |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
93 while let Some(entry_range) = Self::find_entry_near_middle_of(bytes)? { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
94 let (entry_path, rest) = |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
95 ManifestEntry::split_path(&bytes[entry_range.clone()])?; |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
96 let cmp = entry_path.cmp(path); |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
97 if cmp == Less { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
98 let after_newline = entry_range.end + 1; |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
99 bytes = &bytes[after_newline..]; |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
100 } else if cmp == Greater { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
101 bytes = &bytes[..entry_range.start]; |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
102 } else { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
103 return Ok(Some(ManifestEntry::from_path_and_rest( |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
104 entry_path, rest, |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
105 ))); |
47992
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47991
diff
changeset
|
106 } |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47991
diff
changeset
|
107 } |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47991
diff
changeset
|
108 Ok(None) |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47991
diff
changeset
|
109 } |
48532
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
110 |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
111 /// If there is at least one, return the byte range of an entry *excluding* |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
112 /// the final newline. |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
113 fn find_entry_near_middle_of( |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
114 bytes: &[u8], |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
115 ) -> Result<Option<std::ops::Range<usize>>, HgError> { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
116 let len = bytes.len(); |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
117 if len > 0 { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
118 let middle = bytes.len() / 2; |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
119 // Integer division rounds down, so `middle < len`. |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
120 let (before, after) = bytes.split_at(middle); |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
121 let is_newline = |&byte: &u8| byte == b'\n'; |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
122 let entry_start = match before.iter().rposition(is_newline) { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
123 Some(i) => i + 1, |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
124 None => 0, // We choose the first entry in `bytes` |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
125 }; |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
126 let entry_end = match after.iter().position(is_newline) { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
127 Some(i) => { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
128 // No `+ 1` here to exclude this newline from the range |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
129 middle + i |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
130 } |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
131 None => { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
132 // In a well-formed manifest: |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
133 // |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
134 // * Since `len > 0`, `bytes` contains at least one entry |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
135 // * Every entry ends with a newline |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
136 // * Since `middle < len`, `after` contains at least the |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
137 // newline at the end of the last entry of `bytes`. |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
138 // |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
139 // We didn’t find a newline, so this manifest is not |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
140 // well-formed. |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
141 return Err(HgError::corrupted( |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
142 "manifest entry without \\n delimiter", |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
143 )); |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
144 } |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
145 }; |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
146 Ok(Some(entry_start..entry_end)) |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
147 } else { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
148 // len == 0 |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
149 Ok(None) |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
150 } |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
151 } |
45539
89ac95bd4993
hg-core: add `Manifest` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
152 } |
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
153 |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
154 /// `Manifestlog` entry which knows how to interpret the `manifest` data bytes. |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
155 #[derive(Debug)] |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
156 pub struct ManifestEntry<'manifest> { |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
157 pub path: &'manifest HgPath, |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
158 pub hex_node_id: &'manifest [u8], |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
159 |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
160 /// `Some` values are b'x', b'l', or 't' |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
161 pub flags: Option<u8>, |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
162 } |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
163 |
48532
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
164 impl<'a> ManifestEntry<'a> { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
165 fn split_path(bytes: &[u8]) -> Result<(&[u8], &[u8]), HgError> { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
166 bytes.split_2(b'\0').ok_or_else(|| { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
167 HgError::corrupted("manifest entry without \\0 delimiter") |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
168 }) |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
169 } |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
170 |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
171 fn from_path_and_rest(path: &'a [u8], rest: &'a [u8]) -> Self { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
172 let (hex_node_id, flags) = match rest.split_last() { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
173 Some((&b'x', rest)) => (rest, Some(b'x')), |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
174 Some((&b'l', rest)) => (rest, Some(b'l')), |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
175 Some((&b't', rest)) => (rest, Some(b't')), |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
176 _ => (rest, None), |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
177 }; |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
178 Self { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
179 path: HgPath::new(path), |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
180 hex_node_id, |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
181 flags, |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
182 } |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
183 } |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
184 |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
185 fn from_raw(bytes: &'a [u8]) -> Result<Self, HgError> { |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
186 let (path, rest) = Self::split_path(bytes)?; |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
187 Ok(Self::from_path_and_rest(path, rest)) |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
188 } |
e293ff808a05
rhg: Use binary search in manifest lookup
Simon Sapin <simon.sapin@octobus.net>
parents:
48392
diff
changeset
|
189 |
48392
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
190 pub fn node_id(&self) -> Result<Node, HgError> { |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
191 Node::from_hex_for_repo(self.hex_node_id) |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
192 } |
eb428010aad2
rhg: Also parse flags in the manifest parser
Simon Sapin <simon.sapin@octobus.net>
parents:
48391
diff
changeset
|
193 } |