diff --git a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/stats/CacheStats.java b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/stats/CacheStats.java index 7f35b72a5c..f90a0ee91f 100644 --- a/caffeine/src/main/java/com/github/benmanes/caffeine/cache/stats/CacheStats.java +++ b/caffeine/src/main/java/com/github/benmanes/caffeine/cache/stats/CacheStats.java @@ -35,9 +35,9 @@ *
  • After successfully loading an entry {@code missCount} and {@code loadSuccessCount} are * incremented, and the total loading time, in nanoseconds, is added to * {@code totalLoadTime}. - *
  • When an exception is thrown while loading an entry, {@code missCount} and {@code - * loadFailureCount} are incremented, and the total loading time, in nanoseconds, is - * added to {@code totalLoadTime}. + *
  • When an exception is thrown while loading an entry or if the loaded value is {code null}, + * {@code missCount} and {@code loadFailureCount} are incremented, and the total loading + * time, in nanoseconds, is added to {@code totalLoadTime}. *
  • Cache lookups that encounter a missing cache entry that is still loading will wait * for loading to complete (whether successful or not) and then increment {@code missCount}. * @@ -253,14 +253,14 @@ public static CacheStats empty() { } /** - * Returns the average time spent loading new values. This is defined as + * Returns the average number of nanoseconds spent loading new values. This is defined as * {@code totalLoadTime / (loadSuccessCount + loadFailureCount)}. *

    * Note: the values of the metrics are undefined in case of overflow (though it is * guaranteed not to throw an exception). If you require specific handling, we recommend * implementing your own stats collector. * - * @return the average time spent loading new values + * @return the average number of nanoseconds spent loading new values */ public @NonNegative double averageLoadPenalty() { long totalLoadCount = saturatedAdd(loadSuccessCount, loadFailureCount); diff --git a/config/spotbugs/exclude.xml b/config/spotbugs/exclude.xml index 9964b8e3a3..981c5ac61e 100644 --- a/config/spotbugs/exclude.xml +++ b/config/spotbugs/exclude.xml @@ -3,160 +3,86 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://findbugs.sourceforge.net/filter/3.0.0 https://raw.githubusercontent.com/findbugsproject/findbugs/3.0.1/findbugs/etc/findbugsfilter.xsd"> - - + + + - + - + - - - - - - + - - - - - - + - - - - - - - - + - - - - - - - - + - - - - - - - - - - - + - + - + - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - + diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index ec4100964c..bc9d89216f 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -53,7 +53,7 @@ ext { jmh: '1.29', joor: '0.9.14', jsr330: '1', - nullaway: '0.8.0', + nullaway: '0.9.1', ohc: '0.6.1', osgiComponentAnnotations: '1.4.0', picocli: '4.6.1', @@ -63,11 +63,11 @@ ext { univocityParsers: '2.9.1', ycsb: '0.17.0', xz: '1.9', - zstd: '1.4.9-4', + zstd: '1.4.9-5', ] testVersions = [ awaitility: '4.0.3', - easymock: '4.2', + easymock: '4.3', guice: '5.0.1', hamcrest: '2.2', jcacheTck: '1.1.1', @@ -97,7 +97,7 @@ ext { semanticVersioning: '1.1.0', shadow: '6.1.0', sonarqube: '3.1.1', - spotbugs: '4.2.2', + spotbugs: '4.2.3', spotbugsPlugin: '4.7.0', stats: '0.2.2', versions: '0.38.0', diff --git a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinyCache.java b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinyCache.java index 316e4a5bdf..19bcd2a98b 100644 --- a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinyCache.java +++ b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinyCache.java @@ -18,50 +18,51 @@ import java.util.Random; /** - * This is the TinyCache model that takes advantage of random eviction policy with - * a ghost cache as admission policy. It offers a very dense memory layout combined with - * (relative) speed at the expense of limited associativity. s + * This is the TinyCache model that takes advantage of random eviction policy with a ghost cache as + * admission policy. It offers a very dense memory layout combined with (relative) speed at the + * expense of limited associativity. * * @author gilga1983@gmail.com (Gil Einziger) */ -@SuppressWarnings("PMD.AvoidDollarSigns") public final class TinyCache { private final HashFunctionParser hashFunc; - public final long[] chainIndex; - public final long[] lastIndex; + private final TinySetIndexing indexing; + private final long[] chainIndex; + private final long[] lastIndex; private final int itemsPerSet; private final long[] cache; private final Random rnd; public TinyCache(int nrSets, int itemsPerSet, int randomSeed) { - lastIndex = new long[nrSets]; - chainIndex = new long[nrSets]; + this.hashFunc = new HashFunctionParser(nrSets); + this.cache = new long[nrSets * itemsPerSet]; + this.indexing = new TinySetIndexing(); + this.chainIndex = new long[nrSets]; + this.lastIndex = new long[nrSets]; + this.rnd = new Random(randomSeed); this.itemsPerSet = itemsPerSet; - hashFunc = new HashFunctionParser(nrSets); - cache = new long[nrSets * itemsPerSet]; - rnd = new Random(randomSeed); } public boolean contains(long item) { hashFunc.createHash(item); - if (!TinySetIndexing.chainExist(chainIndex[hashFunc.fpaux.set], hashFunc.fpaux.chainId)) { + if (!indexing.chainExist(chainIndex[hashFunc.fpaux.set], hashFunc.fpaux.chainId)) { return false; } - TinySetIndexing.getChain(hashFunc.fpaux, chainIndex, lastIndex); - int offset = this.itemsPerSet * hashFunc.fpaux.set; - TinySetIndexing.chainStart += offset; - TinySetIndexing.chainEnd += offset; + indexing.getChain(hashFunc.fpaux, chainIndex, lastIndex); + int offset = itemsPerSet * hashFunc.fpaux.set; + indexing.chainStart += offset; + indexing.chainEnd += offset; - // Gil : I think some of these tests are, I till carefully examine this function when I have - // time. As far as I understand it is working right now. - while (TinySetIndexing.chainStart <= TinySetIndexing.chainEnd) { + // Gil: I will carefully examine this function when I have time. + // As far as I understand it is working right now. + while (indexing.chainStart <= indexing.chainEnd) { try { - if (cache[TinySetIndexing.chainStart % cache.length] == hashFunc.fpaux.value) { + if (cache[indexing.chainStart % cache.length] == hashFunc.fpaux.value) { return true; } - TinySetIndexing.chainStart++; + indexing.chainStart++; } catch (Exception e) { - System.out.println(" length: " + cache.length + " Access: " + TinySetIndexing.chainStart); + System.out.println("length: " + cache.length + " Access: " + indexing.chainStart); } } return false; @@ -74,10 +75,10 @@ public boolean contains(long item) { private int replace(HashedItem fpaux, byte victim, int bucketStart, int removedOffset) { byte chainId = fpaux.chainId; fpaux.chainId = victim; - this.cache[bucketStart + removedOffset] = 0; - TinySetIndexing.removeItem(fpaux, chainIndex, lastIndex); + cache[bucketStart + removedOffset] = 0; + indexing.removeItem(fpaux, chainIndex, lastIndex); fpaux.chainId = chainId; - int idxToAdd = TinySetIndexing.addItem(fpaux, chainIndex, lastIndex); + int idxToAdd = indexing.addItem(fpaux, chainIndex, lastIndex); int delta = (removedOffset < idxToAdd) ? -1 : 1; replaceItems(idxToAdd, fpaux.value, bucketStart, delta); return removedOffset; @@ -85,23 +86,23 @@ private int replace(HashedItem fpaux, byte victim, int bucketStart, int removedO public boolean addItem(long item) { hashFunc.createHash(item); - int bucketStart = this.itemsPerSet * hashFunc.fpaux.set; - if (cache[bucketStart + this.itemsPerSet - 1] != 0) { + int bucketStart = itemsPerSet * hashFunc.fpaux.set; + if (cache[bucketStart + itemsPerSet - 1] != 0) { return selectVictim(bucketStart); } - int idxToAdd = TinySetIndexing.addItem(hashFunc.fpaux, chainIndex, lastIndex); - this.replaceItems(idxToAdd, hashFunc.fpaux.value, bucketStart, 1); + int idxToAdd = indexing.addItem(hashFunc.fpaux, chainIndex, lastIndex); + replaceItems(idxToAdd, hashFunc.fpaux.value, bucketStart, 1); return false; } private boolean selectVictim(int bucketStart) { - byte victimOffset = (byte) rnd.nextInt(this.itemsPerSet); - int victimChain = - TinySetIndexing.getChainAtOffset(hashFunc.fpaux, chainIndex, lastIndex, victimOffset); - // this if is still for debugging and common sense. Should be eliminated for performance once + byte victimOffset = (byte) rnd.nextInt(itemsPerSet); + int victimChain = indexing.getChainAtOffset( + hashFunc.fpaux, chainIndex, lastIndex, victimOffset); + // this is still for debugging and common sense. Should be eliminated for performance once // I am sure of the correctness. - if (TinySetIndexing.chainExist(chainIndex[hashFunc.fpaux.set], victimChain)) { + if (indexing.chainExist(chainIndex[hashFunc.fpaux.set], victimChain)) { replace(hashFunc.fpaux, (byte) victimChain, bucketStart, victimOffset); return true; } else { @@ -109,14 +110,13 @@ private boolean selectVictim(int bucketStart) { } } - @SuppressWarnings("PMD.LocalVariableNamingConventions") - private void replaceItems(final int idx, long value, int start, final int delta) { + private void replaceItems(int idx, long value, int start, int delta) { start += idx; - long $; + long entry; do { - $ = this.cache[start]; - this.cache[start] = value; - value = $; + entry = cache[start]; + cache[start] = value; + value = entry; start += delta; } while (value != 0); } diff --git a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinyCacheSketch.java b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinyCacheSketch.java index e36c4c4765..aa68b19fce 100644 --- a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinyCacheSketch.java +++ b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinyCacheSketch.java @@ -24,51 +24,50 @@ * * @author gilga1983@gmail.com (Gil Einziger) */ -@SuppressWarnings({"PMD.AvoidDollarSigns", "PMD.LocalVariableNamingConventions"}) public final class TinyCacheSketch { - public final long[] chainIndex; - public final long[] lastIndex; - private final HashFunctionParser hashFunc; + private final TinySetIndexing indexing; + private final long[] chainIndex; + private final long[] lastIndex; private final int itemsPerSet; private final byte[] cache; private final Random rnd; public TinyCacheSketch(int nrSets, int itemsPerSet, int randomSeed) { - chainIndex = new long[nrSets]; - lastIndex = new long[nrSets]; + this.hashFunc = new HashFunctionParser(nrSets); + this.cache = new byte[nrSets * itemsPerSet]; + this.indexing = new TinySetIndexing(); + this.chainIndex = new long[nrSets]; + this.lastIndex = new long[nrSets]; + this.rnd = new Random(randomSeed); this.itemsPerSet = itemsPerSet; - hashFunc = new HashFunctionParser(nrSets); - cache = new byte[nrSets * itemsPerSet]; - rnd = new Random(randomSeed); } public int countItem(long item) { hashFunc.createHash(item); - int $ = 0; - if (!TinySetIndexing.chainExist(chainIndex[hashFunc.fpaux.set], hashFunc.fpaux.chainId)) { + if (!indexing.chainExist(chainIndex[hashFunc.fpaux.set], hashFunc.fpaux.chainId)) { return 0; } - TinySetIndexing.getChain(hashFunc.fpaux, chainIndex, lastIndex); - int offset = this.itemsPerSet * hashFunc.fpaux.set; - TinySetIndexing.chainStart += offset; - TinySetIndexing.chainEnd += offset; + indexing.getChain(hashFunc.fpaux, chainIndex, lastIndex); + int offset = itemsPerSet * hashFunc.fpaux.set; + indexing.chainStart += offset; + indexing.chainEnd += offset; // Gil : I think some of these tests are, I till carefully examine this function when I have // time. As far as I understand it is working right now. - while (TinySetIndexing.chainStart <= TinySetIndexing.chainEnd) { + int count = 0; + while (indexing.chainStart <= indexing.chainEnd) { try { - $ += (cache[TinySetIndexing.chainStart % cache.length] == hashFunc.fpaux.fingerprint) - ? 1 - : 0; - TinySetIndexing.chainStart++; + if (cache[indexing.chainStart % cache.length] == hashFunc.fpaux.fingerprint) { + count++; + } + indexing.chainStart++; } catch (Exception e) { - System.out.println(" length: " + cache.length + " Access: " + TinySetIndexing.chainStart); - // e.printStackTrace(); + System.out.println("length: " + cache.length + " Access: " + indexing.chainStart); } } - return $; + return count; } /** @@ -79,11 +78,11 @@ private int replace(HashedItem fpaux, byte victim, int bucketStart, int removedO byte chainId = fpaux.chainId; fpaux.chainId = victim; - this.cache[bucketStart + removedOffset] = 0; + cache[bucketStart + removedOffset] = 0; - TinySetIndexing.removeItem(fpaux, chainIndex, lastIndex); + indexing.removeItem(fpaux, chainIndex, lastIndex); fpaux.chainId = chainId; - int idxToAdd = TinySetIndexing.addItem(fpaux, chainIndex, lastIndex); + int idxToAdd = indexing.addItem(fpaux, chainIndex, lastIndex); int delta = (removedOffset < idxToAdd) ? -1 : 1; replaceItems(idxToAdd, fpaux.fingerprint, bucketStart, delta); @@ -93,34 +92,34 @@ private int replace(HashedItem fpaux, byte victim, int bucketStart, int removedO public void addItem(long item) { hashFunc.createHash(item); - int bucketStart = this.itemsPerSet * hashFunc.fpaux.set; - if (cache[bucketStart + this.itemsPerSet - 1] != 0) { + int bucketStart = itemsPerSet * hashFunc.fpaux.set; + if (cache[bucketStart + itemsPerSet - 1] != 0) { selectVictim(bucketStart); return; } - int idxToAdd = TinySetIndexing.addItem(hashFunc.fpaux, chainIndex, lastIndex); - this.replaceItems(idxToAdd, hashFunc.fpaux.fingerprint, bucketStart, 1); + int idxToAdd = indexing.addItem(hashFunc.fpaux, chainIndex, lastIndex); + replaceItems(idxToAdd, hashFunc.fpaux.fingerprint, bucketStart, 1); } private void selectVictim(int bucketStart) { - byte victimOffset = (byte) rnd.nextInt(this.itemsPerSet); + byte victimOffset = (byte) rnd.nextInt(itemsPerSet); int victimChain = - TinySetIndexing.getChainAtOffset(hashFunc.fpaux, chainIndex, lastIndex, victimOffset); - if (TinySetIndexing.chainExist(chainIndex[hashFunc.fpaux.set], victimChain)) { + indexing.getChainAtOffset(hashFunc.fpaux, chainIndex, lastIndex, victimOffset); + if (indexing.chainExist(chainIndex[hashFunc.fpaux.set], victimChain)) { replace(hashFunc.fpaux, (byte) victimChain, bucketStart, victimOffset); } else { throw new RuntimeException("Failed to replace"); } } - private void replaceItems(final int idx, byte value, int start, final int delta) { + private void replaceItems(int idx, byte value, int start, int delta) { start += idx; - byte $; + byte entry; do { - $ = this.cache[start]; - this.cache[start] = value; - value = $; + entry = cache[start]; + cache[start] = value; + value = entry; start += delta; } while (value != 0); } diff --git a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinyCacheWithGhostCache.java b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinyCacheWithGhostCache.java index b702305119..8dec262338 100644 --- a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinyCacheWithGhostCache.java +++ b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinyCacheWithGhostCache.java @@ -18,55 +18,55 @@ import java.util.Random; /** - * This is the TinyCache model that takes advantage of random eviction policy with - * a ghost cache as admission policy. It offers a very dense memory layout combined with - * (relative) speed at the expense of limited associativity. s + * This is the TinyCache model that takes advantage of random eviction policy with a ghost cache as + * admission policy. It offers a very dense memory layout combined with (relative) speed at the + * expense of limited associativity. s * * @author gilga1983@gmail.com (Gil Einziger) */ -@SuppressWarnings("PMD.AvoidDollarSigns") public final class TinyCacheWithGhostCache { private static final int sampleSize = 10; - public final long[] chainIndex; - public final long[] lastIndex; - private final HashFunctionParser hashFunc; private final TinyCacheSketch ghostCache; + private final TinySetIndexing indexing; + private final long[] chainIndex; + private final long[] lastIndex; private final int itemsPerSet; private final long[] cache; private final Random rnd; public TinyCacheWithGhostCache(int nrSets, int itemsPerSet, int randomSeed) { - chainIndex = new long[nrSets]; - lastIndex = new long[nrSets]; + this.ghostCache = new TinyCacheSketch(nrSets * sampleSize, itemsPerSet, randomSeed + 1); + this.hashFunc = new HashFunctionParser(nrSets); + this.cache = new long[nrSets * itemsPerSet]; + this.indexing = new TinySetIndexing(); + this.chainIndex = new long[nrSets]; + this.lastIndex = new long[nrSets]; + this.rnd = new Random(randomSeed); this.itemsPerSet = itemsPerSet; - cache = new long[nrSets * itemsPerSet]; - hashFunc = new HashFunctionParser(nrSets); - ghostCache = new TinyCacheSketch(nrSets * sampleSize, itemsPerSet, randomSeed + 1); - rnd = new Random(randomSeed); } public boolean contains(long item) { hashFunc.createHash(item); - if (!TinySetIndexing.chainExist(chainIndex[hashFunc.fpaux.set], hashFunc.fpaux.chainId)) { + if (!indexing.chainExist(chainIndex[hashFunc.fpaux.set], hashFunc.fpaux.chainId)) { return false; } - TinySetIndexing.getChain(hashFunc.fpaux, chainIndex, lastIndex); - int offset = this.itemsPerSet * hashFunc.fpaux.set; - TinySetIndexing.chainStart += offset; - TinySetIndexing.chainEnd += offset; + indexing.getChain(hashFunc.fpaux, chainIndex, lastIndex); + int offset = itemsPerSet * hashFunc.fpaux.set; + indexing.chainStart += offset; + indexing.chainEnd += offset; // Gil : I think some of these tests are, I till carefully examine this function when I have // time. As far as I understand it is working right now. - while (TinySetIndexing.chainStart <= TinySetIndexing.chainEnd) { + while (indexing.chainStart <= indexing.chainEnd) { try { - if (cache[TinySetIndexing.chainStart % cache.length] == hashFunc.fpaux.value) { + if (cache[indexing.chainStart % cache.length] == hashFunc.fpaux.value) { return true; } - TinySetIndexing.chainStart++; + indexing.chainStart++; } catch (Exception e) { - System.out.println(" length: " + cache.length + " Access: " + TinySetIndexing.chainStart); + System.out.println("length: " + cache.length + " Access: " + indexing.chainStart); } } return false; @@ -79,42 +79,42 @@ public boolean contains(long item) { private int replace(HashedItem fpaux, byte victim, int bucketStart, int removedOffset) { byte chainId = fpaux.chainId; fpaux.chainId = victim; - this.cache[bucketStart + removedOffset] = 0; - TinySetIndexing.removeItem(fpaux, chainIndex, lastIndex); + cache[bucketStart + removedOffset] = 0; + indexing.removeItem(fpaux, chainIndex, lastIndex); fpaux.chainId = chainId; - int idxToAdd = TinySetIndexing.addItem(fpaux, chainIndex, lastIndex); + int idxToAdd = indexing.addItem(fpaux, chainIndex, lastIndex); int delta = (removedOffset < idxToAdd) ? -1 : 1; replaceItems(idxToAdd, fpaux.value, bucketStart, delta); return removedOffset; } public void recordItem(long item) { - if (this.ghostCache.countItem(hashFunc.fpaux.value) < sampleSize) { - this.ghostCache.addItem(hashFunc.fpaux.value); + if (ghostCache.countItem(hashFunc.fpaux.value) < sampleSize) { + ghostCache.addItem(hashFunc.fpaux.value); } } public boolean addItem(long item) { hashFunc.createHash(item); - int bucketStart = this.itemsPerSet * hashFunc.fpaux.set; - if (cache[bucketStart + this.itemsPerSet - 1] != 0) { + int bucketStart = itemsPerSet * hashFunc.fpaux.set; + if (cache[bucketStart + itemsPerSet - 1] != 0) { return selectVictim(bucketStart); } - int idxToAdd = TinySetIndexing.addItem(hashFunc.fpaux, chainIndex, lastIndex); - this.replaceItems(idxToAdd, hashFunc.fpaux.value, bucketStart, 1); + int idxToAdd = indexing.addItem(hashFunc.fpaux, chainIndex, lastIndex); + replaceItems(idxToAdd, hashFunc.fpaux.value, bucketStart, 1); return false; } private boolean selectVictim(int bucketStart) { - byte victimOffset = (byte) rnd.nextInt(this.itemsPerSet); - int victimChain = TinySetIndexing.getChainAtOffset( + byte victimOffset = (byte) rnd.nextInt(itemsPerSet); + int victimChain = indexing.getChainAtOffset( hashFunc.fpaux, chainIndex, lastIndex, victimOffset); long victim = cache[bucketStart + victimOffset]; // this if is still for debugging and common sense. Should be eliminated for performance once // I am sure of the correctness. - if (TinySetIndexing.chainExist(chainIndex[hashFunc.fpaux.set], victimChain)) { - int victimScore = this.ghostCache.countItem(victim); - int currItemScore = this.ghostCache.countItem(hashFunc.fpaux.value); + if (indexing.chainExist(chainIndex[hashFunc.fpaux.set], victimChain)) { + int victimScore = ghostCache.countItem(victim); + int currItemScore = ghostCache.countItem(hashFunc.fpaux.value); if (currItemScore > victimScore) { replace(hashFunc.fpaux, (byte) victimChain, bucketStart, victimOffset); return true; @@ -127,13 +127,13 @@ private boolean selectVictim(int bucketStart) { } @SuppressWarnings("PMD.LocalVariableNamingConventions") - private void replaceItems(final int idx, long value, int start, final int delta) { + private void replaceItems(int idx, long value, int start, int delta) { start += idx; - long $; + long entry; do { - $ = this.cache[start]; - this.cache[start] = value; - value = $; + entry = cache[start]; + cache[start] = value; + value = entry; start += delta; } while (value != 0); } diff --git a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinySetIndexing.java b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinySetIndexing.java index bdeb052af4..29e98338d2 100644 --- a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinySetIndexing.java +++ b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/admission/tinycache/TinySetIndexing.java @@ -30,14 +30,12 @@ * * @author gilga1983@gmail.com (Gil Einziger) */ -public final class TinySetIndexing { +final class TinySetIndexing { // for performance - for functions that need to know both the start and the end of the chain. - static int chainStart; - static int chainEnd; + public int chainStart; + public int chainEnd; - private TinySetIndexing() {} - - public static int getChainStart(HashedItem fpaux, long[] chainIndex, long[] isLastIndex) { + public int getChainStart(HashedItem fpaux, long[] chainIndex, long[] isLastIndex) { int requiredChainNumber = rank(chainIndex[fpaux.set], fpaux.chainId); int currentChainNumber = rank(isLastIndex[fpaux.set], requiredChainNumber); int currentOffset = requiredChainNumber; @@ -50,11 +48,11 @@ public static int getChainStart(HashedItem fpaux, long[] chainIndex, long[] isLa return currentOffset; } - public static int rank(long index, int bitNum) { + public int rank(long index, int bitNum) { return Long.bitCount(index & ~(-1L << bitNum)); } - public static int getChain(HashedItem fpaux, long[] chainIndex, long[] isLastIndex) { + public int getChain(HashedItem fpaux, long[] chainIndex, long[] isLastIndex) { int requiredChainNumber = rank(chainIndex[fpaux.set], fpaux.chainId); int currentChainNumber = rank(isLastIndex[fpaux.set], requiredChainNumber); int currentOffset = requiredChainNumber; @@ -65,23 +63,23 @@ public static int getChain(HashedItem fpaux, long[] chainIndex, long[] isLastInd currentOffset++; tempisLastIndex >>>= 1; } - TinySetIndexing.chainStart = currentOffset; + chainStart = currentOffset; while ((tempisLastIndex & 1L) == 0) { currentOffset++; tempisLastIndex >>>= 1; } - TinySetIndexing.chainEnd = currentOffset; + chainEnd = currentOffset; return currentOffset; } @SuppressWarnings("PMD.AvoidReassigningLoopVariables") - public static int getChainAtOffset(HashedItem fpaux, + public int getChainAtOffset(HashedItem fpaux, long[] chainIndex, long[] isLastIndex, int offset) { int nonEmptyChainsToSee = rank(isLastIndex[fpaux.set], offset); int nonEmptyChainSeen = rank(chainIndex[fpaux.set], nonEmptyChainsToSee); for (int i = nonEmptyChainsToSee; i <= 64;) { - if (TinySetIndexing.chainExist(chainIndex[fpaux.set], i) + if (chainExist(chainIndex[fpaux.set], i) && (nonEmptyChainSeen == nonEmptyChainsToSee)) { return i; } @@ -91,11 +89,11 @@ public static int getChainAtOffset(HashedItem fpaux, throw new RuntimeException("Cannot choose victim!"); } - public static boolean chainExist(long chainIndex, int chainId) { + public boolean chainExist(long chainIndex, int chainId) { return (chainIndex | (1L << chainId)) == chainIndex; } - public static int addItem(HashedItem fpaux, long[] chainIndex, long[] lastIndex) { + public int addItem(HashedItem fpaux, long[] chainIndex, long[] lastIndex) { int offset = getChainStart(fpaux, chainIndex, lastIndex); long mask = 1L << fpaux.chainId; lastIndex[fpaux.set] = extendZero(lastIndex[fpaux.set], offset); @@ -112,7 +110,7 @@ public static int addItem(HashedItem fpaux, long[] chainIndex, long[] lastIndex) } @SuppressWarnings("UnnecessaryParentheses") - private static long extendZero(final long isLastIndex, final int offset) { + private long extendZero(long isLastIndex, int offset) { long constantPartMask = (1L << offset) - 1; return (isLastIndex & constantPartMask) | ((isLastIndex << 1L) @@ -121,12 +119,12 @@ private static long extendZero(final long isLastIndex, final int offset) { } @SuppressWarnings("UnnecessaryParentheses") - private static long shrinkOffset(long isLastIndex, int offset) { + private long shrinkOffset(long isLastIndex, int offset) { long conMask = ((1L << offset) - 1); return (isLastIndex & conMask) | (((~conMask) & isLastIndex) >>> 1); } - public static void removeItem(HashedItem fpaux, long[] chainIndex, long[] isLastIndex) { + public void removeItem(HashedItem fpaux, long[] chainIndex, long[] isLastIndex) { int chainStart = getChainStart(fpaux, chainIndex, isLastIndex); // avoid an if command: either update chainIndex to the new state or keep it the way it is. chainIndex[fpaux.set] = (isLastIndex[fpaux.set] & (1L << chainStart)) == 0L