From 54503f09ec0279ff2c2830459c84176c49654db3 Mon Sep 17 00:00:00 2001 From: Ben Manes Date: Sun, 30 Aug 2015 23:44:13 -0700 Subject: [PATCH] Fix warmup of HIR blocks in LIRS policy When comparing against the output from the C reference version I discovered that the warmup for HIR was incorrectly followed. This change results in the same output for a small sample. There is still a mistake as verified by running a large sample, multi1, and seeing that S, Q, evictions, and statistics are askew. While this has a very small impact on the hit rate, we should still try to find the subtle bug remaining. For ease of comparing outputs, the debug format now matches the reference's. --- .../simulator/policy/irr/LirsPolicy.java | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/irr/LirsPolicy.java b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/irr/LirsPolicy.java index fe1fbede19..faa53c9708 100644 --- a/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/irr/LirsPolicy.java +++ b/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/policy/irr/LirsPolicy.java @@ -140,14 +140,16 @@ private void onResidentHir(Node node) { } private void onNonResidentHir(Node node) { - // When LIR block set is not full, all the referenced blocks are given an LIR status until its - // size reaches Llirs. After that, HIR status is given to any blocks that are referenced for the - // first time, and to the blocks that have not been referenced for a long time so that they are - // not in stack S any longer. + // When an LIR block set is not full, all the accessed blocks are given LIR status until its + // size reaches Llirs. After that, HIR status is given to any blocks that are accessed for the + // first time and to blocks that have not been accessed for a long time so that currently they + // are not in stack S. policyStats.recordMiss(); if (sizeHot < maximumHotSize) { - onWarmupMiss(node); + onLirWarmupMiss(node); + } else if (residentSize < maximumSize) { + onHirWarmupMiss(node); } else { onFullMiss(node); } @@ -155,12 +157,18 @@ private void onNonResidentHir(Node node) { } /** Records a miss when the hot set is not full. */ - private void onWarmupMiss(Node node) { + private void onLirWarmupMiss(Node node) { node.moveToTop(StackType.S); node.status = Status.LIR; sizeHot++; } + /** Records a miss when the cold set is not full. */ + private void onHirWarmupMiss(Node node) { + node.status = Status.HIR_RESIDENT; + node.moveToTop(StackType.Q); + } + /** Records a miss when the hot set is full. */ private void onFullMiss(Node node) { // Upon accessing an HIR non-resident block X. This is a miss. We remove the HIR resident block @@ -265,27 +273,30 @@ public void finished() { /** Prints out the internal state of the policy. */ private void printLirs() { - List stack = new ArrayList<>(sizeS); - List queue = new ArrayList<>(sizeQ); - + System.out.println("** LIRS stack TOP **"); for (Node n = headS.nextS; n != headS; n = n.nextS) { checkState(n.isInS); if (n.status == Status.HIR_NON_RESIDENT) { - stack.add("NR_" + n.key); + System.out.println(" " + n.key); } else if (n.status == Status.HIR_RESIDENT) { - stack.add("RH_" + n.key); + System.out.println(" " + n.key); } else { - stack.add("RL_" + n.key); + System.out.println(" " + n.key); } } + System.out.println("** LIRS stack BOTTOM **"); + + System.out.println("\n** LIRS queue END **"); for (Node n = headQ.nextQ; n != headQ; n = n.nextQ) { checkState(n.isInQ); - queue.add(n.key); + System.out.println(n.key); } + System.out.println("** LIRS queue front **"); - System.out.println("Stack: " + stack); - System.out.println("Queue: " + queue); - System.out.println("Evicted: " + evicted); + System.out.println("\nLIRS EVICTED PAGE sequence:"); + for (int i = 0; i < evicted.size(); i++) { + System.out.println("<" + i + "> " + evicted.get(i)); + } } enum Status {