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