github.com/segmentio/parquet-go@v0.0.0-20230712180008-5d42db8f0d47/bloom/block_default.go (about)

     1  //go:build purego && parquet.bloom.no_unroll
     2  
     3  package bloom
     4  
     5  // This file contains direct translation of the algorithms described in the
     6  // parquet bloom filter spec:
     7  // https://github.com/apache/parquet-format/blob/master/BloomFilter.md
     8  //
     9  // There are no practical reasons to eable the parquet.bloom.no_unroll build
    10  // tag, the code is left here as a reference to ensure that the optimized
    11  // implementations of block operations behave the same as the functions in this
    12  // file.
    13  
    14  var salt = [8]uint32{
    15  	0: salt0,
    16  	1: salt1,
    17  	2: salt2,
    18  	3: salt3,
    19  	4: salt4,
    20  	5: salt5,
    21  	6: salt6,
    22  	7: salt7,
    23  }
    24  
    25  func (w *Word) set(i uint) {
    26  	*w |= Word(1 << i)
    27  }
    28  
    29  func (w Word) has(i uint) bool {
    30  	return ((w >> Word(i)) & 1) != 0
    31  }
    32  
    33  func mask(x uint32) Block {
    34  	var b Block
    35  	for i := uint(0); i < 8; i++ {
    36  		y := x * salt[i]
    37  		b[i].set(uint(y) >> 27)
    38  	}
    39  	return b
    40  }
    41  
    42  func (b *Block) Insert(x uint32) {
    43  	masked := mask(x)
    44  	for i := uint(0); i < 8; i++ {
    45  		for j := uint(0); j < 32; j++ {
    46  			if masked[i].has(j) {
    47  				b[i].set(j)
    48  			}
    49  		}
    50  	}
    51  }
    52  
    53  func (b *Block) Check(x uint32) bool {
    54  	masked := mask(x)
    55  	for i := uint(0); i < 8; i++ {
    56  		for j := uint(0); j < 32; j++ {
    57  			if masked[i].has(j) {
    58  				if !b[i].has(j) {
    59  					return false
    60  				}
    61  			}
    62  		}
    63  	}
    64  	return true
    65  }