Skip to content

Commit

Permalink
refactor: optimize cache code architeture
Browse files Browse the repository at this point in the history
  • Loading branch information
songzhipeng committed Jul 27, 2023
1 parent fd52889 commit 53e34a7
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 239 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.CacheException;
import org.apache.ibatis.cache.impl.DelegateCache;

/**
* <p>
Expand All @@ -34,31 +35,20 @@
*
* @author Eduardo Macarron
*/
public class BlockingCache implements Cache {
public class BlockingCache extends DelegateCache {

private long timeout;
private final Cache delegate;
private final ConcurrentHashMap<Object, CountDownLatch> locks;

public BlockingCache(Cache delegate) {
this.delegate = delegate;
super(delegate);
this.locks = new ConcurrentHashMap<>();
}

@Override
public String getId() {
return delegate.getId();
}

@Override
public int getSize() {
return delegate.getSize();
}

@Override
public void putObject(Object key, Object value) {
try {
delegate.putObject(key, value);
super.putObject(key, value);
} finally {
releaseLock(key);
}
Expand All @@ -67,7 +57,7 @@ public void putObject(Object key, Object value) {
@Override
public Object getObject(Object key) {
acquireLock(key);
Object value = delegate.getObject(key);
Object value = super.getObject(key);
if (value != null) {
releaseLock(key);
}
Expand All @@ -81,11 +71,6 @@ public Object removeObject(Object key) {
return null;
}

@Override
public void clear() {
delegate.clear();
}

private void acquireLock(Object key) {
CountDownLatch newLatch = new CountDownLatch(1);
while (true) {
Expand All @@ -98,7 +83,7 @@ private void acquireLock(Object key) {
boolean acquired = latch.await(timeout, TimeUnit.MILLISECONDS);
if (!acquired) {
throw new CacheException(
"Couldn't get a lock in " + timeout + " for the key " + key + " at the cache " + delegate.getId());
"Couldn't get a lock in " + timeout + " for the key " + key + " at the cache " + super.getId());
}
} else {
latch.await();
Expand Down
32 changes: 6 additions & 26 deletions src/main/java/org/apache/ibatis/cache/decorators/FifoCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,65 +19,45 @@
import java.util.LinkedList;

import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.impl.DelegateCache;

/**
* FIFO (first in, first out) cache decorator.
*
* @author Clinton Begin
*/
public class FifoCache implements Cache {
public class FifoCache extends DelegateCache {

private final Cache delegate;
private final Deque<Object> keyList;
private int size;

public FifoCache(Cache delegate) {
this.delegate = delegate;
super(delegate);
this.keyList = new LinkedList<>();
this.size = 1024;
}

@Override
public String getId() {
return delegate.getId();
}

@Override
public int getSize() {
return delegate.getSize();
}

public void setSize(int size) {
this.size = size;
}

@Override
public void putObject(Object key, Object value) {
cycleKeyList(key);
delegate.putObject(key, value);
}

@Override
public Object getObject(Object key) {
return delegate.getObject(key);
}

@Override
public Object removeObject(Object key) {
return delegate.removeObject(key);
super.putObject(key, value);
}

@Override
public void clear() {
delegate.clear();
super.clear();
keyList.clear();
}

private void cycleKeyList(Object key) {
keyList.addLast(key);
if (keyList.size() > size) {
Object oldestKey = keyList.removeFirst();
delegate.removeObject(oldestKey);
super.removeObject(oldestKey);
}
}

Expand Down
43 changes: 4 additions & 39 deletions src/main/java/org/apache/ibatis/cache/decorators/LoggingCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,43 +16,28 @@
package org.apache.ibatis.cache.decorators;

import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.impl.DelegateCache;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;

/**
* @author Clinton Begin
*/
public class LoggingCache implements Cache {
public class LoggingCache extends DelegateCache {

private final Log log;
private final Cache delegate;
protected int requests;
protected int hits;

public LoggingCache(Cache delegate) {
this.delegate = delegate;
super(delegate);
this.log = LogFactory.getLog(getId());
}

@Override
public String getId() {
return delegate.getId();
}

@Override
public int getSize() {
return delegate.getSize();
}

@Override
public void putObject(Object key, Object object) {
delegate.putObject(key, object);
}

@Override
public Object getObject(Object key) {
requests++;
final Object value = delegate.getObject(key);
final Object value = super.getObject(key);
if (value != null) {
hits++;
}
Expand All @@ -62,26 +47,6 @@ public Object getObject(Object key) {
return value;
}

@Override
public Object removeObject(Object key) {
return delegate.removeObject(key);
}

@Override
public void clear() {
delegate.clear();
}

@Override
public int hashCode() {
return delegate.hashCode();
}

@Override
public boolean equals(Object obj) {
return delegate.equals(obj);
}

private double getHitRatio() {
return (double) hits / (double) requests;
}
Expand Down
29 changes: 7 additions & 22 deletions src/main/java/org/apache/ibatis/cache/decorators/LruCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,23 @@
import java.util.Map;

import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.impl.DelegateCache;

/**
* Lru (least recently used) cache decorator.
*
* @author Clinton Begin
*/
public class LruCache implements Cache {
public class LruCache extends DelegateCache {

private final Cache delegate;
private Map<Object, Object> keyMap;
private Object eldestKey;

public LruCache(Cache delegate) {
this.delegate = delegate;
super(delegate);
setSize(1024);
}

@Override
public String getId() {
return delegate.getId();
}

@Override
public int getSize() {
return delegate.getSize();
}

public void setSize(final int size) {
keyMap = new LinkedHashMap<Object, Object>(size, .75F, true) {
private static final long serialVersionUID = 4267176411845948333L;
Expand All @@ -63,31 +53,26 @@ protected boolean removeEldestEntry(Map.Entry<Object, Object> eldest) {

@Override
public void putObject(Object key, Object value) {
delegate.putObject(key, value);
super.putObject(key, value);
cycleKeyList(key);
}

@Override
public Object getObject(Object key) {
keyMap.get(key); // touch
return delegate.getObject(key);
}

@Override
public Object removeObject(Object key) {
return delegate.removeObject(key);
return super.getObject(key);
}

@Override
public void clear() {
delegate.clear();
super.clear();
keyMap.clear();
}

private void cycleKeyList(Object key) {
keyMap.put(key, key);
if (eldestKey != null) {
delegate.removeObject(eldestKey);
super.removeObject(eldestKey);
eldestKey = null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@
import java.util.concurrent.TimeUnit;

import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.impl.DelegateCache;

/**
* @author Clinton Begin
*/
public class ScheduledCache implements Cache {
public class ScheduledCache extends DelegateCache {

private final Cache delegate;
protected long clearInterval;
protected long lastClear;

public ScheduledCache(Cache delegate) {
this.delegate = delegate;
super(delegate);
this.clearInterval = TimeUnit.HOURS.toMillis(1);
this.lastClear = System.currentTimeMillis();
}
Expand All @@ -38,48 +38,33 @@ public void setClearInterval(long clearInterval) {
this.clearInterval = clearInterval;
}

@Override
public String getId() {
return delegate.getId();
}

@Override
public int getSize() {
clearWhenStale();
return delegate.getSize();
return super.getSize();
}

@Override
public void putObject(Object key, Object object) {
clearWhenStale();
delegate.putObject(key, object);
super.putObject(key, object);
}

@Override
public Object getObject(Object key) {
return clearWhenStale() ? null : delegate.getObject(key);
return clearWhenStale() ? null : super.getObject(key);
}

@Override
public Object removeObject(Object key) {
clearWhenStale();
return delegate.removeObject(key);
return super.removeObject(key);
}

@Override
public void clear() {
lastClear = System.currentTimeMillis();
delegate.clear();
}

@Override
public int hashCode() {
return delegate.hashCode();
}

@Override
public boolean equals(Object obj) {
return delegate.equals(obj);
super.clear();
}

private boolean clearWhenStale() {
Expand Down
Loading

0 comments on commit 53e34a7

Please sign in to comment.