I think it would be a waste of time to use any form of HashMap . I assume that you compute multi-byte hashes of different data, this is hash es, there is no need to hash them in the future.
Although you do not state this, I assume your hashes are byte sequences. Clearly, either trie or dawg would be ideal to preserve them.
Therefore, I would suggest implementing trie/dawg and use it to store all hashes in the first array. Then you can use all the processing power in parallel to search for each element in the second array in this trie . No locks required.
Added
Here is a simple Dawg implementation that I came across. This seems to work.
public class Dawg { // All my children. Dawg[] children = new Dawg[256]; // Am I a leaf. boolean isLeaf = false; // Add a new word. public void add ( byte[] word ) { // Finds its location, growing as necessary. Dawg loc = find ( word, 0, true ); loc.isLeaf = true; } // String form. public void add ( String word ) { add(word.getBytes()); } // Returns true if word is in the dawg. public boolean contains ( byte [] word ) { // Finds its location, no growing allowed. Dawg d = find ( word, 0, false ); return d != null && d.isLeaf; } // String form. public boolean contains ( String word ) { return contains(word.getBytes()); } // Find the Dawg - growing the tree as necessary if requested. private Dawg find ( byte [] word, int i, boolean grow ) { Dawg child = children[word[i]]; if ( child == null ) { // Not present! if ( grow ) { // Grow the tree. child = new Dawg(); children[word[i]] = child; } } // Found it? if ( child != null ) { // More to find? if ( i < word.length - 1 ) { child = child.find(word, i+1, grow); } } return child; } public static void main ( String[] args ) { Dawg d = new Dawg(); d.add("H"); d.add("Hello"); d.add("World"); d.add("Hell"); System.out.println("Hello is "+(d.contains("Hello")?"in":"out")); System.out.println("World is "+(d.contains("World")?"in":"out")); System.out.println("Hell is "+(d.contains("Hell")?"in":"out")); System.out.println("Hal is "+(d.contains("Hal")?"in":"out")); System.out.println("Hel is "+(d.contains("Hel")?"in":"out")); System.out.println("H is "+(d.contains("H")?"in":"out")); } }
Added
This can be a good start in a parallel version without blocking. These things are usually difficult to verify, so I canβt guarantee that this will work, but in my opinion, it must be.
import java.util.concurrent.atomic.AtomicReferenceArray; public class LFDawg { // All my children. AtomicReferenceArray<LFDawg> children = new AtomicReferenceArray<LFDawg> ( 256 ); // Am I a leaf. boolean isLeaf = false; // Add a new word. public void add ( byte[] word ) { // Finds its location, growing as necessary. LFDawg loc = find( word, 0, true ); loc.isLeaf = true; } // String form. public void add ( String word ) { add( word.getBytes() ); } // Returns true if word is in the dawg. public boolean contains ( byte[] word ) { // Finds its location, no growing allowed. LFDawg d = find( word, 0, false ); return d != null && d.isLeaf; } // String form. public boolean contains ( String word ) { return contains( word.getBytes() ); } // Find the Dawg - growing the tree as necessary if requested. private LFDawg find ( byte[] word, int i, boolean grow ) { LFDawg child = children.get( word[i] ); if ( child == null ) { // Not present! if ( grow ) { // Grow the tree. child = new LFDawg(); if ( !children.compareAndSet( word[i], null, child ) ) { // Someone else got there before me. Get the one they set. child = children.get( word[i] ); } } } // Found it? if ( child != null ) { // More to find? if ( i < word.length - 1 ) { child = child.find( word, i + 1, grow ); } } return child; } public static void main ( String[] args ) { LFDawg d = new LFDawg(); d.add( "H" ); d.add( "Hello" ); d.add( "World" ); d.add( "Hell" ); System.out.println( "Hello is " + ( d.contains( "Hello" ) ? "in" : "out" ) ); System.out.println( "World is " + ( d.contains( "World" ) ? "in" : "out" ) ); System.out.println( "Hell is " + ( d.contains( "Hell" ) ? "in" : "out" ) ); System.out.println( "Hal is " + ( d.contains( "Hal" ) ? "in" : "out" ) ); System.out.println( "Hel is " + ( d.contains( "Hel" ) ? "in" : "out" ) ); System.out.println( "H is " + ( d.contains( "H" ) ? "in" : "out" ) ); } }