question: private void loadNotifiedDownloads ( ) { notifiedDownloads = new BloomFilter < > ( Constants . NOTIFIED_BLOOM_FILTER_BITSET_SIZE , Constants . NOTIFIED_BLOOM_FILTER_EXPECTED_ELEMENTS ) ; if ( ! notifiedDat . exists ( ) ) { try { notifiedDat . createNewFile ( ) ; } catch ( Throwable e ) { e . printStackTrace ( ) ; LOG . error ( "Could not create notified.dat" , e ) ; } } else if ( notifiedDat . length ( ) > 0 ) { try { ObjectInputStream ois = new ObjectInputStream ( new FileInputStream ( notifiedDat ) ) ; int numberOfElements = ois . readInt ( ) ; BitSet bs = ( BitSet ) ois . readObject ( ) ; ois . close ( ) ; notifiedDownloads = new BloomFilter < > ( Constants . NOTIFIED_BLOOM_FILTER_BITSET_SIZE , Constants . NOTIFIED_BLOOM_FILTER_EXPECTED_ELEMENTS , numberOfElements , bs ) ; LOG . info ( "Loaded bloom filter from notified.dat sucessfully (" + numberOfElements + " elements)" ) ; } catch ( Throwable e ) { LOG . error ( "Error reading notified.dat" , e ) ; notifiedDat . delete ( ) ; try { notifiedDat . createNewFile ( ) ; LOG . info ( "Created new notified.dat file." ) ; } catch ( IOException e1 ) { LOG . error ( e1 . getMessage ( ) , e1 ) ; } } } }
target:  loads a dictionary of infohashes that have been already notified from notified.dat. This binary file packs together infohashes 20 bytes at the time. <p/> this method goes through the file, 20 bytes at the time and populates a HashMap we can use to query wether or not we should notify the user in constant time. <p/> When we have a new infohash, the file conveniently grows by appending the new 20 bytes of the new hash.