BasicMoleculeHashGenerator implements MoleculeHashGenerator { @Override public long generate(IAtomContainer container) { long[] hashes = generator.generate(container); long[] rotated = new long[hashes.length]; Arrays.sort(hashes); long hash = 2147483647L; for (int i = 0; i < hashes.length; i++) { if (i > 0 && hashes[i] == hashes[i - 1]) { hash ^= rotated[i] = pseudorandom.next(rotated[i - 1]); } else { hash ^= rotated[i] = hashes[i]; } } return hash; } BasicMoleculeHashGenerator(AtomHashGenerator generator);   BasicMoleculeHashGenerator(AtomHashGenerator generator, Pseudorandom pseudorandom); @Override long generate(IAtomContainer container);  }
@Test public void testGenerate() { AtomHashGenerator atomGenerator = mock(AtomHashGenerator.class); Pseudorandom prng = mock(Pseudorandom.class); IAtomContainer container = mock(IAtomContainer.class); MoleculeHashGenerator generator = new BasicMoleculeHashGenerator(atomGenerator, prng); when(atomGenerator.generate(container)).thenReturn(new long[]{1, 1, 1, 1}); when(prng.next(1L)).thenReturn(1L); long hashCode = generator.generate(container); verify(atomGenerator, times(1)).generate(container); verify(prng, times(3)).next(1L); verifyNoMoreInteractions(atomGenerator, container, prng); long expected = 2147483647L ^ 1L ^ 1L ^ 1L ^ 1L; assertThat(hashCode, is(expected)); }
@Test public void testGenerate_Rotation() { AtomHashGenerator atomGenerator = mock(AtomHashGenerator.class); Xorshift xorshift = new Xorshift(); IAtomContainer container = mock(IAtomContainer.class); MoleculeHashGenerator generator = new BasicMoleculeHashGenerator(atomGenerator, new Xorshift()); when(atomGenerator.generate(container)).thenReturn(new long[]{5L, 5L, 5L, 5L}); long hashCode = generator.generate(container); verify(atomGenerator, times(1)).generate(container); verifyNoMoreInteractions(atomGenerator, container); long expected = 2147483647L ^ 5L ^ xorshift.next(5L) ^ xorshift.next(xorshift.next(5L)) ^ xorshift.next(xorshift.next(xorshift.next(5L))); assertThat(hashCode, is(expected)); }