提交 1c75fd78 authored 作者: Thomas Mueller Graf's avatar Thomas Mueller Graf

LIRS cache: keep more non-resident entries

上级 11ef3490
......@@ -55,7 +55,7 @@ public class CacheLongKeyLIRS<V> {
private final int segmentShift;
private final int segmentMask;
private final int stackMoveDistance;
private final double nonResidentQueueSize;
private final int nonResidentQueueSize;
/**
* Create a new cache with the given memory size.
......@@ -535,7 +535,7 @@ public class CacheLongKeyLIRS<V> {
* The number of entries in the non-resident queue, as a factor of the
* number of entries in the map.
*/
private final double nonResidentQueueSize;
private final int nonResidentQueueSize;
/**
* The stack of recently referenced elements. This includes all hot
......@@ -581,7 +581,7 @@ public class CacheLongKeyLIRS<V> {
* @param nonResidentQueueSize the non-resident queue size factor
*/
Segment(long maxMemory, int stackMoveDistance, int len,
double nonResidentQueueSize) {
int nonResidentQueueSize) {
setMaxMemory(maxMemory);
this.stackMoveDistance = stackMoveDistance;
this.nonResidentQueueSize = nonResidentQueueSize;
......@@ -904,11 +904,13 @@ public class CacheLongKeyLIRS<V> {
e.memory = 0;
addToQueue(queue2, e);
// the size of the non-resident-cold entries needs to be limited
int maxQueue2Size = (int) (nonResidentQueueSize * mapSize);
while (queue2Size > maxQueue2Size) {
e = queue2.queuePrev;
int hash = getHash(e.key);
remove(e.key, hash);
int maxQueue2Size = nonResidentQueueSize * (mapSize - queue2Size);
if (maxQueue2Size >= 0) {
while (queue2Size > maxQueue2Size) {
e = queue2.queuePrev;
int hash = getHash(e.key);
remove(e.key, hash);
}
}
}
}
......@@ -1165,15 +1167,16 @@ public class CacheLongKeyLIRS<V> {
public int segmentCount = 16;
/**
* How many other item are to be moved to the top of the stack before the current item is moved.
* How many other item are to be moved to the top of the stack before
* the current item is moved.
*/
public int stackMoveDistance = 32;
/**
* The number of entries in the non-resident queue, as a factor of the
* number of entries in the map.
* number of all other entries in the map.
*/
public double nonResidentQueueSize = 0.5;
public int nonResidentQueueSize = 3;
}
......
......@@ -114,7 +114,8 @@ public class TestCacheLongKeyLIRS extends TestBase {
assertEquals(63, test.size() - test.sizeHot());
// at most as many non-resident elements
// as there are entries in the stack
assertEquals(999, test.sizeNonResident());
assertEquals(1000, test.size());
assertEquals(1000, test.sizeNonResident());
}
private void verifyMapSize(int elements, int expectedMapSize) {
......@@ -323,8 +324,8 @@ public class TestCacheLongKeyLIRS extends TestBase {
test.put(i, 10 * i);
}
assertEquals(100, test.size());
assertEquals(99, test.sizeNonResident());
assertEquals(93, test.sizeHot());
assertEquals(200, test.sizeNonResident());
assertEquals(90, test.sizeHot());
}
private void testLimitNonResident() {
......@@ -332,8 +333,8 @@ public class TestCacheLongKeyLIRS extends TestBase {
for (int i = 0; i < 20; i++) {
test.put(i, 10 * i);
}
verify(test, "mem: 4 stack: 19 18 17 16 3 2 1 " +
"cold: 19 non-resident: 18 17 16");
verify(test, "mem: 4 stack: 19 18 17 16 15 14 13 12 11 10 3 2 1 " +
"cold: 19 non-resident: 18 17 16 15 14 13 12 11 10");
}
private void testLimitMemory() {
......@@ -344,21 +345,21 @@ public class TestCacheLongKeyLIRS extends TestBase {
verify(test, "mem: 4 stack: 4 3 2 1 cold: 4 non-resident: 0");
assertTrue("" + test.getUsedMemory(), test.getUsedMemory() <= 4);
test.put(6, 60, 3);
verify(test, "mem: 4 stack: 6 3 cold: 6 non-resident: 2 1");
verify(test, "mem: 4 stack: 6 4 3 cold: 6 non-resident: 2 1 4");
assertTrue("" + test.getUsedMemory(), test.getUsedMemory() <= 4);
test.put(7, 70, 3);
verify(test, "mem: 4 stack: 7 6 3 cold: 7 non-resident: 6 2");
verify(test, "mem: 4 stack: 7 6 3 cold: 7 non-resident: 6 2 1");
assertTrue("" + test.getUsedMemory(), test.getUsedMemory() <= 4);
test.put(8, 80, 4);
verify(test, "mem: 4 stack: 8 cold: non-resident: 3");
verify(test, "mem: 4 stack: 8 cold: non-resident:");
assertTrue("" + test.getUsedMemory(), test.getUsedMemory() <= 4);
}
private void testScanResistance() {
boolean log = false;
int size = 20;
// cache size 11 (10 hot, 1 cold)
CacheLongKeyLIRS<Integer> test = createCache(size / 2 + 1);
// cache size 11 (10 hot, 2 cold)
CacheLongKeyLIRS<Integer> test = createCache(size / 2 + 2);
// init the cache with some dummy entries
for (int i = 0; i < size; i++) {
test.put(-i, -i * 10);
......@@ -394,10 +395,10 @@ public class TestCacheLongKeyLIRS extends TestBase {
}
verify(test, null);
}
// ensure 0..9 are hot, 10..18 are not resident, 19 is cold
// ensure 0..9 are hot, 10..17 are not resident, 18..19 are cold
for (int i = 0; i < size; i++) {
Integer x = test.get(i);
if (i < size / 2 || i == size - 1) {
if (i < size / 2 || i == size - 1 || i == size - 2) {
assertTrue("i: " + i, x != null);
assertEquals(i * 10, x.intValue());
} else {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论