LruCache.java

  1. /*
  2.  *    Copyright 2009-2023 the original author or authors.
  3.  *
  4.  *    Licensed under the Apache License, Version 2.0 (the "License");
  5.  *    you may not use this file except in compliance with the License.
  6.  *    You may obtain a copy of the License at
  7.  *
  8.  *       https://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  *    Unless required by applicable law or agreed to in writing, software
  11.  *    distributed under the License is distributed on an "AS IS" BASIS,
  12.  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  *    See the License for the specific language governing permissions and
  14.  *    limitations under the License.
  15.  */
  16. package org.apache.ibatis.cache.decorators;

  17. import java.util.LinkedHashMap;
  18. import java.util.Map;

  19. import org.apache.ibatis.cache.Cache;

  20. /**
  21.  * Lru (least recently used) cache decorator.
  22.  *
  23.  * @author Clinton Begin
  24.  */
  25. public class LruCache implements Cache {

  26.   private final Cache delegate;
  27.   private Map<Object, Object> keyMap;
  28.   private Object eldestKey;

  29.   public LruCache(Cache delegate) {
  30.     this.delegate = delegate;
  31.     setSize(1024);
  32.   }

  33.   @Override
  34.   public String getId() {
  35.     return delegate.getId();
  36.   }

  37.   @Override
  38.   public int getSize() {
  39.     return delegate.getSize();
  40.   }

  41.   public void setSize(final int size) {
  42.     keyMap = new LinkedHashMap<Object, Object>(size, .75F, true) {
  43.       private static final long serialVersionUID = 4267176411845948333L;

  44.       @Override
  45.       protected boolean removeEldestEntry(Map.Entry<Object, Object> eldest) {
  46.         boolean tooBig = size() > size;
  47.         if (tooBig) {
  48.           eldestKey = eldest.getKey();
  49.         }
  50.         return tooBig;
  51.       }
  52.     };
  53.   }

  54.   @Override
  55.   public void putObject(Object key, Object value) {
  56.     delegate.putObject(key, value);
  57.     cycleKeyList(key);
  58.   }

  59.   @Override
  60.   public Object getObject(Object key) {
  61.     keyMap.get(key); // touch
  62.     return delegate.getObject(key);
  63.   }

  64.   @Override
  65.   public Object removeObject(Object key) {
  66.     keyMap.remove(key);
  67.     return delegate.removeObject(key);
  68.   }

  69.   @Override
  70.   public void clear() {
  71.     delegate.clear();
  72.     keyMap.clear();
  73.   }

  74.   private void cycleKeyList(Object key) {
  75.     keyMap.put(key, key);
  76.     if (eldestKey != null) {
  77.       delegate.removeObject(eldestKey);
  78.       eldestKey = null;
  79.     }
  80.   }

  81. }