-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Clarified the JavaDoc of CacheStats' loading metrics - Used bug pattern names instead of non-descript code - Fixed warnings in the TinySet contributions - Removed outdated suppressions
- Loading branch information
Showing
7 changed files
with
160 additions
and
237 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 [email protected] (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,49 +75,48 @@ 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 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 { | ||
throw new RuntimeException("Failed to replace"); | ||
} | ||
} | ||
|
||
@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); | ||
} | ||
|
Oops, something went wrong.