comparison rust/hg-core/src/revlog/revlog.rs @ 46033:88e741bf2d93

rust: use NodePrefix::from_hex instead of hex::decode directly This adds support for prefixes with an odd number of hex digits. Differential Revision: https://phab.mercurial-scm.org/D9490
author Simon Sapin <simon-commits@exyr.org>
date Wed, 02 Dec 2020 15:00:49 +0100
parents 8d6164098782
children 9eb07ab3f2d4
comparison
equal deleted inserted replaced
46032:8d6164098782 46033:88e741bf2d93
11 use memmap::{Mmap, MmapOptions}; 11 use memmap::{Mmap, MmapOptions};
12 use micro_timer::timed; 12 use micro_timer::timed;
13 use zstd; 13 use zstd;
14 14
15 use super::index::Index; 15 use super::index::Index;
16 use super::node::{NODE_BYTES_LENGTH, NULL_NODE_ID}; 16 use super::node::{NodePrefixRef, NODE_BYTES_LENGTH, NULL_NODE};
17 use super::patch; 17 use super::patch;
18 use crate::revlog::Revision; 18 use crate::revlog::Revision;
19 19
20 pub enum RevlogError { 20 pub enum RevlogError {
21 IoError(std::io::Error), 21 IoError(std::io::Error),
90 self.index.is_empty() 90 self.index.is_empty()
91 } 91 }
92 92
93 /// Return the full data associated to a node. 93 /// Return the full data associated to a node.
94 #[timed] 94 #[timed]
95 pub fn get_node_rev(&self, node: &[u8]) -> Result<Revision, RevlogError> { 95 pub fn get_node_rev(
96 &self,
97 node: NodePrefixRef,
98 ) -> Result<Revision, RevlogError> {
96 // This is brute force. But it is fast enough for now. 99 // This is brute force. But it is fast enough for now.
97 // Optimization will come later. 100 // Optimization will come later.
98 let mut found_by_prefix = None; 101 let mut found_by_prefix = None;
99 for rev in (0..self.len() as Revision).rev() { 102 for rev in (0..self.len() as Revision).rev() {
100 let index_entry = 103 let index_entry =
101 self.index.get_entry(rev).ok_or(RevlogError::Corrupted)?; 104 self.index.get_entry(rev).ok_or(RevlogError::Corrupted)?;
102 if index_entry.hash() == node { 105 if node == *index_entry.hash() {
103 return Ok(rev); 106 return Ok(rev);
104 } 107 }
105 if index_entry.hash().starts_with(node) { 108 if node.is_prefix_of(index_entry.hash()) {
106 if found_by_prefix.is_some() { 109 if found_by_prefix.is_some() {
107 return Err(RevlogError::AmbiguousPrefix); 110 return Err(RevlogError::AmbiguousPrefix);
108 } 111 }
109 found_by_prefix = Some(rev) 112 found_by_prefix = Some(rev)
110 } 113 }
141 }; 144 };
142 145
143 if self.check_hash( 146 if self.check_hash(
144 index_entry.p1(), 147 index_entry.p1(),
145 index_entry.p2(), 148 index_entry.p2(),
146 index_entry.hash(), 149 index_entry.hash().as_bytes(),
147 &data, 150 &data,
148 ) { 151 ) {
149 Ok(data) 152 Ok(data)
150 } else { 153 } else {
151 Err(RevlogError::Corrupted) 154 Err(RevlogError::Corrupted)
161 data: &[u8], 164 data: &[u8],
162 ) -> bool { 165 ) -> bool {
163 let e1 = self.index.get_entry(p1); 166 let e1 = self.index.get_entry(p1);
164 let h1 = match e1 { 167 let h1 = match e1 {
165 Some(ref entry) => entry.hash(), 168 Some(ref entry) => entry.hash(),
166 None => &NULL_NODE_ID, 169 None => &NULL_NODE,
167 }; 170 };
168 let e2 = self.index.get_entry(p2); 171 let e2 = self.index.get_entry(p2);
169 let h2 = match e2 { 172 let h2 = match e2 {
170 Some(ref entry) => entry.hash(), 173 Some(ref entry) => entry.hash(),
171 None => &NULL_NODE_ID, 174 None => &NULL_NODE,
172 }; 175 };
173 176
174 hash(data, &h1, &h2).as_slice() == expected 177 hash(data, h1.as_bytes(), h2.as_bytes()).as_slice() == expected
175 } 178 }
176 179
177 /// Build the full data of a revision out its snapshot 180 /// Build the full data of a revision out its snapshot
178 /// and its deltas. 181 /// and its deltas.
179 #[timed] 182 #[timed]