diff --git a/.build/capnp/index.capnp.json b/.build/capnp/index.capnp.json index 4b2c24be..3fb897f3 100644 --- a/.build/capnp/index.capnp.json +++ b/.build/capnp/index.capnp.json @@ -1,4 +1,4 @@ { - "source": "e9a1ab0d52fc8a798553feddc01dd0d3221ea2551134bba7993598f4171300af", - "target": "fc0896783f60725dfcde8665bbb81f0fa1385d4b7cda23037ea282219a305e9c" + "source": "a24016e5b59980a2589d90683fed3eda21b9d736133eaa9d31b7e0af80d0ebb2", + "target": "8bea793178710915cd183a95aa10c99a41bd6d23ccec7bcf2b295b48205a6b9b" } \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 6e20a95a..e013f04c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -657,6 +657,16 @@ dependencies = [ "wasi", ] +[[package]] +name = "gxhash" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "370b2ac6cb58eb38e600bf6a783f8cca3f164d5fe5e501ad274d5dc8e94c7212" +dependencies = [ + "rand", + "rustc_version", +] + [[package]] name = "half" version = "1.8.2" @@ -717,7 +727,7 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hl" -version = "0.25.1-beta.1" +version = "0.25.1-beta.2" dependencies = [ "atoi", "bincode", @@ -740,6 +750,7 @@ dependencies = [ "enum-map", "flate2", "generic-array", + "gxhash", "heapless", "hex", "htp", @@ -1193,6 +1204,12 @@ dependencies = [ "plotters-backend", ] +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro2" version = "1.0.71" @@ -1217,6 +1234,18 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", "rand_core", ] @@ -1225,6 +1254,9 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] [[package]] name = "rayon" @@ -1350,6 +1382,15 @@ dependencies = [ "ordered-multimap", ] +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.28" @@ -1378,6 +1419,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "semver" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" + [[package]] name = "serde" version = "1.0.193" diff --git a/Cargo.toml b/Cargo.toml index 74fc24bc..92ad6a37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ categories = ["command-line-utilities"] description = "Utility for viewing json-formatted log files." keywords = ["cli", "human", "log"] name = "hl" -version = "0.25.1-beta.1" +version = "0.25.1-beta.2" edition = "2021" build = "build.rs" @@ -17,7 +17,6 @@ serde_json = { version = "1", features = ["raw_value"] } sha2 = "0" [dependencies] -nu-ansi-term = "0" atoi = "1" bincode = "1" bitmask = "0" @@ -36,6 +35,7 @@ derive_deref = "1" enum-map = "2" flate2 = "1" generic-array = "0" +gxhash = "3" heapless = "0" hex = "0" htp = { git = "https://github.com/pamburus/htp.git" } @@ -43,6 +43,7 @@ humantime = "2" itertools = "0" itoa = { version = "1", default-features = false } notify = { version = "6", features = ["macos_kqueue"] } +nu-ansi-term = "0" num_cpus = "1" once_cell = "1" pest = "2" diff --git a/schema/index.capnp b/schema/index.capnp index 71c65a47..61adcbdd 100644 --- a/schema/index.capnp +++ b/schema/index.capnp @@ -24,6 +24,7 @@ struct SourceBlock { size @1 :UInt32; index @2 :Index; chronology @3 :Chronology; + hash @4 :Hash; } # Index holds index information of a block or a whole file. @@ -65,6 +66,18 @@ struct Chronology { jumps @3 :List(UInt32); } +# HashAlgorithm is an algorithm used to calculate data hash. +enum HashAlgorithm { + sha256 @0; + gxhash64 @1; +} + +# Hash is a hash of some data. +struct Hash { + algorithm @0 :HashAlgorithm; + value @1 :Data; +} + # Various flags. const flagLevelDebug :UInt64 = 0x0000000000000001; const flagLevelInfo :UInt64 = 0x0000000000000002; diff --git a/src/index.rs b/src/index.rs index 88b5c80b..8a2b2488 100644 --- a/src/index.rs +++ b/src/index.rs @@ -47,6 +47,14 @@ pub type Reader = dyn Read + Send + Sync; // --- +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub enum Hash { + Sha256(GenericArray), + GxHash64(u64), +} + +// --- + #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] pub struct Timestamp { pub sec: i64, @@ -148,6 +156,7 @@ impl Indexer { let meta = source_path.metadata()?; let hash = hex::encode(sha256(source_path.to_string_lossy().as_bytes())); let index_path = self.dir.join(PathBuf::from(hash)); + let mut existing_index = None; if Path::new(&index_path).exists() { let mut file = match File::open(&index_path) { Ok(file) => file, @@ -162,10 +171,11 @@ impl Indexer { if meta.len() == index.source().size && ts(meta.modified()?) == index.source().modified { return Ok(index); } + existing_index = Some(index) } } - self.build_index(&source_path, &index_path) + self.build_index(&source_path, &index_path, existing_index) } /// Builds index for the given stream. @@ -180,10 +190,11 @@ impl Indexer { }, input, &mut std::io::sink(), + None, ) } - fn build_index(&self, source_path: &PathBuf, index_path: &PathBuf) -> Result { + fn build_index(&self, source_path: &PathBuf, index_path: &PathBuf, existing_index: Option) -> Result { let mut input = match Input::open(&source_path) { Ok(input) => input, Err(err) => { @@ -211,7 +222,13 @@ impl Indexer { }); } }; - self.process_file(&source_path, (&metadata).try_into()?, &mut input.stream, &mut output) + self.process_file( + &source_path, + (&metadata).try_into()?, + &mut input.stream, + &mut output, + existing_index, + ) } fn process_file( @@ -220,6 +237,7 @@ impl Indexer { metadata: Metadata, input: &mut Reader, output: &mut Writer, + existing_index: Option, ) -> Result { let n = self.concurrency; let sfi = Arc::new(SegmentBufFactory::new(self.buffer_size.try_into()?)); @@ -229,14 +247,14 @@ impl Indexer { // prepare receive/transmit channels for output data let (txo, rxo): (Vec<_>, Vec<_>) = (0..n) .into_iter() - .map(|_| channel::bounded::<(usize, Stat, Chronology)>(1)) + .map(|_| channel::bounded::<(usize, Stat, Chronology, Option)>(1)) .unzip(); // spawn reader thread let reader = scope.spawn(closure!(clone sfi, |_| -> Result<()> { let mut sn: usize = 0; let scanner = Scanner::new(sfi, "\n".to_string()); for item in scanner.items(input).with_max_segment_size(self.max_message_size.try_into()?) { - if let Err(_) = txi[sn % n].send(item?) { + if let Err(_) = txi[sn % n].send((sn, item?)) { break; } sn += 1; @@ -245,19 +263,27 @@ impl Indexer { })); // spawn processing threads for (rxi, txo) in izip!(rxi, txo) { - scope.spawn(closure!(ref sfi, |_| { - for segment in rxi.iter() { - let ((stat, chronology), segment) = match segment { - Segment::Complete(segment) => (self.process_segment(&segment), segment), + scope.spawn(closure!(ref sfi, ref existing_index, |_| { + for (sn, segment) in rxi.iter() { + let (stat, chronology, segment, hash) = match segment { + Segment::Complete(segment) => { + let hash = Hash::GxHash64(gxhash::gxhash64(segment.data(), 0)); + let (stat, chronology) = existing_index + .as_ref() + .and_then(|index| Self::match_segment(&index, sn, &hash)) + .map(|(stat, chronology)| (stat, chronology)) + .unwrap_or_else(|| self.process_segment(&segment)); + (stat, chronology, segment, Some(hash)) + } Segment::Incomplete(segment, _) => { let mut stat = Stat::new(); stat.add_invalid(); - ((stat, Chronology::default()), segment) + (stat, Chronology::default(), segment, None) } }; let size = segment.data().len(); sfi.recycle(segment); - if let Err(_) = txo.send((size, stat, chronology)) { + if let Err(_) = txo.send((size, stat, chronology, hash)) { break; }; } @@ -280,12 +306,15 @@ impl Indexer { let mut offset: u64 = 0; loop { match rxo[sn % n].recv() { - Ok((size, stat, chronology)) => { + Ok((size, stat, chronology, hash)) => { index.source.stat.merge(&stat); - index - .source - .blocks - .push(SourceBlock::new(offset, size.try_into()?, stat, chronology)); + index.source.blocks.push(SourceBlock::new( + offset, + size.try_into()?, + stat, + chronology, + hash, + )); offset += u64::try_from(size)?; } Err(RecvError) => { @@ -385,6 +414,18 @@ impl Indexer { }; (stat, chronology) } + + fn match_segment(index: &Index, sn: usize, hash: &Hash) -> Option<(Stat, Chronology)> { + index.source().blocks.get(sn).and_then(|block| { + block.hash.as_ref().and_then(|h| { + if h == hash { + Some((block.stat.clone(), block.chronology.clone())) + } else { + None + } + }) + }) + } } // --- @@ -488,6 +529,7 @@ impl Index { size: block.get_size(), stat: Self::load_stat(block.get_index()?), chronology: Self::load_chronology(block.get_chronology()?)?, + hash: Self::load_hash(block.get_hash()?)?, }) } Ok(result) @@ -500,7 +542,8 @@ impl Index { block.set_offset(source_block.offset); block.set_size(source_block.size); Self::save_stat(block.reborrow().init_index(), &source_block.stat); - Self::save_chronology(block.init_chronology(), &source_block.chronology)?; + Self::save_chronology(block.reborrow().init_chronology(), &source_block.chronology)?; + Self::save_hash(block.init_hash(), &source_block.hash)?; } Ok(()) } @@ -566,6 +609,43 @@ impl Index { } Ok(()) } + + fn load_hash(hash: schema::hash::Reader) -> Result> { + match hash.get_algorithm().ok() { + Some(schema::HashAlgorithm::Sha256) => { + let value = hash.get_value()?; + if value.len() == 32 { + Ok(Some(Hash::Sha256(*GenericArray::from_slice(value)))) + } else { + Ok(None) + } + } + Some(schema::HashAlgorithm::Gxhash64) => { + let value = hash.get_value()?; + if value.len() == 8 { + Ok(Some(Hash::GxHash64(u64::from_be_bytes(value.try_into().unwrap())))) + } else { + Ok(None) + } + } + _ => Ok(None), + } + } + + fn save_hash(mut to: schema::hash::Builder, from: &Option) -> Result<()> { + match from { + Some(Hash::Sha256(value)) => { + to.set_algorithm(schema::HashAlgorithm::Sha256); + to.set_value(value.as_slice()); + } + Some(Hash::GxHash64(value)) => { + to.set_algorithm(schema::HashAlgorithm::Gxhash64); + to.set_value(&value.to_be_bytes()); + } + None => (), + } + Ok(()) + } } // --- @@ -589,16 +669,18 @@ pub struct SourceBlock { pub size: u32, pub stat: Stat, pub chronology: Chronology, + pub hash: Option, } impl SourceBlock { /// Returns a new SourceBlock. - pub fn new(offset: u64, size: u32, stat: Stat, chronology: Chronology) -> Self { + pub fn new(offset: u64, size: u32, stat: Stat, chronology: Chronology, hash: Option) -> Self { Self { offset, size, stat, chronology, + hash, } } diff --git a/src/index_capnp.rs b/src/index_capnp.rs index 08c10a6a..a01d2611 100644 --- a/src/index_capnp.rs +++ b/src/index_capnp.rs @@ -901,11 +901,19 @@ pub mod source_block { pub fn has_chronology(&self) -> bool { !self.reader.get_pointer_field(1).is_null() } + #[inline] + pub fn get_hash(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(2), ::core::option::Option::None) + } + #[inline] + pub fn has_hash(&self) -> bool { + !self.reader.get_pointer_field(2).is_null() + } } pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { - const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 2, pointers: 2 }; + const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 2, pointers: 3 }; } impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { const TYPE_ID: u64 = _private::TYPE_ID; @@ -1003,6 +1011,22 @@ pub mod source_block { pub fn has_chronology(&self) -> bool { !self.builder.is_pointer_field_null(1) } + #[inline] + pub fn get_hash(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(2), ::core::option::Option::None) + } + #[inline] + pub fn set_hash(&mut self, value: crate::index_capnp::hash::Reader<'_>) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(2), value, false) + } + #[inline] + pub fn init_hash(self, ) -> crate::index_capnp::hash::Builder<'a> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(2), 0) + } + #[inline] + pub fn has_hash(&self) -> bool { + !self.builder.is_pointer_field_null(2) + } } pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } @@ -1018,54 +1042,64 @@ pub mod source_block { pub fn get_chronology(&self) -> crate::index_capnp::chronology::Pipeline { ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(1)) } + pub fn get_hash(&self) -> crate::index_capnp::hash::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(2)) + } } mod _private { - pub static ENCODED_NODE: [::capnp::Word; 78] = [ + pub static ENCODED_NODE: [::capnp::Word; 93] = [ ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), ::capnp::word(96, 2, 222, 79, 120, 87, 225, 204), ::capnp::word(12, 0, 0, 0, 1, 0, 2, 0), ::capnp::word(159, 109, 14, 67, 239, 4, 192, 180), - ::capnp::word(2, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(3, 0, 7, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(21, 0, 0, 0, 194, 0, 0, 0), ::capnp::word(29, 0, 0, 0, 7, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), - ::capnp::word(25, 0, 0, 0, 231, 0, 0, 0), + ::capnp::word(25, 0, 0, 0, 31, 1, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(105, 110, 100, 101, 120, 46, 99, 97), ::capnp::word(112, 110, 112, 58, 83, 111, 117, 114), ::capnp::word(99, 101, 66, 108, 111, 99, 107, 0), ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), - ::capnp::word(16, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(20, 0, 0, 0, 3, 0, 4, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), - ::capnp::word(97, 0, 0, 0, 58, 0, 0, 0), + ::capnp::word(125, 0, 0, 0, 58, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), - ::capnp::word(92, 0, 0, 0, 3, 0, 1, 0), - ::capnp::word(104, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(120, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(132, 0, 0, 0, 2, 0, 1, 0), ::capnp::word(1, 0, 0, 0, 2, 0, 0, 0), ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), - ::capnp::word(101, 0, 0, 0, 42, 0, 0, 0), + ::capnp::word(129, 0, 0, 0, 42, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), - ::capnp::word(96, 0, 0, 0, 3, 0, 1, 0), - ::capnp::word(108, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(124, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(136, 0, 0, 0, 2, 0, 1, 0), ::capnp::word(2, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 1, 0, 2, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), - ::capnp::word(105, 0, 0, 0, 50, 0, 0, 0), + ::capnp::word(133, 0, 0, 0, 50, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), - ::capnp::word(100, 0, 0, 0, 3, 0, 1, 0), - ::capnp::word(112, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(128, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(140, 0, 0, 0, 2, 0, 1, 0), ::capnp::word(3, 0, 0, 0, 1, 0, 0, 0), ::capnp::word(0, 0, 1, 0, 3, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), - ::capnp::word(109, 0, 0, 0, 90, 0, 0, 0), + ::capnp::word(137, 0, 0, 0, 90, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), - ::capnp::word(108, 0, 0, 0, 3, 0, 1, 0), - ::capnp::word(120, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(136, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(148, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(4, 0, 0, 0, 2, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 4, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(145, 0, 0, 0, 42, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(140, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(152, 0, 0, 0, 2, 0, 1, 0), ::capnp::word(111, 102, 102, 115, 101, 116, 0, 0), ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), @@ -1099,6 +1133,14 @@ pub mod source_block { ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(104, 97, 115, 104, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(130, 241, 82, 110, 153, 162, 113, 227), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), ]; pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { match index { @@ -1106,6 +1148,7 @@ pub mod source_block { 1 => ::introspect(), 2 => ::introspect(), 3 => ::introspect(), + 4 => ::introspect(), _ => panic!("invalid field index {}", index), } } @@ -1117,7 +1160,7 @@ pub mod source_block { nonunion_members: NONUNION_MEMBERS, members_by_discriminant: MEMBERS_BY_DISCRIMINANT, }; - pub static NONUNION_MEMBERS : &[u16] = &[0,1,2,3]; + pub static NONUNION_MEMBERS : &[u16] = &[0,1,2,3,4]; pub static MEMBERS_BY_DISCRIMINANT : &[u16] = &[]; pub const TYPE_ID: u64 = 0xcce1_5778_4fde_0260; } @@ -2776,6 +2819,304 @@ pub mod chronology { } } } + +#[repr(u16)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum HashAlgorithm { + Sha256 = 0, + Gxhash64 = 1, +} + +impl ::capnp::introspect::Introspect for HashAlgorithm { + fn introspect() -> ::capnp::introspect::Type { ::capnp::introspect::TypeVariant::Enum(::capnp::introspect::RawEnumSchema { encoded_node: &hash_algorithm::ENCODED_NODE, annotation_types: hash_algorithm::get_annotation_types }).into() } +} +impl <'a> ::core::convert::From for ::capnp::dynamic_value::Reader<'a> { + fn from(e: HashAlgorithm) -> Self { ::capnp::dynamic_value::Enum::new(e.into(), ::capnp::introspect::RawEnumSchema { encoded_node: &hash_algorithm::ENCODED_NODE, annotation_types: hash_algorithm::get_annotation_types }.into()).into() } +} +impl ::core::convert::TryFrom for HashAlgorithm { + type Error = ::capnp::NotInSchema; + fn try_from(value: u16) -> ::core::result::Result>::Error> { + match value { + 0 => ::core::result::Result::Ok(Self::Sha256), + 1 => ::core::result::Result::Ok(Self::Gxhash64), + n => ::core::result::Result::Err(::capnp::NotInSchema(n)), + } + } +} +impl From for u16 { + #[inline] + fn from(x: HashAlgorithm) -> u16 { x as u16 } +} +impl ::capnp::traits::HasTypeId for HashAlgorithm { + const TYPE_ID: u64 = 0xe772_27a8_a403_5917u64; +} +mod hash_algorithm { +pub static ENCODED_NODE: [::capnp::Word; 27] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(23, 89, 3, 164, 168, 39, 114, 231), + ::capnp::word(12, 0, 0, 0, 2, 0, 0, 0), + ::capnp::word(159, 109, 14, 67, 239, 4, 192, 180), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 210, 0, 0, 0), + ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 55, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(105, 110, 100, 101, 120, 46, 99, 97), + ::capnp::word(112, 110, 112, 58, 72, 97, 115, 104), + ::capnp::word(65, 108, 103, 111, 114, 105, 116, 104), + ::capnp::word(109, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(8, 0, 0, 0, 1, 0, 2, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(17, 0, 0, 0, 58, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 74, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(115, 104, 97, 50, 53, 54, 0, 0), + ::capnp::word(103, 120, 104, 97, 115, 104, 54, 52), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), +]; +pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) +} +} + +pub mod hash { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { fn introspect() -> ::capnp::introspect::Type { ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types, annotation_types: _private::get_annotation_types }).into() } } + impl ::capnp::traits::Owned for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::OwnedStruct for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + impl <'a,> ::core::marker::Copy for Reader<'a,> {} + impl <'a,> ::core::clone::Clone for Reader<'a,> { + fn clone(&self) -> Self { *self } + } + + impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a,> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new(reader.reader, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::core::fmt::Debug for Reader<'a,> { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt(&::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), f) + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,> Reader<'a,> { + pub fn reborrow(&self) -> Reader<'_,> { + Self { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_algorithm(self) -> ::core::result::Result { + ::core::convert::TryInto::try_into(self.reader.get_data_field::(0)) + } + #[inline] + pub fn get_value(self) -> ::capnp::Result<::capnp::data::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn has_value(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 1, pointers: 1 }; + } + impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl <'a,> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a,> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder, } + } + } + + impl <'a,> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a,>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new(builder.builder, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>}))) + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder.init_struct(::STRUCT_SIZE).into() + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result { + ::core::result::Result::Ok(builder.get_struct(::STRUCT_SIZE, default)?.into()) + } + } + + impl <'a,> ::capnp::traits::SetPointerBuilder for Reader<'a,> { + fn set_pointer_builder(mut pointer: ::capnp::private::layout::PointerBuilder<'_>, value: Self, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_,> { + Builder { builder: self.builder.reborrow() } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_algorithm(self) -> ::core::result::Result { + ::core::convert::TryInto::try_into(self.builder.get_data_field::(0)) + } + #[inline] + pub fn set_algorithm(&mut self, value: crate::index_capnp::HashAlgorithm) { + self.builder.set_data_field::(0, value as u16); + } + #[inline] + pub fn get_value(self) -> ::capnp::Result<::capnp::data::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn set_value(&mut self, value: ::capnp::data::Reader<'_>) { + self.builder.reborrow().get_pointer_field(0).set_data(value); + } + #[inline] + pub fn init_value(self, size: u32) -> ::capnp::data::Builder<'a> { + self.builder.get_pointer_field(0).init_data(size) + } + #[inline] + pub fn has_value(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { _typeless: typeless, } + } + } + impl Pipeline { + } + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 48] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(130, 241, 82, 110, 153, 162, 113, 227), + ::capnp::word(12, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(159, 109, 14, 67, 239, 4, 192, 180), + ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 138, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(25, 0, 0, 0, 119, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(105, 110, 100, 101, 120, 46, 99, 97), + ::capnp::word(112, 110, 112, 58, 72, 97, 115, 104), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(41, 0, 0, 0, 82, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(40, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(52, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(49, 0, 0, 0, 50, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(44, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(56, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(97, 108, 103, 111, 114, 105, 116, 104), + ::capnp::word(109, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(15, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(23, 89, 3, 164, 168, 39, 114, 231), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(15, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(118, 97, 108, 117, 101, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => ::introspect(), + 1 => <::capnp::data::Owned as ::capnp::introspect::Introspect>::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types(child_index: Option, index: u32) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS : &[u16] = &[0,1]; + pub static MEMBERS_BY_DISCRIMINANT : &[u16] = &[]; + pub const TYPE_ID: u64 = 0xe371_a299_6e52_f182; + } +} pub const FLAG_LEVEL_DEBUG: u64 = 1; pub const FLAG_LEVEL_INFO: u64 = 2; pub const FLAG_LEVEL_WARNING: u64 = 4;