package org.radargun.stages.cache.test; import java.util.Random; import org.radargun.config.DefinitionElement; import org.radargun.config.Namespace; import org.radargun.config.Property; import org.radargun.config.PropertyHelper; import org.radargun.stages.test.TestStage; /** * @author Radim Vansa <rvansa@redhat.com> */ public class ConcurrentKeysSelector implements KeySelector { private final long offset; private final long size; private final Random random; public ConcurrentKeysSelector(Random random, long offset, long size) { this.random = random; this.offset = offset; this.size = size; } @Override public long next() { return offset + (random.nextLong() & Long.MAX_VALUE) % size; } @Namespace(name = TestStage.NAMESPACE, deprecatedName = TestStage.DEPRECATED_NAMESPACE) @DefinitionElement(name = "concurrent-keys", doc = "Each thread works with its own private set of keys, fixed for the whole duration of the test.") public static class Factory implements KeySelectorFactory { @Property(doc = "Number of key-value entries per each thread. You have to set either this or total-entries.") protected long numEntriesPerThread = 0; @Property(doc = "Total number of key-value entries. You have to set either this or num-entries-per-thread.") protected long totalEntries = 0; public void init() { if (numEntriesPerThread > 0 && totalEntries > 0) { throw new IllegalStateException("Only one of num-entries-per-thread, total-entries can be set."); } else if (numEntriesPerThread <= 0 || totalEntries <= 0) { throw new IllegalStateException("Either num-entries-per-thread or total-entries have to be set."); } } @Override public KeySelector newInstance(CacheOperationsTestStage stage, Random random, int globalThreadId, int threadId) { int totalThreads = stage.getTotalThreads(); if (numEntriesPerThread > 0) { return new ConcurrentKeysSelector(random, numEntriesPerThread * globalThreadId, numEntriesPerThread); } else if (totalEntries > 0) { if (totalEntries < totalThreads) { throw new IllegalStateException("Number of total threads cannot be greater than number of total entries."); } long offset = totalEntries * globalThreadId / totalThreads; long end = totalEntries * (globalThreadId + 1) / totalThreads; return new ConcurrentKeysSelector(random, offset, end - offset); } else { throw new IllegalStateException("Either num-entries-per-thread or total-entries have to be set."); } } @Override public String toString() { return ConcurrentKeysSelector.class.getSimpleName() + PropertyHelper.toString(this); } } }