/* * Licensed to the Apache Software Foundation (ASF) under one or more contributor license * agreements. See the NOTICE file distributed with this work for additional information regarding * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package org.apache.geode.internal.cache.lru; import org.apache.geode.cache.Region; import org.apache.geode.internal.cache.InternalRegionArguments; import org.apache.geode.internal.cache.AbstractRegionEntry; /** * NewLIFOClockHand holds the behavior for LIFO logic , Overwriting getLRUEntry() to return most * recently added Entry * * @since GemFire 5.7 */ public class NewLIFOClockHand extends NewLRUClockHand { /* * constructor */ public NewLIFOClockHand(Object region, EnableLRU ccHelper, InternalRegionArguments internalRegionArgs) { super(region, ccHelper, internalRegionArgs); } public NewLIFOClockHand(Region region, EnableLRU ccHelper, NewLRUClockHand oldList) { super(region, ccHelper, oldList); } /* * Fetch the tail member which should be the last added value and remove it from the list */ protected LRUClockNode getTailEntry() { LRUClockNode aNode = null; synchronized (this.lock) { aNode = this.tail.prevLRUNode(); if (aNode == this.head) { return null; // end of lru list } // remove entry from list LRUClockNode prev = aNode.prevLRUNode(); prev.setNextLRUNode(this.tail); this.tail.setPrevLRUNode(prev); aNode.setNextLRUNode(null); aNode.setPrevLRUNode(null); super.size--; } return aNode; } /* * return the Entry that is considered most recently used and available to be evicted to overflow */ @Override public LRUClockNode getLRUEntry() { long numEvals = 0; LRUClockNode aNode = null; // search for entry to return from list for (;;) { aNode = getTailEntry(); // end of Lifo list stop searching if (aNode == null) { break; } numEvals++; synchronized (aNode) { // look for another entry if in transaction boolean inUseByTransaction = false; if (aNode instanceof AbstractRegionEntry) { if (((AbstractRegionEntry) aNode).isInUseByTransaction()) { inUseByTransaction = true; } } // if entry NOT used by transaction and NOT evicted return entry if (!inUseByTransaction && !aNode.testEvicted()) { break; } } } this.stats().incEvaluations(numEvals); return aNode; } }