@@ -182,6 +182,61 @@ impl<const N: usize> Fingerprint<N> {
182182 & self . words
183183 }
184184
185+ /// Multi-lane SIMD view: iterate fingerprint as batches of 8 u64 words.
186+ ///
187+ /// At N=256 (16K fingerprint), this yields 32 chunks of 8 words each.
188+ /// Each chunk is one AVX-512 VPOPCNTDQ iteration (512 bits at a time).
189+ /// Consumer uses `U64x8::from_slice(chunk)` for SIMD popcount.
190+ #[ inline]
191+ pub fn chunks_u64x8 ( & self ) -> impl Iterator < Item = & [ u64 ] > {
192+ self . words . chunks ( 8 )
193+ }
194+
195+ /// Multi-lane SIMD view: iterate as batches of 64 bytes.
196+ ///
197+ /// At N=256 (16K fingerprint), yields 32 chunks of 64 bytes.
198+ /// Each chunk = one U8x64 load for byte-level SIMD ops.
199+ #[ inline]
200+ pub fn chunks_u8x64 ( & self ) -> impl Iterator < Item = & [ u8 ] > {
201+ self . as_bytes ( ) . chunks ( 64 )
202+ }
203+
204+ /// Bundle (majority vote) across multiple fingerprints.
205+ ///
206+ /// Returns a new fingerprint where each bit is set if more than
207+ /// half of the input fingerprints have it set.
208+ pub fn bundle ( items : & [ & Self ] ) -> Self {
209+ let n = items. len ( ) ;
210+ if n == 0 { return Self :: zero ( ) ; }
211+ let threshold = n / 2 ;
212+ let mut result = [ 0u64 ; N ] ;
213+ for w in 0 ..N {
214+ for bit in 0 ..64 {
215+ let count: usize = items. iter ( )
216+ . filter ( |fp| ( fp. words [ w] >> bit) & 1 == 1 )
217+ . count ( ) ;
218+ if count > threshold {
219+ result[ w] |= 1u64 << bit;
220+ }
221+ }
222+ }
223+ Self { words : result }
224+ }
225+
226+ /// Create a quasi-orthogonal fingerprint from a seed.
227+ /// Uses golden-ratio-multiplied seeds to ensure near-orthogonality.
228+ pub fn orthogonal ( seed : u64 ) -> Self {
229+ Self :: random ( seed. wrapping_mul ( 0x9E3779B97F4A7C15 ) )
230+ }
231+
232+ /// Bitwise OR.
233+ #[ inline]
234+ pub fn or ( & self , other : & Self ) -> Self {
235+ let mut words = [ 0u64 ; N ] ;
236+ for i in 0 ..N { words[ i] = self . words [ i] | other. words [ i] ; }
237+ Self { words }
238+ }
239+
185240 /// Create from content string (SHA-256-like hash expansion).
186241 pub fn from_content ( data : & str ) -> Self {
187242 let mut h = 0x736f6d6570736575u64 ;
0 commit comments