Skip to content

refactor cache decorator #838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions src/main/java/org/apache/ibatis/cache/CacheDecorator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* Copyright 2009-2016 the original author or authors.
*
* Licensed 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.ibatis.cache;

import java.util.concurrent.locks.ReadWriteLock;

/**
* abstract cache decorator.
* @author wuwen
*/
public abstract class CacheDecorator implements Cache {

private Cache delegate;

public CacheDecorator(Cache cache) {
this.delegate = cache;
}

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

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

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

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

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

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

@Override
public ReadWriteLock getReadWriteLock() {
return delegate.getReadWriteLock();
}

public Cache getDelegate() {
return delegate;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2009-2015 the original author or authors.
* Copyright 2009-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,10 +18,10 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.CacheDecorator;
import org.apache.ibatis.cache.CacheException;

/**
Expand All @@ -34,31 +34,20 @@
* @author Eduardo Macarron
*
*/
public class BlockingCache implements Cache {
public class BlockingCache extends CacheDecorator {

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

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

@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 +56,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 @@ -80,16 +69,6 @@ public Object removeObject(Object key) {
releaseLock(key);
return null;
}

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

@Override
public ReadWriteLock getReadWriteLock() {
return null;
}

private ReentrantLock getLockForKey(Object key) {
ReentrantLock lock = new ReentrantLock();
Expand All @@ -103,7 +82,7 @@ private void acquireLock(Object key) {
try {
boolean acquired = lock.tryLock(timeout, TimeUnit.MILLISECONDS);
if (!acquired) {
throw new CacheException("Couldn't get a lock in " + timeout + " for the key " + key + " at the cache " + delegate.getId());
throw new CacheException("Couldn't get a lock in " + timeout + " for the key " + key + " at the cache " + getId());
}
} catch (InterruptedException e) {
throw new CacheException("Got interrupted while trying to acquire lock for key " + key, e);
Expand Down
40 changes: 7 additions & 33 deletions src/main/java/org/apache/ibatis/cache/decorators/FifoCache.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2009-2015 the original author or authors.
* Copyright 2009-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,73 +17,47 @@

import java.util.Deque;
import java.util.LinkedList;
import java.util.concurrent.locks.ReadWriteLock;

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

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

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

public FifoCache(Cache delegate) {
this.delegate = delegate;
super(delegate);
this.keyList = new LinkedList<Object>();
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();
}

@Override
public ReadWriteLock getReadWriteLock() {
return null;
}

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

Expand Down
56 changes: 16 additions & 40 deletions src/main/java/org/apache/ibatis/cache/decorators/LoggingCache.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2009-2015 the original author or authors.
* Copyright 2009-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,46 +15,30 @@
*/
package org.apache.ibatis.cache.decorators;

import java.util.concurrent.locks.ReadWriteLock;

import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.CacheDecorator;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;

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

private Log log;
private Cache delegate;
protected int requests = 0;
protected int hits = 0;
protected volatile int requests = 0;
protected volatile int hits = 0;

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 @@ -64,33 +48,25 @@ 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 ReadWriteLock getReadWriteLock() {
return null;
}

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

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

private double getHitRatio() {
return (double) hits / (double) requests;
}

public int getRequests() {
return requests;
}

public int getHits() {
return hits;
}
}
Loading