@@ -19,7 +19,28 @@ import { Md5, Integer } from '@firebase/webchannel-wrapper';
19
19
import { newTextEncoder } from '../platform/serializer' ;
20
20
import { debugAssert } from '../util/assert' ;
21
21
22
- const MAX_64_BIT_UNSIGNED_INTEGER = Integer . fromNumber ( Math . pow ( 2 , 64 ) ) ;
22
+ const MAX_64_BIT_UNSIGNED_INTEGER = new Integer ( [ 0xffffffff , 0xffffffff ] , 0 ) ;
23
+
24
+ // Hash a string using md5 hashing algorithm.
25
+ function getMd5HashValue ( value : string ) : Uint8Array {
26
+ const encodedValue = newTextEncoder ( ) . encode ( value ) ;
27
+ const md5 = new Md5 ( ) ;
28
+ md5 . update ( encodedValue ) ;
29
+ return new Uint8Array ( md5 . digest ( ) ) ;
30
+ }
31
+
32
+ // Interpret the 16 bytes array as two 64-bit unsigned integers, encoded using
33
+ // 2’s complement using little endian.
34
+ function get64BitUints ( Bytes : Uint8Array ) : [ Integer , Integer ] {
35
+ const dataView = new DataView ( Bytes . buffer ) ;
36
+ const chunk1 = dataView . getUint32 ( 0 , /* littleEndian= */ true ) ;
37
+ const chunk2 = dataView . getUint32 ( 4 , /* littleEndian= */ true ) ;
38
+ const chunk3 = dataView . getUint32 ( 8 , /* littleEndian= */ true ) ;
39
+ const chunk4 = dataView . getUint32 ( 12 , /* littleEndian= */ true ) ;
40
+ const integer1 = new Integer ( [ chunk1 , chunk2 ] , 0 ) ;
41
+ const integer2 = new Integer ( [ chunk3 , chunk4 ] , 0 ) ;
42
+ return [ integer1 , integer2 ] ;
43
+ }
23
44
24
45
export class BloomFilter {
25
46
readonly size : number ;
@@ -45,30 +66,10 @@ export class BloomFilter {
45
66
}
46
67
47
68
this . size = bitmap . length * 8 - padding ;
69
+ // Set the size in Integer to avoid repeated calculation in mightContain().
48
70
this . sizeInInteger = Integer . fromNumber ( this . size ) ;
49
71
}
50
72
51
- // Hash a string using md5 hashing algorithm.
52
- private static getMd5HashValue ( value : string ) : Uint8Array {
53
- const md5 = new Md5 ( ) ;
54
- const encodedValue = newTextEncoder ( ) . encode ( value ) ;
55
- md5 . update ( encodedValue ) ;
56
- return new Uint8Array ( md5 . digest ( ) ) ;
57
- }
58
-
59
- // Interpret the 16 bytes array as two 64-bit unsigned integers, encoded using 2’s
60
- // complement using little endian.
61
- private static get64BitUints ( Bytes : Uint8Array ) : [ Integer , Integer ] {
62
- const dataView = new DataView ( Bytes . buffer ) ;
63
- const chunk1 = dataView . getUint32 ( 0 , /* littleEndian= */ true ) ;
64
- const chunk2 = dataView . getUint32 ( 4 , /* littleEndian= */ true ) ;
65
- const chunk3 = dataView . getUint32 ( 8 , /* littleEndian= */ true ) ;
66
- const chunk4 = dataView . getUint32 ( 12 , /* littleEndian= */ true ) ;
67
- const integer1 = new Integer ( [ chunk1 , chunk2 ] , 0 ) ;
68
- const integer2 = new Integer ( [ chunk3 , chunk4 ] , 0 ) ;
69
- return [ integer1 , integer2 ] ;
70
- }
71
-
72
73
// Calculate the ith hash value based on the hashed 64bit integers,
73
74
// and calculate its corresponding bit index in the bitmap to be checked.
74
75
private getBitIndex ( num1 : Integer , num2 : Integer , index : number ) : number {
@@ -85,17 +86,19 @@ export class BloomFilter {
85
86
private isBitSet ( index : number ) : boolean {
86
87
// To retrieve bit n, calculate: (bitmap[n / 8] & (0x01 << (n % 8))).
87
88
const byte = this . bitmap [ Math . floor ( index / 8 ) ] ;
88
- return ( byte & ( 0x01 << index % 8 ) ) !== 0 ;
89
+ const offset = index % 8 ;
90
+ return ( byte & ( 0x01 << offset ) ) !== 0 ;
89
91
}
90
92
91
93
mightContain ( value : string ) : boolean {
92
- // Empty bitmap and empty value should always return false on membership check.
94
+ // Empty bitmap and empty value should always return false on membership
95
+ // check.
93
96
if ( this . size === 0 || value === '' ) {
94
97
return false ;
95
98
}
96
99
97
- const md5HashedValue = BloomFilter . getMd5HashValue ( value ) ;
98
- const [ hash1 , hash2 ] = BloomFilter . get64BitUints ( md5HashedValue ) ;
100
+ const md5HashedValue = getMd5HashValue ( value ) ;
101
+ const [ hash1 , hash2 ] = get64BitUints ( md5HashedValue ) ;
99
102
for ( let i = 0 ; i < this . hashCount ; i ++ ) {
100
103
const index = this . getBitIndex ( hash1 , hash2 , i ) ;
101
104
if ( ! this . isBitSet ( index ) ) {
0 commit comments