LIFOList extends AbstractEvictionList { @Override public EvictableEntry getEvictableEntry() { long evaluations = 0; EvictionNode evictionNode; for (;;) { evictionNode = unlinkTailEntry(); if (evictionNode == null) { break; } evaluations++; synchronized (evictionNode) { if (!evictionNode.isInUseByTransaction() && !evictionNode.isEvicted()) { break; } } } getStatistics().incEvaluations(evaluations); return (EvictableEntry) evictionNode; } LIFOList(EvictionController controller); @Override EvictableEntry getEvictableEntry(); @Override void incrementRecentlyUsed();  }
@Test public void evictingFromEmptyListTest() throws Exception { LIFOList list = new LIFOList(controller); assertThat(list.getEvictableEntry()).isNull(); assertThat(list.size()).isZero(); }
@Test public void evictingFromNonEmptyListTest() throws Exception { LIFOList list = new LIFOList(controller); EvictionNode node = mock(EvictableEntry.class); list.appendEntry(node); assertThat(list.size()).isEqualTo(1); when(node.next()).thenReturn(list.tail); when(node.previous()).thenReturn(list.head); assertThat(list.getEvictableEntry()).isSameAs(node); verify(stats).incEvaluations(anyLong()); assertThat(list.size()).isZero(); }
@Test public void doesNotEvictNodeInTransaction() throws Exception { LIFOList list = new LIFOList(controller); EvictionNode nodeInTransaction = mock(EvictableEntry.class); when(nodeInTransaction.isInUseByTransaction()).thenReturn(true); EvictionNode nodeNotInTransaction = mock(EvictableEntry.class); list.appendEntry(nodeNotInTransaction); list.appendEntry(nodeInTransaction); assertThat(list.size()).isEqualTo(2); when(nodeInTransaction.next()).thenReturn(list.tail); when(nodeInTransaction.previous()).thenReturn(nodeNotInTransaction); when(nodeNotInTransaction.next()).thenReturn(list.tail); when(nodeNotInTransaction.previous()).thenReturn(list.head); assertThat(list.getEvictableEntry()).isSameAs(nodeNotInTransaction); verify(stats).incEvaluations(2); assertThat(list.size()).isZero(); }
@Test public void doesNotEvictNodeThatIsEvicted() throws Exception { LIFOList list = new LIFOList(controller); EvictionNode evictedNode = mock(EvictableEntry.class); when(evictedNode.isEvicted()).thenReturn(true); EvictionNode node = mock(EvictableEntry.class); list.appendEntry(node); list.appendEntry(evictedNode); assertThat(list.size()).isEqualTo(2); when(evictedNode.next()).thenReturn(list.tail); when(evictedNode.previous()).thenReturn(node); when(node.next()).thenReturn(list.tail); when(node.previous()).thenReturn(list.head); assertThat(list.getEvictableEntry()).isSameAs(node); verify(stats).incEvaluations(2); assertThat(list.size()).isZero(); }