##// END OF EJS Templates
rust-index: add append method...
Raphaël Gomès -
r52082:b4d152a2 default
parent child Browse files
Show More
@@ -2,13 +2,17 b' use std::fmt::Debug;'
2 use std::ops::Deref;
2 use std::ops::Deref;
3
3
4 use byteorder::{BigEndian, ByteOrder};
4 use byteorder::{BigEndian, ByteOrder};
5 use bytes_cast::{unaligned, BytesCast};
5
6
7 use super::REVIDX_KNOWN_FLAGS;
6 use crate::errors::HgError;
8 use crate::errors::HgError;
9 use crate::node::{NODE_BYTES_LENGTH, STORED_NODE_ID_BYTES};
7 use crate::revlog::node::Node;
10 use crate::revlog::node::Node;
8 use crate::revlog::{Revision, NULL_REVISION};
11 use crate::revlog::{Revision, NULL_REVISION};
9 use crate::{Graph, GraphError, RevlogIndex, UncheckedRevision};
12 use crate::{Graph, GraphError, RevlogError, RevlogIndex, UncheckedRevision};
10
13
11 pub const INDEX_ENTRY_SIZE: usize = 64;
14 pub const INDEX_ENTRY_SIZE: usize = 64;
15 pub const COMPRESSION_MODE_INLINE: u8 = 2;
12
16
13 pub struct IndexHeader {
17 pub struct IndexHeader {
14 header_bytes: [u8; 4],
18 header_bytes: [u8; 4],
@@ -120,6 +124,81 b' impl std::ops::Index<std::ops::Range<usi'
120 }
124 }
121 }
125 }
122
126
127 pub struct RevisionDataParams {
128 flags: u16,
129 data_offset: u64,
130 data_compressed_length: i32,
131 data_uncompressed_length: i32,
132 data_delta_base: i32,
133 link_rev: i32,
134 parent_rev_1: i32,
135 parent_rev_2: i32,
136 node_id: [u8; NODE_BYTES_LENGTH],
137 _sidedata_offset: u64,
138 _sidedata_compressed_length: i32,
139 data_compression_mode: u8,
140 _sidedata_compression_mode: u8,
141 _rank: i32,
142 }
143
144 #[derive(BytesCast)]
145 #[repr(C)]
146 pub struct RevisionDataV1 {
147 data_offset_or_flags: unaligned::U64Be,
148 data_compressed_length: unaligned::I32Be,
149 data_uncompressed_length: unaligned::I32Be,
150 data_delta_base: unaligned::I32Be,
151 link_rev: unaligned::I32Be,
152 parent_rev_1: unaligned::I32Be,
153 parent_rev_2: unaligned::I32Be,
154 node_id: [u8; STORED_NODE_ID_BYTES],
155 }
156
157 fn _static_assert_size_of_revision_data_v1() {
158 let _ = std::mem::transmute::<RevisionDataV1, [u8; 64]>;
159 }
160
161 impl RevisionDataParams {
162 pub fn validate(&self) -> Result<(), RevlogError> {
163 if self.flags & !REVIDX_KNOWN_FLAGS != 0 {
164 return Err(RevlogError::corrupted(format!(
165 "unknown revlog index flags: {}",
166 self.flags
167 )));
168 }
169 if self.data_compression_mode != COMPRESSION_MODE_INLINE {
170 return Err(RevlogError::corrupted(format!(
171 "invalid data compression mode: {}",
172 self.data_compression_mode
173 )));
174 }
175 // FIXME isn't this only for v2 or changelog v2?
176 if self._sidedata_compression_mode != COMPRESSION_MODE_INLINE {
177 return Err(RevlogError::corrupted(format!(
178 "invalid sidedata compression mode: {}",
179 self._sidedata_compression_mode
180 )));
181 }
182 Ok(())
183 }
184
185 pub fn into_v1(self) -> RevisionDataV1 {
186 let data_offset_or_flags = self.data_offset << 16 | self.flags as u64;
187 let mut node_id = [0; STORED_NODE_ID_BYTES];
188 node_id[..NODE_BYTES_LENGTH].copy_from_slice(&self.node_id);
189 RevisionDataV1 {
190 data_offset_or_flags: data_offset_or_flags.into(),
191 data_compressed_length: self.data_compressed_length.into(),
192 data_uncompressed_length: self.data_uncompressed_length.into(),
193 data_delta_base: self.data_delta_base.into(),
194 link_rev: self.link_rev.into(),
195 parent_rev_1: self.parent_rev_1.into(),
196 parent_rev_2: self.parent_rev_2.into(),
197 node_id,
198 }
199 }
200 }
201
123 /// A Revlog index
202 /// A Revlog index
124 pub struct Index {
203 pub struct Index {
125 bytes: IndexData,
204 bytes: IndexData,
@@ -283,6 +362,20 b' impl Index {'
283 offset_override,
362 offset_override,
284 }
363 }
285 }
364 }
365
366 /// TODO move this to the trait probably, along with other things
367 pub fn append(
368 &mut self,
369 revision_data: RevisionDataParams,
370 ) -> Result<(), RevlogError> {
371 revision_data.validate()?;
372 let new_offset = self.bytes.len();
373 if let Some(offsets) = self.offsets.as_mut() {
374 offsets.push(new_offset)
375 }
376 self.bytes.added.extend(revision_data.into_v1().as_bytes());
377 Ok(())
378 }
286 }
379 }
287
380
288 impl super::RevlogIndex for Index {
381 impl super::RevlogIndex for Index {
@@ -20,6 +20,10 b' use std::fmt;'
20 /// the future.
20 /// the future.
21 pub const NODE_BYTES_LENGTH: usize = 20;
21 pub const NODE_BYTES_LENGTH: usize = 20;
22
22
23 /// The length in bytes set aside on disk for a `Node`. Revlog up to v1 only
24 /// use 20 out of those 32.
25 pub const STORED_NODE_ID_BYTES: usize = 32;
26
23 /// Id of the null node.
27 /// Id of the null node.
24 ///
28 ///
25 /// Used to indicate the absence of node.
29 /// Used to indicate the absence of node.
General Comments 0
You need to be logged in to leave comments. Login now