diff --git a/.build/capnp/index.capnp.json b/.build/capnp/index.capnp.json index 4b2c24be..a979110f 100644 --- a/.build/capnp/index.capnp.json +++ b/.build/capnp/index.capnp.json @@ -1,4 +1,4 @@ { - "source": "e9a1ab0d52fc8a798553feddc01dd0d3221ea2551134bba7993598f4171300af", - "target": "fc0896783f60725dfcde8665bbb81f0fa1385d4b7cda23037ea282219a305e9c" + "source": "7cafdecc6197b3fe7978bcfe649598aa26938d097c052f9eefe37676579ddb9f", + "target": "47b895a77c88757bb44bb6061d0aefd0b24636e10eb078a1b3f65acf8e6398e2" } \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index bc2a1e4f..e32fefde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -717,7 +717,7 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hl" -version = "0.25.1-beta.2" +version = "0.25.1-beta.3" dependencies = [ "atoi", "bincode", @@ -767,6 +767,7 @@ dependencies = [ "thiserror", "wildmatch", "winapi", + "wyhash", ] [[package]] @@ -1857,6 +1858,15 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +[[package]] +name = "wyhash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf6e163c25e3fac820b4b453185ea2dea3b6a3e0a721d4d23d75bd33734c295" +dependencies = [ + "rand_core", +] + [[package]] name = "yaml-rust" version = "0.4.5" diff --git a/Cargo.toml b/Cargo.toml index 317e0ded..5ef3df00 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.2" +version = "0.25.1-beta.3" 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" @@ -43,6 +42,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" @@ -60,6 +60,7 @@ snap = "1" thiserror = "1" wildmatch = "2" winapi = {version = "0", features = ["handleapi"]} +wyhash = "0" [target.'cfg(target_os = "macos")'.dependencies] kqueue = "1" diff --git a/schema/index.capnp b/schema/index.capnp index 71c65a47..8337492f 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,19 @@ struct Chronology { jumps @3 :List(UInt32); } +# HashAlgorithm is an algorithm used to calculate data hash. +enum HashAlgorithm { + sha256 @0; + gxHash64 @1; + wyHash @2; +} + +# 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 fe7d23d7..490f659a 100644 --- a/src/index.rs +++ b/src/index.rs @@ -47,6 +47,15 @@ pub type Reader = dyn Read + Send + Sync; // --- +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub enum Hash { + Sha256(GenericArray), + GxHash64(u64), + WyHash(u64), +} + +// --- + #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] pub struct Timestamp { pub sec: i64, @@ -148,6 +157,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 +172,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 +191,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 +223,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 +238,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 +248,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, b'\n'); 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 +264,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::WyHash(wyhash::wyhash(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 +307,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 +415,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 +530,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 +543,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 +610,45 @@ 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::WyHash) => { + let value = hash.get_value()?; + if value.len() == 8 { + Ok(Some(Hash::WyHash(u64::from_be_bytes(value.try_into().unwrap())))) + } else { + Ok(None) + } + } + Some(schema::HashAlgorithm::GxHash64) => Ok(None), + 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::WyHash(value)) => { + to.set_algorithm(schema::HashAlgorithm::WyHash); + to.set_value(&value.to_be_bytes()); + } + Some(Hash::GxHash64(_)) => (), + None => (), + } + Ok(()) + } } // --- @@ -589,16 +672,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..46b375cd 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,310 @@ pub mod chronology { } } } + +#[repr(u16)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum HashAlgorithm { + Sha256 = 0, + GxHash64 = 1, + WyHash = 2, +} + +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), + 2 => ::core::result::Result::Ok(Self::WyHash), + 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; 31] = [ + ::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, 79, 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(12, 0, 0, 0, 1, 0, 2, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(29, 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(21, 0, 0, 0, 74, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(2, 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(115, 104, 97, 50, 53, 54, 0, 0), + ::capnp::word(103, 120, 72, 97, 115, 104, 54, 52), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(119, 121, 72, 97, 115, 104, 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;