-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #107 from weibocom/dev
Dev
- Loading branch information
Showing
6 changed files
with
320 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
// 用于兼容api-commons中的cn.sina.api.commons.util.Util.crc32(),一般尽量不用使用 fishermen | ||
|
||
use std::fmt::Display; | ||
|
||
use super::Hash; | ||
|
||
const CRCLOCALTAB: [i64; 256] = [ | ||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, | ||
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, | ||
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, | ||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, | ||
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, | ||
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, | ||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, | ||
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, | ||
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, | ||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, | ||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, | ||
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, | ||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, | ||
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, | ||
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, | ||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, | ||
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, | ||
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, | ||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, | ||
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, | ||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, | ||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, | ||
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, | ||
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, | ||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, | ||
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, | ||
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, | ||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, | ||
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, | ||
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, | ||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, | ||
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, | ||
]; | ||
|
||
const CRCLOCAL_SEED: i64 = 0xffffffff; | ||
// 用于表示无分隔符的场景 | ||
const DELIMITER_NONE: char = 0 as char; | ||
|
||
#[derive(Default, Clone, Debug)] | ||
pub struct Crc32local {} | ||
|
||
impl Hash for Crc32local { | ||
fn hash<S: super::HashKey>(&self, key: &S) -> i64 { | ||
let mut crc: i64 = CRCLOCAL_SEED; | ||
|
||
for i in 0..key.len() { | ||
let c = key.at(i); | ||
crc = crc >> 8 ^ CRCLOCALTAB[((crc ^ (c as i64)) & 0xff) as usize]; | ||
} | ||
|
||
crc ^= CRCLOCAL_SEED; | ||
let crc32 = crc as i32; | ||
crc32.abs() as i64 | ||
} | ||
} | ||
|
||
// Crc32算法,hash key是开始位置之后、分隔符之前的字符串 | ||
#[derive(Default, Clone, Debug)] | ||
pub struct Crc32localDelimiter { | ||
start_pos: usize, | ||
delimiter: char, | ||
name: String, | ||
} | ||
|
||
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"); | ||
|
||
// 如果需要扩展新的分隔符,在这里新增一行即可 fishermen | ||
let delimiter = match alg_parts[1] { | ||
super::CRC32_EXT_POINT => '.', | ||
super::CRC32_EXT_UNDERSCORE => '_', | ||
super::CRC32_EXT_POUND => '#', | ||
_ => { | ||
log::debug!("found unknown hash alg: {}, use crc32 instead", alg); | ||
DELIMITER_NONE | ||
} | ||
}; | ||
|
||
if alg_parts.len() == 2 { | ||
return Self { | ||
start_pos: 0, | ||
delimiter: delimiter, | ||
name: alg.to_string(), | ||
}; | ||
} | ||
|
||
debug_assert!(alg_parts.len() == 3); | ||
if let Ok(prefix_len) = alg_parts[2].parse::<usize>() { | ||
return Self { | ||
start_pos: prefix_len, | ||
delimiter: delimiter, | ||
name: alg.to_string(), | ||
}; | ||
} else { | ||
log::debug!("unknown crc32local hash/{}, ignore prefix instead", alg); | ||
return Self { | ||
start_pos: 0, | ||
delimiter: delimiter, | ||
name: alg.to_string(), | ||
}; | ||
} | ||
} | ||
} | ||
|
||
impl super::Hash for Crc32localDelimiter { | ||
fn hash<S: super::HashKey>(&self, key: &S) -> i64 { | ||
let mut crc: i64 = CRCLOCAL_SEED; | ||
debug_assert!(self.start_pos < key.len()); | ||
|
||
// 对于用“.”、“_”、“#”做分割的hash key,遇到分隔符停止 | ||
let check_delimiter = self.delimiter != DELIMITER_NONE; | ||
for i in self.start_pos..key.len() { | ||
let c = key.at(i); | ||
if check_delimiter && (c == self.delimiter as u8) { | ||
break; | ||
} | ||
crc = crc >> 8 ^ CRCLOCALTAB[((crc ^ (c as i64)) & 0xff) as usize]; | ||
} | ||
|
||
crc ^= CRCLOCAL_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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
use super::{Crc32local, Hash}; | ||
|
||
// 用于支持groupchat中的UidSelectionStrategy | ||
// 算法描述:1 优先解析“_”之前的uid,没有"_"解析整个字符串,如果是数字,直接返回; | ||
// 2 否则进行crc32local计算 | ||
#[derive(Clone, Debug)] | ||
pub struct Rawcrc32local { | ||
crc32local: Crc32local, | ||
} | ||
|
||
impl Default for Rawcrc32local { | ||
fn default() -> Self { | ||
Rawcrc32local { | ||
crc32local: Crc32local::default(), | ||
} | ||
} | ||
} | ||
|
||
const DELIMITER_UNDERSCORE: u8 = '_' as u8; | ||
|
||
impl Hash for Rawcrc32local { | ||
fn hash<S: super::HashKey>(&self, key: &S) -> i64 { | ||
let mut hash = 0; | ||
|
||
// 先尝试按uid_xxx来hash | ||
for i in 0..key.len() { | ||
let c = key.at(i); | ||
if !c.is_ascii_digit() { | ||
// 非数字必须是“_”,否则整体做crc32local计算 | ||
if c == DELIMITER_UNDERSCORE { | ||
return hash; | ||
} else { | ||
hash = 0; | ||
break; | ||
} | ||
} | ||
hash = hash * 10 + (key.at(i) - '0' as u8) as i64; | ||
} | ||
|
||
// hash如果为0,进行crc32local | ||
if hash == 0 { | ||
return self.crc32local.hash(key); | ||
} else if hash > 0 { | ||
return hash; | ||
} else { | ||
log::error!("found malform rawcrc32local for key: {:?}", key); | ||
return 0; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.