package org.infinispan.lock; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.infinispan.test.AbstractInfinispanTest; import org.infinispan.util.StripedHashFunction; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @Test(groups = "unit", testName = "lock.StripedHashFunctionTest") public class StripedHashFunctionTest extends AbstractInfinispanTest { private StripedHashFunction<String> stripedHashFunction; @BeforeMethod public void setUp() { stripedHashFunction = new StripedHashFunction<>(500); } public void testHashingDistribution() { // ensure even bucket distribution of lock stripes List<String> keys = createRandomKeys(1000); Map<Integer, Integer> distribution = new HashMap<>(); for (String s : keys) { int segmentIndex = stripedHashFunction.hashToSegment(s); log.tracef("Lock for %s is %s", s, segmentIndex); if (distribution.containsKey(segmentIndex)) { int count = distribution.get(segmentIndex) + 1; distribution.put(segmentIndex, count); } else { distribution.put(segmentIndex, 1); } } // cannot be larger than the number of locks log.trace("dist size: " + distribution.size()); log.trace("num shared locks: " + stripedHashFunction.getNumSegments()); assert distribution.size() <= stripedHashFunction.getNumSegments(); // assume at least a 2/3rd spread assert distribution.size() * 1.5 >= stripedHashFunction.getNumSegments(); } private List<String> createRandomKeys(int number) { List<String> f = new ArrayList<>(number); int i = number; while (f.size() < number) { String s = i + "baseKey" + (10000 + i++); f.add(s); } return f; } }