net.sf.ehcache.store.LegacyStoreWrapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
/**
* Copyright Terracotta, Inc.
*
* 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 net.sf.ehcache.store;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.Element;
import net.sf.ehcache.Status;
import net.sf.ehcache.concurrent.LockType;
import net.sf.ehcache.concurrent.StripedReadWriteLockSync;
import net.sf.ehcache.concurrent.Sync;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.event.RegisteredEventListeners;
import net.sf.ehcache.writer.CacheWriterManager;
import org.terracotta.context.annotations.ContextChild;
/**
* A wrapper to convert a legacy pair of stores into a new style compound store.
*
* @author Chris Dennis
*/
public class LegacyStoreWrapper extends AbstractStore {
private static final int SYNC_STRIPES = 64;
@ContextChild private final Store memory;
@ContextChild private final Store disk;
private final RegisteredEventListeners eventListeners;
private final CacheConfiguration config;
private final StripedReadWriteLockSync sync = new StripedReadWriteLockSync(SYNC_STRIPES);
/**
* Create a correctly locked store wrapper around the supplied in-memory and on disk stores.
*
* @param memory in-memory store
* @param disk on disk store
* @param eventListeners event listener to fire on
* @param config cache configuration
*/
public LegacyStoreWrapper(Store memory, Store disk, RegisteredEventListeners eventListeners, CacheConfiguration config) {
this.memory = memory;
this.disk = disk;
this.eventListeners = eventListeners;
this.config = config;
}
/**
* {@inheritDoc}
*/
public boolean bufferFull() {
if (disk == null) {
return false;
} else {
return disk.bufferFull();
}
}
/**
* {@inheritDoc}
*/
public boolean containsKey(Object key) {
Sync s = sync.getSyncForKey(key);
s.lock(LockType.READ);
try {
if (key instanceof Serializable && (disk != null)) {
return disk.containsKey(key) || memory.containsKey(key);
} else {
return memory.containsKey(key);
}
} finally {
s.unlock(LockType.READ);
}
}
/**
* {@inheritDoc}
*/
public boolean containsKeyInMemory(Object key) {
Sync s = sync.getSyncForKey(key);
s.lock(LockType.READ);
try {
return memory.containsKey(key);
} finally {
s.unlock(LockType.READ);
}
}
/**
* {@inheritDoc}
*/
public boolean containsKeyOffHeap(Object key) {
return false;
}
/**
* {@inheritDoc}
*/
public boolean containsKeyOnDisk(Object key) {
Sync s = sync.getSyncForKey(key);
s.lock(LockType.READ);
try {
if (disk != null) {
return disk.containsKey(key);
} else {
return false;
}
} finally {
s.unlock(LockType.READ);
}
}
/**
* {@inheritDoc}
*/
public void dispose() {
memory.dispose();
if (disk != null) {
disk.dispose();
}
}
/**
* {@inheritDoc}
*/
public void expireElements() {
for (Object key : memory.getKeys()) {
Sync s = sync.getSyncForKey(key);
s.lock(LockType.WRITE);
try {
Element element = memory.getQuiet(key);
if (element != null) {
if (element.isExpired(config)) {
Element e = remove(key);
if (e != null) {
eventListeners.notifyElementExpiry(e, false);
}
}
}
} finally {
s.unlock(LockType.WRITE);
}
}
//This is called regularly by the expiry thread, but call it here synchronously
if (disk != null) {
disk.expireElements();
}
}
/**
* {@inheritDoc}
*/
public void flush() throws IOException {
memory.flush();
if (disk != null) {
disk.flush();
}
}
/**
* {@inheritDoc}
*/
public Element get(Object key) {
Sync s = sync.getSyncForKey(key);
s.lock(LockType.READ);
try {
Element e = memory.get(key);
if (e == null && disk != null) {
e = disk.get(key);
if (e != null) {
memory.put(e);
}
}
return e;
} finally {
s.unlock(LockType.READ);
}
}
/**
* {@inheritDoc}
*/
public Policy getInMemoryEvictionPolicy() {
return memory.getInMemoryEvictionPolicy();
}
/**
* {@inheritDoc}
*/
public int getInMemorySize() {
return memory.getSize();
}
/**
* {@inheritDoc}
*/
public long getInMemorySizeInBytes() {
return memory.getInMemorySizeInBytes();
}
/**
* {@inheritDoc}
*/
public Object getInternalContext() {
return sync;
}
/**
* {@inheritDoc}
*/
public List getKeys() {
if (disk == null) {
return memory.getKeys();
} else {
HashSet
© 2015 - 2025 Weber Informatics LLC | Privacy Policy