annotate rust/hg-core/src/revlog/revlog.rs @ 48570:f2f57724d4eb

rhg: Add RevlogEntry::data that does delta resolution This requires keeping a `&Revlog` reference inside the `RevlogEntry` struct. This struct already had the appropriate lifetime parameter. Differential Revision: https://phab.mercurial-scm.org/D11960
author Simon Sapin <simon.sapin@octobus.net>
date Tue, 21 Dec 2021 18:35:58 +0100
parents 20d0d896183e
children 35c47015b9b7
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;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
2 use std::io::Read;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
3 use std::ops::Deref;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
4 use std::path::Path;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
5
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
6 use flate2::read::ZlibDecoder;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
7 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
8 use sha1::{Digest, Sha1};
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
9 use zstd;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
10
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
11 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
12 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
13 use super::nodemap;
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
14 use super::nodemap::{NodeMap, NodeMapError};
46091
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
15 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
16 use super::patch;
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
17 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
18 use crate::repo::Repo;
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
19 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
20 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
21
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
22 #[derive(derive_more::From)]
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
23 pub enum RevlogError {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
24 InvalidRevision,
46821
e8ae91b1a63d rhg: raise wdir specific error for `hg debugdata`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46757
diff changeset
25 /// Working directory is not supported
e8ae91b1a63d rhg: raise wdir specific error for `hg debugdata`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46757
diff changeset
26 WDirUnsupported,
46036
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
27 /// 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
28 AmbiguousPrefix,
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
29 #[from]
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
30 Other(HgError),
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
31 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
32
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
33 impl From<NodeMapError> for RevlogError {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
34 fn from(error: NodeMapError) -> Self {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
35 match error {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
36 NodeMapError::MultipleResults => RevlogError::AmbiguousPrefix,
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
37 NodeMapError::RevisionNotInIndex(_) => RevlogError::corrupted(),
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
38 }
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
39 }
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
40 }
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
41
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
42 impl RevlogError {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
43 fn corrupted() -> Self {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
44 RevlogError::Other(HgError::corrupted("corrupted revlog"))
46462
0800aa42bb4c rust: use the bytes-cast crate to parse persistent nodemaps
Simon Sapin <simon.sapin@octobus.net>
parents: 46167
diff changeset
45 }
0800aa42bb4c rust: use the bytes-cast crate to parse persistent nodemaps
Simon Sapin <simon.sapin@octobus.net>
parents: 46167
diff changeset
46 }
0800aa42bb4c rust: use the bytes-cast crate to parse persistent nodemaps
Simon Sapin <simon.sapin@octobus.net>
parents: 46167
diff changeset
47
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
48 /// Read only implementation of revlog.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
49 pub struct Revlog {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
50 /// 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
51 /// 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
52 /// data.
47995
6c653d9d41b8 rust: Make private the `index` field of the `Revlog` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47991
diff changeset
53 index: Index,
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
54 /// 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
55 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
56 /// 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
57 nodemap: Option<nodemap::NodeTree>,
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
58 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
59
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
60 impl Revlog {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
61 /// Open a revlog index file.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
62 ///
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
63 /// 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
64 /// interleaved.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
65 #[timed]
45825
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45606
diff changeset
66 pub fn open(
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
67 repo: &Repo,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
68 index_path: impl AsRef<Path>,
45825
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45606
diff changeset
69 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
70 ) -> Result<Self, HgError> {
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
71 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
72 let index = {
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
73 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
74 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
75 Some(index_mmap) => {
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
76 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
77 Ok(index)
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
78 }
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
79 }
9d0e5629cfbf rhg: do not fail when the repo is empty
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48210
diff changeset
80 }?;
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
81
45825
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45606
diff changeset
82 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
83
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
84 // type annotation required
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
85 // 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
86 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
87 if index.is_inline() {
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
88 None
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
89 } else {
45825
7252f5237352 hg-core: fix path encoding usage
Antoine cezar<acezar@chwitlabs.fr>
parents: 45606
diff changeset
90 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
91 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
92 Some(Box::new(data_mmap))
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
93 };
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
94
48238
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
95 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
96 None
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
97 } else {
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
98 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
99 |(docket, data)| {
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
100 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
101 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
102 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
103 )
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
104 },
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
105 )
5e77bdc29d56 rhg: do not try to open a nodemap for an inline index
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48211
diff changeset
106 };
46091
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
107
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
108 Ok(Revlog {
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
109 index,
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
110 data_bytes,
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
111 nodemap,
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
112 })
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
113 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
114
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
115 /// 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
116 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
117 self.index.len()
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
118 }
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
119
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
120 /// 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
121 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
122 self.index.is_empty()
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
123 }
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
124
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
125 /// 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
126 /// revlog
47995
6c653d9d41b8 rust: Make private the `index` field of the `Revlog` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47991
diff changeset
127 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
128 if rev == NULL_REVISION {
f8dc78716ad2 rhg: fix `hg cat` interaction with null revision
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48239
diff changeset
129 return Some(&NULL_NODE);
f8dc78716ad2 rhg: fix `hg cat` interaction with null revision
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48239
diff changeset
130 }
47995
6c653d9d41b8 rust: Make private the `index` field of the `Revlog` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47991
diff changeset
131 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
132 }
6c653d9d41b8 rust: Make private the `index` field of the `Revlog` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47991
diff changeset
133
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
134 /// 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
135 /// revlog
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
136 #[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
137 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
138 &self,
46499
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46462
diff changeset
139 node: NodePrefix,
46037
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 46036
diff changeset
140 ) -> 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
141 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
142 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
143 }
8c29af0f6d6e rhg: Align with Python on some revset parsing corner cases
Simon Sapin <simon.sapin@octobus.net>
parents: 47386
diff changeset
144
46091
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
145 if let Some(nodemap) = &self.nodemap {
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
146 return nodemap
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
147 .find_bin(&self.index, node)?
46091
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
148 .ok_or(RevlogError::InvalidRevision);
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
149 }
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
150
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
151 // 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
152 // 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
153 // enabled, or for small revlogs.
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
154 //
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 46037
diff changeset
155 // 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
156 // optimize these cases.
46036
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
157 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
158 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
159 let index_entry =
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
160 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
161 "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
162 ))?;
46037
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 46036
diff changeset
163 if node == *index_entry.hash() {
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
164 return Ok(rev);
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
165 }
46037
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 46036
diff changeset
166 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
167 if found_by_prefix.is_some() {
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
168 return Err(RevlogError::AmbiguousPrefix);
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
169 }
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
170 found_by_prefix = Some(rev)
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
171 }
45540
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
172 }
46036
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45825
diff changeset
173 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
174 }
4f11a67a12fb hg-core: add `Revlog.get_node_rev`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45537
diff changeset
175
46501
4b381dbbf8b7 rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
176 /// 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
177 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
178 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
179 }
4b381dbbf8b7 rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
180
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
181 /// 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
182 ///
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
183 /// 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
184 /// 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
185 /// 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
186 #[timed]
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
187 pub fn get_rev_data(
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
188 &self,
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
189 rev: Revision,
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
190 ) -> Result<Cow<[u8]>, RevlogError> {
48210
61ce70fd420e rhg: handle null changelog and manifest revisions
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48095
diff changeset
191 if rev == NULL_REVISION {
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
192 return Ok(Cow::Borrowed(&[]));
48210
61ce70fd420e rhg: handle null changelog and manifest revisions
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48095
diff changeset
193 };
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
194 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
195 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
196
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
197 /// 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
198 pub fn check_hash(
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
199 &self,
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
200 p1: Revision,
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
201 p2: Revision,
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
202 expected: &[u8],
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
203 data: &[u8],
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
204 ) -> 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
205 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
206 let h1 = match e1 {
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
207 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
208 None => &NULL_NODE,
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
209 };
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
210 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
211 let h2 = match e2 {
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
212 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
213 None => &NULL_NODE,
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
214 };
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
215
47386
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
216 &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
217 }
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
218
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
219 /// 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
220 /// and its deltas.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
221 #[timed]
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
222 fn build_data_from_deltas(
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
223 snapshot: RevlogEntry,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
224 deltas: &[RevlogEntry],
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
225 ) -> Result<Vec<u8>, RevlogError> {
48569
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48497
diff changeset
226 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
227 let deltas = deltas
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
228 .iter()
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
229 .rev()
48569
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48497
diff changeset
230 .map(RevlogEntry::data_chunk)
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
231 .collect::<Result<Vec<Cow<'_, [u8]>>, RevlogError>>()?;
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
232 let patches: Vec<_> =
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
233 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
234 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
235 Ok(patch.apply(&snapshot))
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
236 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
237
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
238 /// Return the revlog data.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
239 fn data(&self) -> &[u8] {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
240 match self.data_bytes {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
241 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
242 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
243 "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
244 ),
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
245 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
246 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
247
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
248 /// Get an entry of the revlog.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
249 fn get_entry(&self, rev: Revision) -> 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
250 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
251 .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
252 .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
253 .ok_or(RevlogError::InvalidRevision)?;
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
254 let start = index_entry.offset();
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
255 let end = start + index_entry.compressed_len();
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
256 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
257 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
258 } 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
259 &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
260 };
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
261 let entry = RevlogEntry {
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
262 revlog: self,
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
263 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
264 bytes: data,
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
265 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
266 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
267 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
268 .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
269 == rev
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
270 {
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
271 None
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
272 } else {
48497
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
273 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
274 },
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
275 };
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
276 Ok(entry)
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
277 }
48497
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
278
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
279 /// 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
280 /// 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
281 fn get_entry_internal(
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
282 &self,
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
283 rev: Revision,
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
284 ) -> Result<RevlogEntry, RevlogError> {
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
285 return self.get_entry(rev).map_err(|_| RevlogError::corrupted());
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
286 }
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
287 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
288
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
289 /// 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
290 /// the entry's data.
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
291 #[derive(Clone)]
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
292 pub struct RevlogEntry<'a> {
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
293 revlog: &'a Revlog,
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
294 rev: Revision,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
295 bytes: &'a [u8],
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
296 compressed_len: usize,
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
297 uncompressed_len: usize,
48497
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
298 base_rev_or_base_of_delta_chain: Option<Revision>,
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
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
301 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
302 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
303 self.rev
fecfea658127 hg-core: silence dead-code warning by adding RevlogEntry::revion() accessor
Martin von Zweigbergk <martinvonz@google.com>
parents: 47997
diff changeset
304 }
fecfea658127 hg-core: silence dead-code warning by adding RevlogEntry::revion() accessor
Martin von Zweigbergk <martinvonz@google.com>
parents: 47997
diff changeset
305
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
306 /// The data for this entry, after resolving deltas if any.
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
307 pub fn data(&self) -> Result<Cow<'a, [u8]>, RevlogError> {
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
308 let mut entry = self.clone();
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
309 let mut delta_chain = vec![];
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
310
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
311 // 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
312 // 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
313 // `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
314 // [_chaininfo] and in [index_deltachain].
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
315 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
316 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
317 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
318 base_rev
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
319 } else {
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
320 entry.rev - 1
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
321 };
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
322 delta_chain.push(entry);
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
323 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
324 }
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
325
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
326 // TODO do not look twice in the index
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
327 let index_entry = self
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
328 .revlog
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
329 .index
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
330 .get_entry(self.rev)
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
331 .ok_or(RevlogError::InvalidRevision)?;
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
332
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
333 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
334 entry.data_chunk()?
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
335 } else {
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
336 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
337 };
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
338
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
339 if self.revlog.check_hash(
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
340 index_entry.p1(),
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
341 index_entry.p2(),
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
342 index_entry.hash().as_bytes(),
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
343 &data,
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
344 ) {
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
345 Ok(data)
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
346 } else {
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
347 Err(RevlogError::corrupted())
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
348 }
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
349 }
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
350
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
351 /// 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
352 /// This may be a delta. (See `is_delta`.)
48570
f2f57724d4eb rhg: Add RevlogEntry::data that does delta resolution
Simon Sapin <simon.sapin@octobus.net>
parents: 48569
diff changeset
353 fn data_chunk(&self) -> Result<Cow<'a, [u8]>, RevlogError> {
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
354 if self.bytes.is_empty() {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
355 return Ok(Cow::Borrowed(&[]));
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
356 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
357 match self.bytes[0] {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
358 // 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
359 // header.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
360 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
361 // Raw revision data follows.
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
362 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
363 // 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
364 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
365 // zstd data.
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
366 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
367 // A proper new format should have had a repo/store requirement.
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
368 _format_type => Err(RevlogError::corrupted()),
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
369 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
370 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
371
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
372 fn uncompressed_zlib_data(&self) -> Result<Vec<u8>, RevlogError> {
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
373 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
374 if self.is_delta() {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
375 let mut buf = Vec::with_capacity(self.compressed_len);
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
376 decoder
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
377 .read_to_end(&mut buf)
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
378 .map_err(|_| RevlogError::corrupted())?;
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
379 Ok(buf)
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
380 } else {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
381 let mut buf = vec![0; self.uncompressed_len];
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
382 decoder
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
383 .read_exact(&mut buf)
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
384 .map_err(|_| RevlogError::corrupted())?;
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
385 Ok(buf)
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
386 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
387 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
388
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
389 fn uncompressed_zstd_data(&self) -> Result<Vec<u8>, RevlogError> {
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
390 if self.is_delta() {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
391 let mut buf = Vec::with_capacity(self.compressed_len);
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
392 zstd::stream::copy_decode(self.bytes, &mut buf)
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
393 .map_err(|_| RevlogError::corrupted())?;
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
394 Ok(buf)
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
395 } else {
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
396 let mut buf = vec![0; self.uncompressed_len];
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
397 let len = zstd::block::decompress_to_buffer(self.bytes, &mut buf)
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
398 .map_err(|_| RevlogError::corrupted())?;
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
399 if len != self.uncompressed_len {
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46501
diff changeset
400 Err(RevlogError::corrupted())
45598
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
401 } else {
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
402 Ok(buf)
497657895b54 hg-core: return `Err` on decompression error (D8958#inline-15004 followup)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
403 }
45532
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
404 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
405 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
406
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
407 /// 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
408 /// (influences on decompression).
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
409 fn is_delta(&self) -> bool {
48497
96ea4db4741b rhg: fix a crash on non-generaldelta revlogs
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 48496
diff changeset
410 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
411 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
412 }
26c53ee51c68 hg-core: Add a limited read only `revlog` implementation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
413
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
414 /// 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
415 fn hash(
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
416 data: &[u8],
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
417 p1_hash: &[u8],
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
418 p2_hash: &[u8],
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
419 ) -> [u8; NODE_BYTES_LENGTH] {
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
420 let mut hasher = Sha1::new();
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
421 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
422 if a > b {
47386
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
423 hasher.update(b);
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
424 hasher.update(a);
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
425 } else {
47386
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
426 hasher.update(a);
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
427 hasher.update(b);
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
428 }
47386
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
429 hasher.update(data);
fad504cfc94b rust: Use a maintained crate for SHA-1 hashing
Simon Sapin <simon.sapin@octobus.net>
parents: 46821
diff changeset
430 *hasher.finalize().as_ref()
45537
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45532
diff changeset
431 }