use std::fmt::Display;
use super::{
DebugName, Hash,
crc32::{self, CRC_SEED, CRC32TAB},
};
#[derive(Default, Clone, Debug)]
pub struct Crc32local {}
impl Hash for Crc32local {
fn hash<S: super::HashKey>(&self, key: &S) -> i64 {
let mut crc: i64 = CRC_SEED;
for i in 0..key.len() {
let c = key.at(i);
crc = crc >> 8 ^ CRC32TAB[((crc ^ (c as i64)) & 0xff) as usize];
}
crc ^= CRC_SEED;
let crc32 = crc as i32;
crc32.abs() as i64
}
}
#[derive(Default, Clone, Debug)]
pub struct Crc32localDelimiter {
start_pos: usize,
delimiter: u8,
name: DebugName,
}
impl Crc32localDelimiter {
pub fn from(alg: &str) -> Self {
let alg_parts: Vec<&str> = alg.split(super::HASHER_NAME_DELIMITER).collect();
debug_assert!(alg_parts.len() >= 2);
debug_assert_eq!(alg_parts[0], "crc32local");
let delimiter = super::key_delimiter_name_2u8(alg, alg_parts[1]);
if alg_parts.len() == 2 {
return Self {
start_pos: 0,
delimiter,
name: alg.into(),
};
}
debug_assert!(alg_parts.len() == 3);
if let Ok(prefix_len) = alg_parts[2].parse::<usize>() {
return Self {
start_pos: prefix_len,
delimiter,
name: alg.into(),
};
} else {
tracing::debug!("unknown crc32local hash/{}, ignore prefix instead", alg);
return Self {
start_pos: 0,
delimiter,
name: alg.into(),
};
}
}
}
impl super::Hash for Crc32localDelimiter {
fn hash<S: super::HashKey>(&self, key: &S) -> i64 {
let mut crc: i64 = CRC_SEED;
debug_assert!(self.start_pos < key.len());
let check_delimiter = self.delimiter != super::KEY_DELIMITER_NONE;
for i in self.start_pos..key.len() {
let c = key.at(i);
if check_delimiter && (c == self.delimiter) {
break;
}
crc = crc >> 8 ^ CRC32TAB[((crc ^ (c as i64)) & 0xff) as usize];
}
crc ^= CRC_SEED;
let crc32 = crc as i32;
crc32.abs() as i64
}
}
impl Display for Crc32localDelimiter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.name)
}
}
#[derive(Default, Clone, Debug)]
pub struct Crc32localSmartNum {}
impl super::Hash for Crc32localSmartNum {
fn hash<S: super::HashKey>(&self, key: &S) -> i64 {
let (start, end) = crc32::parse_smartnum_hashkey(key);
let mut crc: i64 = CRC_SEED;
for i in start..end {
let c = key.at(i);
crc = crc >> 8 ^ CRC32TAB[((crc ^ (c as i64)) & 0xff) as usize];
}
crc ^= CRC_SEED;
let crc32 = crc as i32;
crc32.abs() as i64
}
}