@@ -0,0 +1,3206 @@
+package water.nbhm;%0A%0Aimport junit.framework.TestCase;%0A%0Aimport java.util.ArrayList;%0Aimport java.util.HashSet;%0Aimport java.util.List;%0Aimport java.util.Set;%0Aimport java.util.concurrent.*;%0A%0Apublic class NonBlockingHashMapLongZeroKeyConcurrentGetPutIfAbsentTest extends TestCase %7B%0A    private static final int N_THREADS = 4;%0A    private static final int ITERATIONS = 1000000;%0A    private ExecutorService service;%0A%0A    protected void setUp() %7B%0A        service = Executors.newFixedThreadPool(N_THREADS);%0A    %7D%0A%0A    protected void tearDown() throws Exception %7B%0A        service.shutdownNow();%0A        service.awaitTermination(1, TimeUnit.HOURS);%0A    %7D%0A%0A%0A    public void test_empty_map_key_0() throws Exception %7B%0A        empty_map_test(0);%0A    %7D%0A%0A    public void test_empty_map_key_123() throws Exception %7B%0A        empty_map_test(123);%0A    %7D%0A%0A    private void empty_map_test(long key) throws Exception %7B%0A        for (int i = 0; i %3C ITERATIONS; i++) %7B%0A            Set%3CString%3E results = runIteration(new NonBlockingHashMapLong%3CString%3E(), key);%0A            assertEquals(results.toString(), 1, results.size());%0A        %7D%0A    %7D%0A%0A    private Set%3CString%3E runIteration(NonBlockingHashMapLong%3CString%3E map, long key) throws Exception %7B%0A        List%3CCallable%3CString%3E%3E tasks = new ArrayList%3CCallable%3CString%3E%3E(N_THREADS);%0A        for (int i = 1; i %3C= N_THREADS; i++) %7B%0A            tasks.add(new PutIfAbsent(map, key, %22worker #%22 + i));%0A        %7D%0A%0A        List%3CString%3E results = executeTasks(tasks);%0A%0A        return new HashSet%3CString%3E(results);%0A    %7D%0A%0A    private List%3CString%3E executeTasks(List%3CCallable%3CString%3E%3E tasks) throws Exception %7B%0A        List%3CFuture%3CString%3E%3E futures = new ArrayList%3CFuture%3CString%3E%3E(N_THREADS);%0A        final CountDownLatch startLatch = new CountDownLatch(N_THREADS + 1);%0A        for (Callable%3CString%3E t : tasks) %7B%0A            final Callable%3CString%3E task = t;%0A            Future%3CString%3E future = service.submit(new Callable%3CString%3E() %7B%0A                @Override%0A                public String call() throws Exception %7B%0A                    startLatch.countDown();%0A                    startLatch.await();%0A                    return task.call();%0A                %7D%0A            %7D);%0A            futures.add(future);%0A        %7D%0A%0A        startLatch.countDown();%0A%0A        List%3CString%3E results = new ArrayList%3CString%3E(N_THREADS);%0A        for (Future%3CString%3E f : futures) %7B%0A            results.add(f.get());%0A        %7D%0A        return results;%0A    %7D%0A%0A    private static class PutIfAbsent implements Callable%3CString%3E %7B%0A        private final NonBlockingHashMapLong%3CString%3E map;%0A        private final String newValue;%0A        private final long key;%0A%0A        public PutIfAbsent(NonBlockingHashMapLong%3CString%3E map, long key, String newValue) %7B%0A            this.map = map;%0A            this.newValue = newValue;%0A            this.key = key;%0A        %7D%0A%0A        @Override%0A        public String call() throws Exception %7B%0A            String value = map.get(key);%0A            if (value == null) %7B%0A                value = newValue;%0A                String tmp = map.putIfAbsent(key, value);%0A                if (tmp != null) %7B%0A                    return tmp;%0A                %7D%0A            %7D%0A            return value;%0A        %7D%0A    %7D%0A%7D%0A

Test that case for NonBlockingHashMapLong for zero and non-zero key on putIfAbsent atomicity