@@ -12,7 +12,7 @@ use std::fmt::Display;
1212/// ================ 基于i32版本 ================
1313/// 备注:不取名crc32-abs,是为了区分i32/i63的base,及为后续扩展做准备 fishermen
1414/// 7 crc32abs: 转为i32,然后进行abs操作
15- /// 8 后续可能会有crc32abs-xxx,此处先预留语义 ;
15+ /// 8 后续可能会有crc32abs-delimiter,基于point/pound/underscore之前的部分key,先转为i32,然后进行abs操作 ;
1616///
1717
1818pub ( super ) const CRC32TAB : [ i64 ; 256 ] = [
@@ -82,6 +82,18 @@ pub struct Crc32SmartNum {}
8282#[ derive( Default , Clone , Debug ) ]
8383pub struct Crc32MixNum { }
8484
85+ /// 遵从i32进行crc32计算,并进行abs操作;
86+ #[ derive( Debug , Clone , Default ) ]
87+ pub struct Crc32Abs ;
88+
89+ /// 遵从i32进行crc32计算,并进行abs操作,且只计算startpos之后、delimiter之前的字符,格式:$start+$hashkey+$delimiter$
90+ #[ derive( Default , Clone , Debug ) ]
91+ pub struct Crc32AbsDelimiter {
92+ start_pos : usize ,
93+ delimiter : u8 ,
94+ name : DebugName ,
95+ }
96+
8597// 对全key做crc32
8698impl super :: Hash for Crc32 {
8799 #[ inline]
@@ -331,10 +343,6 @@ impl super::Hash for Crc32MixNum {
331343 }
332344}
333345
334- /// 遵从i32进行crc32计算,并进行abs操作;
335- #[ derive( Debug , Clone , Default ) ]
336- pub struct Crc32Abs ;
337-
338346impl Hash for Crc32Abs {
339347 fn hash < S : super :: HashKey > ( & self , key : & S ) -> i64 {
340348 let mut crc: i64 = CRC_SEED ;
@@ -356,3 +364,71 @@ impl Hash for Crc32Abs {
356364 crc as i64
357365 }
358366}
367+
368+ /// --- Crc32AbsDelimiter impl: crc32abs-point/underscore/pound ---
369+ impl Crc32AbsDelimiter {
370+ pub fn from ( alg : & str ) -> Self {
371+ let alg_parts: Vec < & str > = alg. split ( super :: HASHER_NAME_DELIMITER ) . collect ( ) ;
372+
373+ debug_assert ! ( alg_parts. len( ) >= 2 ) ;
374+ debug_assert_eq ! ( alg_parts[ 0 ] , "crc32abs" ) ;
375+
376+ let delimiter = super :: key_delimiter_name_2u8 ( alg, alg_parts[ 1 ] ) ;
377+
378+ if alg_parts. len ( ) == 2 {
379+ return Self {
380+ start_pos : 0 ,
381+ delimiter,
382+ name : alg. into ( ) ,
383+ } ;
384+ }
385+
386+ debug_assert ! ( alg_parts. len( ) == 3 ) ;
387+ if let Ok ( prefix_len) = alg_parts[ 2 ] . parse :: < usize > ( ) {
388+ return Self {
389+ start_pos : prefix_len,
390+ delimiter,
391+ name : alg. into ( ) ,
392+ } ;
393+ } else {
394+ log:: debug!( "found unknown hash/{}, ignore prefix instead" , alg) ;
395+ return Self {
396+ start_pos : 0 ,
397+ delimiter,
398+ name : alg. into ( ) ,
399+ } ;
400+ }
401+ }
402+ }
403+
404+ impl super :: Hash for Crc32AbsDelimiter {
405+ fn hash < S : super :: HashKey > ( & self , key : & S ) -> i64 {
406+ let mut crc: i64 = CRC_SEED ;
407+ debug_assert ! ( self . start_pos < key. len( ) ) ;
408+
409+ let check_delimiter = self . delimiter != super :: KEY_DELIMITER_NONE ;
410+ for i in self . start_pos ..key. len ( ) {
411+ let c = key. at ( i) ;
412+ if check_delimiter && ( c == self . delimiter ) {
413+ break ;
414+ }
415+ crc = ( ( crc >> 8 ) & 0x00FFFFFF ) ^ CRC32TAB [ ( ( crc ^ ( c as i64 ) ) & 0xff ) as usize ] ;
416+ }
417+
418+ crc ^= CRC_SEED ;
419+ crc &= CRC_SEED ;
420+
421+ let mut crc = crc as i32 ;
422+ if crc <= 0 {
423+ log:: debug!( "{:?} - negative hash/{} for key/{:?}" , self . name, crc, key) ;
424+ crc = crc. abs ( ) ;
425+ }
426+ crc as i64
427+ }
428+ }
429+
430+ impl Display for Crc32AbsDelimiter {
431+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
432+ write ! ( f, "{:?}" , self . name)
433+ }
434+ }
0 commit comments