annotate rust/hg-core/src/revlog/revlog.rs @ 48575:e91aa800ae5b

rhg: desambiguate status without decompressing filelog if possible When status is unsure based on `stat()` and the dirstate if a file is clean or modified, we need to compare it against the filelog. This comparison can skip looking at contents if the lengths differ. This changeset optimize this further to deduce what we can about the length if the filelog without decompressing it or resolving deltas. Differential Revision: https://phab.mercurial-scm.org/D11965
author Simon Sapin <simon.sapin@octobus.net>
date Fri, 07 Jan 2022 14:40:21 +0100
parents faa243f345cc
children cc92ad0e8185 5d205e476057
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
1 use std::borrow::Cow;
48572
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
2 use std::convert::TryFrom;
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
3 use std::io::Read;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
4 use std::ops::Deref;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
5 use std::path::Path;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
6
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
7 use flate2::read::ZlibDecoder;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
8 use micro_timer::timed;
47386
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
9 use sha1::{Digest, Sha1};
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
10 use zstd;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
11
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
12 use super::index::Index;
46499
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
13 use super::node::{NodePrefix, NODE_BYTES_LENGTH, NULL_NODE};
46091
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
14 use super::nodemap;
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
15 use super::nodemap::{NodeMap, NodeMapError};
46091
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
16 use super::nodemap_docket::NodeMapDocket;
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
17 use super::patch;
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
18 use crate::errors::HgError;
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
19 use crate::repo::Repo;
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
20 use crate::revlog::Revision;
47995
6c653d9d41b8 rust: Make private the `index` field of the `Revlog` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47991
diff changeset
21 use crate::{Node, NULL_REVISION};
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
22
48575
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
23 const REVISION_FLAG_CENSORED: u16 = 1 << 15;
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
24 const REVISION_FLAG_ELLIPSIS: u16 = 1 << 14;
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
25 const REVISION_FLAG_EXTSTORED: u16 = 1 << 13;
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
26 const REVISION_FLAG_HASCOPIESINFO: u16 = 1 << 12;
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
27
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
28 // Keep this in sync with REVIDX_KNOWN_FLAGS in
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
29 // mercurial/revlogutils/flagutil.py
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
30 const REVIDX_KNOWN_FLAGS: u16 = REVISION_FLAG_CENSORED
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
31 | REVISION_FLAG_ELLIPSIS
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
32 | REVISION_FLAG_EXTSTORED
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
33 | REVISION_FLAG_HASCOPIESINFO;
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
34
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
35 #[derive(derive_more::From)]
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
36 pub enum RevlogError {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
37 InvalidRevision,
46821
e8ae91b1a63d rhg: raise wdir specific error for `hg debugdata`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46757
diff changeset
38 /// Working directory is not supported
e8ae91b1a63d rhg: raise wdir specific error for `hg debugdata`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46757
diff changeset
39 WDirUnsupported,
46036
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
40 /// Found more than one entry whose ID match the requested prefix
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
41 AmbiguousPrefix,
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
42 #[from]
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
43 Other(HgError),
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
44 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
45
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
46 impl From<NodeMapError> for RevlogError {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
47 fn from(error: NodeMapError) -> Self {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
48 match error {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
49 NodeMapError::MultipleResults => RevlogError::AmbiguousPrefix,
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
50 NodeMapError::RevisionNotInIndex(_) => RevlogError::corrupted(),
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
51 }
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
52 }
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
53 }
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
54
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
55 fn corrupted() -> HgError {
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
56 HgError::corrupted("corrupted revlog")
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
57 }
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
58
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
59 impl RevlogError {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
60 fn corrupted() -> Self {
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
61 RevlogError::Other(corrupted())
46462
0800aa42bb4c rust: use the bytes-cast crate to parse persistent nodemaps
Simon Sapin <simon.sapin@octobus.net>
parents: 46167
diff changeset
62 }
0800aa42bb4c rust: use the bytes-cast crate to parse persistent nodemaps
Simon Sapin <simon.sapin@octobus.net>
parents: 46167
diff changeset
63 }
0800aa42bb4c rust: use the bytes-cast crate to parse persistent nodemaps
Simon Sapin <simon.sapin@octobus.net>
parents: 46167
diff changeset
64
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
65 /// Read only implementation of revlog.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
66 pub struct Revlog {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
67 /// When index and data are not interleaved: bytes of the revlog index.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
68 /// When index and data are interleaved: bytes of the revlog index and
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
69 /// data.
47995
6c653d9d41b8 rust: Make private the `index` field of the `Revlog` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47991
diff changeset
70 index: Index,
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
71 /// When index and data are not interleaved: bytes of the revlog data
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
72 data_bytes: Option<Box<dyn Deref<Target = [u8]> + Send>>,
46091
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
73 /// When present on disk: the persistent nodemap for this revlog
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
74 nodemap: Option<nodemap::NodeTree>,
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
75 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
76
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
77 impl Revlog {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
78 /// Open a revlog index file.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
79 ///
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
80 /// It will also open the associated data file if index and data are not
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
81 /// interleaved.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
82 #[timed]
45825
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45606
diff changeset
83 pub fn open(
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
84 repo: &Repo,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
85 index_path: impl AsRef<Path>,
45825
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45606
diff changeset
86 data_path: Option<&Path>,
47991
001d747c2baf rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents: 47990
diff changeset
87 ) -> Result<Self, HgError> {
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
88 let index_path = index_path.as_ref();
48211
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
89 let index = {
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
90 match repo.store_vfs().mmap_open_opt(&index_path)? {
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
91 None => Index::new(Box::new(vec![])),
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
92 Some(index_mmap) => {
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
93 let index = Index::new(Box::new(index_mmap))?;
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
94 Ok(index)
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
95 }
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
96 }
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
97 }?;
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
98
45825
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45606
diff changeset
99 let default_data_path = index_path.with_extension("d");
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45606
diff changeset
100
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
101 // type annotation required
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
102 // won't recognize Mmap as Deref<Target = [u8]>
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
103 let data_bytes: Option<Box<dyn Deref<Target = [u8]> + Send>> =
45604
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
104 if index.is_inline() {
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
105 None
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
106 } else {
45825
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45606
diff changeset
107 let data_path = data_path.unwrap_or(&default_data_path);
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
108 let data_mmap = repo.store_vfs().mmap_open(data_path)?;
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
109 Some(Box::new(data_mmap))
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
110 };
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
111
48238
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
112 let nodemap = if index.is_inline() {
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
113 None
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
114 } else {
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
115 NodeMapDocket::read_from_file(repo, index_path)?.map(
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
116 |(docket, data)| {
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
117 nodemap::NodeTree::load_bytes(
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
118 Box::new(data),
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
119 docket.data_length,
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
120 )
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
121 },
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
122 )
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
123 };
46091
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
124
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
125 Ok(Revlog {
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
126 index,
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
127 data_bytes,
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
128 nodemap,
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
129 })
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
130 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
131
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
132 /// Return number of entries of the `Revlog`.
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
133 pub fn len(&self) -> usize {
45604
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
134 self.index.len()
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
135 }
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
136
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
137 /// Returns `true` if the `Revlog` has zero `entries`.
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
138 pub fn is_empty(&self) -> bool {
45604
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
139 self.index.is_empty()
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
140 }
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
141
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
142 /// Returns the node ID for the given revision number, if it exists in this
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
143 /// revlog
47995
6c653d9d41b8 rust: Make private the `index` field of the `Revlog` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47991
diff changeset
144 pub fn node_from_rev(&self, rev: Revision) -> Option<&Node> {
48248
f8dc78716ad2 rhg: fix `hg cat` interaction with null revision
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48239
diff changeset
145 if rev == NULL_REVISION {
f8dc78716ad2 rhg: fix `hg cat` interaction with null revision
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48239
diff changeset
146 return Some(&NULL_NODE);
f8dc78716ad2 rhg: fix `hg cat` interaction with null revision
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48239
diff changeset
147 }
47995
6c653d9d41b8 rust: Make private the `index` field of the `Revlog` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47991
diff changeset
148 Some(self.index.get_entry(rev)?.hash())
6c653d9d41b8 rust: Make private the `index` field of the `Revlog` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47991
diff changeset
149 }
6c653d9d41b8 rust: Make private the `index` field of the `Revlog` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47991
diff changeset
150
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
151 /// Return the revision number for the given node ID, if it exists in this
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
152 /// revlog
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
153 #[timed]
47996
6f579618ea7b rust: Rename the `Revlog::get_node_rev` method to `rev_from_node`
Simon Sapin <simon.sapin@octobus.net>
parents: 47995
diff changeset
154 pub fn rev_from_node(
46037
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 46036
diff changeset
155 &self,
46499
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
156 node: NodePrefix,
46037
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 46036
diff changeset
157 ) -> Result<Revision, RevlogError> {
47990
8c29af0f6d6e rhg: Align with Python on some revset parsing corner cases
Simon Sapin <simon.sapin@octobus.net>
parents: 47386
diff changeset
158 if node.is_prefix_of(&NULL_NODE) {
8c29af0f6d6e rhg: Align with Python on some revset parsing corner cases
Simon Sapin <simon.sapin@octobus.net>
parents: 47386
diff changeset
159 return Ok(NULL_REVISION);
8c29af0f6d6e rhg: Align with Python on some revset parsing corner cases
Simon Sapin <simon.sapin@octobus.net>
parents: 47386
diff changeset
160 }
8c29af0f6d6e rhg: Align with Python on some revset parsing corner cases
Simon Sapin <simon.sapin@octobus.net>
parents: 47386
diff changeset
161
46091
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
162 if let Some(nodemap) = &self.nodemap {
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
163 return nodemap
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
164 .find_bin(&self.index, node)?
46091
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
165 .ok_or(RevlogError::InvalidRevision);
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
166 }
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
167
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
168 // Fallback to linear scan when a persistent nodemap is not present.
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
169 // This happens when the persistent-nodemap experimental feature is not
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
170 // enabled, or for small revlogs.
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
171 //
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
172 // TODO: consider building a non-persistent nodemap in memory to
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
173 // optimize these cases.
46036
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
174 let mut found_by_prefix = None;
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
175 for rev in (0..self.len() as Revision).rev() {
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
176 let index_entry =
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
177 self.index.get_entry(rev).ok_or(HgError::corrupted(
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
178 "revlog references a revision not in the index",
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
179 ))?;
46037
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 46036
diff changeset
180 if node == *index_entry.hash() {
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
181 return Ok(rev);
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
182 }
46037
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 46036
diff changeset
183 if node.is_prefix_of(index_entry.hash()) {
46036
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
184 if found_by_prefix.is_some() {
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
185 return Err(RevlogError::AmbiguousPrefix);
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
186 }
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
187 found_by_prefix = Some(rev)
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
188 }
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
189 }
46036
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
190 found_by_prefix.ok_or(RevlogError::InvalidRevision)
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
191 }
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
192
46501
4b381dbbf8b7 rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
193 /// Returns whether the given revision exists in this revlog.
4b381dbbf8b7 rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
194 pub fn has_rev(&self, rev: Revision) -> bool {
4b381dbbf8b7 rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
195 self.index.get_entry(rev).is_some()
4b381dbbf8b7 rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
196 }
4b381dbbf8b7 rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
197
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
198 /// Return the full data associated to a revision.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
199 ///
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
200 /// All entries required to build the final data out of deltas will be
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
201 /// retrieved as needed, and the deltas will be applied to the inital
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
202 /// snapshot to rebuild the final data.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
203 #[timed]
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
204 pub fn get_rev_data(
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
205 &self,
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
206 rev: Revision,
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
207 ) -> Result<Cow<[u8]>, RevlogError> {
48210
61ce70fd420e rhg: handle null changelog and manifest revisions
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48095
diff changeset
208 if rev == NULL_REVISION {
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
209 return Ok(Cow::Borrowed(&[]));
48210
61ce70fd420e rhg: handle null changelog and manifest revisions
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48095
diff changeset
210 };
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
211 Ok(self.get_entry(rev)?.data()?)
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
212 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
213
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
214 /// Check the hash of some given data against the recorded hash.
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
215 pub fn check_hash(
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
216 &self,
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
217 p1: Revision,
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
218 p2: Revision,
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
219 expected: &[u8],
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
220 data: &[u8],
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
221 ) -> bool {
45604
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
222 let e1 = self.index.get_entry(p1);
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
223 let h1 = match e1 {
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
224 Some(ref entry) => entry.hash(),
46037
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 46036
diff changeset
225 None => &NULL_NODE,
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
226 };
45604
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
227 let e2 = self.index.get_entry(p2);
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
228 let h2 = match e2 {
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
229 Some(ref entry) => entry.hash(),
46037
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 46036
diff changeset
230 None => &NULL_NODE,
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
231 };
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
232
47386
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
233 &hash(data, h1.as_bytes(), h2.as_bytes()) == expected
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
234 }
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
235
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
236 /// Build the full data of a revision out its snapshot
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
237 /// and its deltas.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
238 #[timed]
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
239 fn build_data_from_deltas(
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
240 snapshot: RevlogEntry,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
241 deltas: &[RevlogEntry],
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
242 ) -> Result<Vec<u8>, HgError> {
48569
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48497
diff changeset
243 let snapshot = snapshot.data_chunk()?;
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
244 let deltas = deltas
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
245 .iter()
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
246 .rev()
48569
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48497
diff changeset
247 .map(RevlogEntry::data_chunk)
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
248 .collect::<Result<Vec<_>, _>>()?;
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
249 let patches: Vec<_> =
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
250 deltas.iter().map(|d| patch::PatchList::new(d)).collect();
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
251 let patch = patch::fold_patch_lists(&patches);
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
252 Ok(patch.apply(&snapshot))
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
253 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
254
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
255 /// Return the revlog data.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
256 fn data(&self) -> &[u8] {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
257 match self.data_bytes {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
258 Some(ref data_bytes) => &data_bytes,
45604
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
259 None => panic!(
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
260 "forgot to load the data or trying to access inline data"
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
261 ),
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
262 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
263 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
264
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
265 /// Get an entry of the revlog.
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
266 pub fn get_entry(
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
267 &self,
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
268 rev: Revision,
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
269 ) -> Result<RevlogEntry, RevlogError> {
45604
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
270 let index_entry = self
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
271 .index
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
272 .get_entry(rev)
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
273 .ok_or(RevlogError::InvalidRevision)?;
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
274 let start = index_entry.offset();
48572
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
275 let end = start + index_entry.compressed_len() as usize;
45604
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
276 let data = if self.index.is_inline() {
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
277 self.index.data(start, end)
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
278 } else {
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
279 &self.data()[start..end]
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
280 };
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
281 let entry = RevlogEntry {
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
282 revlog: self,
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
283 rev,
45604
900b9b79b99c hg-core: make `Index` owner of its bytes (D8958#inline-14994 followup 1/2)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45598
diff changeset
284 bytes: data,
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
285 compressed_len: index_entry.compressed_len(),
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
286 uncompressed_len: index_entry.uncompressed_len(),
48497
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
287 base_rev_or_base_of_delta_chain: if index_entry
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
288 .base_revision_or_base_of_delta_chain()
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
289 == rev
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
290 {
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
291 None
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
292 } else {
48497
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
293 Some(index_entry.base_revision_or_base_of_delta_chain())
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
294 },
48573
faa243f345cc rhg: Store p1, p2, and hash in RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48572
diff changeset
295 p1: index_entry.p1(),
faa243f345cc rhg: Store p1, p2, and hash in RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48572
diff changeset
296 p2: index_entry.p2(),
48575
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
297 flags: index_entry.flags(),
48573
faa243f345cc rhg: Store p1, p2, and hash in RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48572
diff changeset
298 hash: *index_entry.hash(),
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
299 };
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
300 Ok(entry)
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
301 }
48497
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
302
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
303 /// when resolving internal references within revlog, any errors
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
304 /// should be reported as corruption, instead of e.g. "invalid revision"
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
305 fn get_entry_internal(
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
306 &self,
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
307 rev: Revision,
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
308 ) -> Result<RevlogEntry, HgError> {
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
309 return self.get_entry(rev).map_err(|_| corrupted());
48497
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
310 }
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
311 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
312
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
313 /// The revlog entry's bytes and the necessary informations to extract
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
314 /// the entry's data.
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
315 #[derive(Clone)]
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
316 pub struct RevlogEntry<'a> {
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
317 revlog: &'a Revlog,
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
318 rev: Revision,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
319 bytes: &'a [u8],
48572
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
320 compressed_len: u32,
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
321 uncompressed_len: i32,
48497
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
322 base_rev_or_base_of_delta_chain: Option<Revision>,
48573
faa243f345cc rhg: Store p1, p2, and hash in RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48572
diff changeset
323 p1: Revision,
faa243f345cc rhg: Store p1, p2, and hash in RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48572
diff changeset
324 p2: Revision,
48575
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
325 flags: u16,
48573
faa243f345cc rhg: Store p1, p2, and hash in RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48572
diff changeset
326 hash: Node,
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
327 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
328
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
329 impl<'a> RevlogEntry<'a> {
48095
fecfea658127 hg-core: silence dead-code warning by adding RevlogEntry::revion() accessor
Martin von Zweigbergk <martinvonz@google.com>
parents: 47997
diff changeset
330 pub fn revision(&self) -> Revision {
fecfea658127 hg-core: silence dead-code warning by adding RevlogEntry::revion() accessor
Martin von Zweigbergk <martinvonz@google.com>
parents: 47997
diff changeset
331 self.rev
fecfea658127 hg-core: silence dead-code warning by adding RevlogEntry::revion() accessor
Martin von Zweigbergk <martinvonz@google.com>
parents: 47997
diff changeset
332 }
fecfea658127 hg-core: silence dead-code warning by adding RevlogEntry::revion() accessor
Martin von Zweigbergk <martinvonz@google.com>
parents: 47997
diff changeset
333
48572
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
334 pub fn uncompressed_len(&self) -> Option<u32> {
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
335 u32::try_from(self.uncompressed_len).ok()
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
336 }
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
337
48575
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
338 pub fn has_p1(&self) -> bool {
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
339 self.p1 != NULL_REVISION
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
340 }
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
341
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
342 pub fn is_cencored(&self) -> bool {
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
343 (self.flags & REVISION_FLAG_CENSORED) != 0
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
344 }
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
345
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
346 pub fn has_length_affecting_flag_processor(&self) -> bool {
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
347 // Relevant Python code: revlog.size()
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
348 // note: ELLIPSIS is known to not change the content
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
349 (self.flags & (REVIDX_KNOWN_FLAGS ^ REVISION_FLAG_ELLIPSIS)) != 0
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
350 }
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48573
diff changeset
351
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
352 /// The data for this entry, after resolving deltas if any.
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
353 pub fn data(&self) -> Result<Cow<'a, [u8]>, HgError> {
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
354 let mut entry = self.clone();
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
355 let mut delta_chain = vec![];
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
356
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
357 // The meaning of `base_rev_or_base_of_delta_chain` depends on
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
358 // generaldelta. See the doc on `ENTRY_DELTA_BASE` in
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
359 // `mercurial/revlogutils/constants.py` and the code in
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
360 // [_chaininfo] and in [index_deltachain].
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
361 let uses_generaldelta = self.revlog.index.uses_generaldelta();
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
362 while let Some(base_rev) = entry.base_rev_or_base_of_delta_chain {
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
363 let base_rev = if uses_generaldelta {
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
364 base_rev
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
365 } else {
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
366 entry.rev - 1
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
367 };
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
368 delta_chain.push(entry);
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
369 entry = self.revlog.get_entry_internal(base_rev)?;
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
370 }
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
371
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
372 let data = if delta_chain.is_empty() {
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
373 entry.data_chunk()?
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
374 } else {
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
375 Revlog::build_data_from_deltas(entry, &delta_chain)?.into()
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
376 };
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
377
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
378 if self.revlog.check_hash(
48573
faa243f345cc rhg: Store p1, p2, and hash in RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48572
diff changeset
379 self.p1,
faa243f345cc rhg: Store p1, p2, and hash in RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48572
diff changeset
380 self.p2,
faa243f345cc rhg: Store p1, p2, and hash in RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48572
diff changeset
381 self.hash.as_bytes(),
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
382 &data,
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
383 ) {
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
384 Ok(data)
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
385 } else {
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
386 Err(corrupted())
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
387 }
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
388 }
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
389
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
390 /// Extract the data contained in the entry.
48569
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48497
diff changeset
391 /// This may be a delta. (See `is_delta`.)
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
392 fn data_chunk(&self) -> Result<Cow<'a, [u8]>, HgError> {
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
393 if self.bytes.is_empty() {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
394 return Ok(Cow::Borrowed(&[]));
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
395 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
396 match self.bytes[0] {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
397 // Revision data is the entirety of the entry, including this
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
398 // header.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
399 b'\0' => Ok(Cow::Borrowed(self.bytes)),
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
400 // Raw revision data follows.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
401 b'u' => Ok(Cow::Borrowed(&self.bytes[1..])),
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
402 // zlib (RFC 1950) data.
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
403 b'x' => Ok(Cow::Owned(self.uncompressed_zlib_data()?)),
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
404 // zstd data.
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
405 b'\x28' => Ok(Cow::Owned(self.uncompressed_zstd_data()?)),
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
406 // A proper new format should have had a repo/store requirement.
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
407 _format_type => Err(corrupted()),
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
408 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
409 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
410
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
411 fn uncompressed_zlib_data(&self) -> Result<Vec<u8>, HgError> {
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
412 let mut decoder = ZlibDecoder::new(self.bytes);
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
413 if self.is_delta() {
48572
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
414 let mut buf = Vec::with_capacity(self.compressed_len as usize);
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
415 decoder.read_to_end(&mut buf).map_err(|_| corrupted())?;
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
416 Ok(buf)
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
417 } else {
48572
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
418 let cap = self.uncompressed_len.max(0) as usize;
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
419 let mut buf = vec![0; cap];
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
420 decoder.read_exact(&mut buf).map_err(|_| corrupted())?;
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
421 Ok(buf)
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
422 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
423 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
424
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
425 fn uncompressed_zstd_data(&self) -> Result<Vec<u8>, HgError> {
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
426 if self.is_delta() {
48572
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
427 let mut buf = Vec::with_capacity(self.compressed_len as usize);
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
428 zstd::stream::copy_decode(self.bytes, &mut buf)
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
429 .map_err(|_| corrupted())?;
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
430 Ok(buf)
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
431 } else {
48572
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
432 let cap = self.uncompressed_len.max(0) as usize;
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
433 let mut buf = vec![0; cap];
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
434 let len = zstd::block::decompress_to_buffer(self.bytes, &mut buf)
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
435 .map_err(|_| corrupted())?;
48572
0a4ac916673e rhg: RevlogEntry::uncompressed_len is signed
Simon Sapin <simon.sapin@octobus.net>
parents: 48571
diff changeset
436 if len != self.uncompressed_len as usize {
48571
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48570
diff changeset
437 Err(corrupted())
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
438 } else {
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
439 Ok(buf)
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
440 }
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
441 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
442 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
443
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
444 /// Tell if the entry is a snapshot or a delta
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
445 /// (influences on decompression).
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
446 fn is_delta(&self) -> bool {
48497
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
447 self.base_rev_or_base_of_delta_chain.is_some()
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
448 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
449 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
450
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
451 /// Calculate the hash of a revision given its data and its parents.
47386
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
452 fn hash(
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
453 data: &[u8],
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
454 p1_hash: &[u8],
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
455 p2_hash: &[u8],
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
456 ) -> [u8; NODE_BYTES_LENGTH] {
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
457 let mut hasher = Sha1::new();
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
458 let (a, b) = (p1_hash, p2_hash);
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
459 if a > b {
47386
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
460 hasher.update(b);
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
461 hasher.update(a);
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
462 } else {
47386
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
463 hasher.update(a);
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
464 hasher.update(b);
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
465 }
47386
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
466 hasher.update(data);
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
467 *hasher.finalize().as_ref()
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
468 }