rs_uuids2tinybloom/
lib.rs

1use std::io;
2
3use io::BufRead;
4
5use io::ErrorKind;
6
7use io::Write;
8
9pub const TINY_BLOOM_BYTE_SIZE: u8 = 32;
10pub const TINY_BLOOM_BIT_SIZE: u16 = 256;
11
12pub const NUM_OF_ITEMS_DEFAULT: u8 = TINY_BLOOM_BYTE_SIZE;
13pub const NUM_OF_HASH_DEFAULT: u8 = 4;
14pub const HASH_SIZE: u8 = 1;
15
16pub fn uuid2hash4_hi(u: u128) -> [u8; 4] {
17    let a: [u8; 16] = u.to_be_bytes();
18    [a[0], a[1], a[2], a[3]]
19}
20
21pub fn uuid2hash4(u: u128) -> [u8; 4] {
22    uuid2hash4_hi(u)
23}
24
25pub fn set_bit(mut bloom: [u8; 32], bitpos: u8) -> [u8; 32] {
26    let bytepos: u8 = bitpos >> 3;
27    let original: u8 = bloom[bytepos as usize];
28    let localpos: u8 = bitpos & 0x07;
29    let one: u8 = 1;
30    let shifted: u8 = one << localpos;
31    let neo: u8 = original | shifted;
32    bloom[bytepos as usize] = neo;
33    bloom
34}
35
36pub fn update_bloom(bloom: [u8; 32], id: u128) -> [u8; 32] {
37    let hash: [u8; 4] = uuid2hash4(id);
38    hash.into_iter().fold(bloom, |state, next| {
39        let current_hash: u8 = next;
40        set_bit(state, current_hash)
41    })
42}
43
44pub fn uuids2bloom<I>(uuids: I) -> [u8; 32]
45where
46    I: Iterator<Item = u128>,
47{
48    uuids.fold([0; 32], update_bloom)
49}
50
51pub fn rdr2uuids_raw<R>(mut rdr: R) -> impl Iterator<Item = Result<u128, io::Error>>
52where
53    R: BufRead,
54{
55    let mut buf: [u8; 16] = [0; 16];
56
57    std::iter::from_fn(move || match rdr.read_exact(&mut buf) {
58        Ok(_) => Some(Ok(u128::from_be_bytes(buf))),
59        Err(e) => match e.kind() {
60            ErrorKind::UnexpectedEof => None,
61            _ => Some(Err(e)),
62        },
63    })
64}
65
66pub fn stdin2uuids_raw() -> impl Iterator<Item = u128> {
67    rdr2uuids_raw(io::stdin().lock()).map_while(Result::ok)
68}
69
70pub fn bloom2wtr_raw<W>(mut wtr: W) -> impl FnMut([u8; 32]) -> Result<(), io::Error>
71where
72    W: Write,
73{
74    move |bloom: [u8; 32]| {
75        let s: &[u8] = &bloom;
76        wtr.write_all(s)
77    }
78}
79
80pub fn bloom2stdout_raw(bloom: [u8; 32]) -> Result<(), io::Error> {
81    let o = io::stdout();
82    let mut l = o.lock();
83    bloom2wtr_raw(&mut l)(bloom)?;
84    l.flush()
85}
86
87pub fn stdin2uuids2bloom2stdout_raw() -> Result<(), io::Error> {
88    let uuids = stdin2uuids_raw();
89    let bloom: [u8; 32] = uuids2bloom(uuids);
90    bloom2stdout_raw(bloom)
91}