blob: 119e137e7579fe2f9101cab3e370d5b7ba755fdf [file] [log] [blame]
/*=========================================================================
* Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
* This product is protected by U.S. and international copyright
* and intellectual property laws. Pivotal products are covered by
* one or more patents listed at http://www.pivotal.io/patents.
*=========================================================================
*/
package com.gemstone.gemfire.modules.hibernate;
import java.util.Map;
import org.hibernate.cache.Cache;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.Timestamper;
import com.gemstone.gemfire.cache.EntryNotFoundException;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.Scope;
import com.gemstone.gemfire.distributed.DistributedLockService;
import com.gemstone.gemfire.internal.cache.LocalRegion;
public class GemFireCache implements Cache {
private Region region;
private boolean clientRegion = false;
private final DistributedLockService distributedLockService;
public GemFireCache(Region region, DistributedLockService lockService) {
this.region = region;
this.distributedLockService = lockService;
this.clientRegion = isClient(region);
}
private boolean isClient(Region region) {
return region.getAttributes().getPoolName() != null;
}
/**
* Clear the cache
*/
public void clear() throws CacheException {
GemFireCacheProvider.getLogger().info("GemFireCache: clear called");
region.clear();
}
/**
* Clean up
*/
public void destroy() throws CacheException {
GemFireCacheProvider.getLogger().info("GemFireCache: destroy called");
region.localDestroyRegion();
}
/**
* Get an item from the cache
*
* @param key
* @return the cached object or <tt>null</tt>
* @throws CacheException
*/
public Object get(Object key) throws CacheException {
GemFireCacheProvider.getLogger().debug(
"GemFireCache: get called for: " + key);
try {
Object value = region.get(key);
GemFireCacheProvider.getLogger().debug(
"GemFireCache: retrieved: " + key + "-->" + value);
return value;
}
catch (com.gemstone.gemfire.cache.CacheException e) {
throw new CacheException(e);
}
}
/**
* The count of entries currently contained in the regions in-memory store.
*
* @return The count of entries in memory; -1 if unknown or unsupported.
*/
public long getElementCountInMemory() {
return ((LocalRegion)region).entryCount();
}
/**
* The count of entries currently contained in the regions disk store.
*
* @return The count of entries on disk; -1 if unknown or unsupported.
*/
public long getElementCountOnDisk() {
return -1;
}
/**
* Get the name of the cache region
*/
public String getRegionName() {
return region.getName();
}
/**
* The number of bytes is this cache region currently consuming in memory.
*
* @return The number of bytes consumed by this region; -1 if unknown or
* unsupported.
*/
public long getSizeInMemory() {
return -1;
}
/**
* Return the lock timeout for this cache.
*/
public int getTimeout() {
GemFireCacheProvider.getLogger().debug("GemFireCache: getTimeout");
return Timestamper.ONE_MS * 60000;
}
/**
* If this is a clustered cache, lock the item
*/
public void lock(Object key) throws CacheException {
GemFireCacheProvider.getLogger().info(
"GemFireCache: lock called for: " + key);
if (!clientRegion) {
// If we're using GLOBAL scope, we don't have to worry about
// locking.
if (!Scope.GLOBAL.equals(region.getAttributes().getScope())) {
this.distributedLockService.lock(key, -1, -1);
}
}
else {
// We assume the server region is GLOBAL for now. Else, use command
// pattern to acquire lock on the server
GemFireCacheProvider.getLogger().info(
"GemFireCache: client region, ignoring lock : " + key);
}
}
/**
* Generate the next timestamp
*/
public long nextTimestamp() {
GemFireCacheProvider.getLogger().debug("GemFireCache: nextTimestamp called");
// TODO : Need a counter, cache-wide
return Timestamper.next();
}
/**
* Add an item to the cache
*
* @param key
* @param value
* @throws CacheException
*/
public void put(Object key, Object value) throws CacheException {
GemFireCacheProvider.getLogger().debug(
"GemFireCache: put called for key: " + key + "value: " + value);
try {
region.put(key, value);
GemFireCacheProvider.getLogger().debug(
"GemFireCache: put " + key + "-->" + value);
}
catch (com.gemstone.gemfire.cache.CacheException e) {
throw new CacheException(e);
}
}
public Object read(Object key) throws CacheException {
GemFireCacheProvider.getLogger().info(
"GemFireCache: read called for: " + key);
return region.get(key);
}
/**
* Remove an item from the cache
*/
public void remove(Object key) throws CacheException {
GemFireCacheProvider.getLogger().debug(
"GemFireCache: remove called for: " + key);
try {
region.destroy(key);
GemFireCacheProvider.getLogger().debug("GemFireCache: removed: " + key);
}
catch (EntryNotFoundException e) {
// We can silently ignore this
}
catch (com.gemstone.gemfire.cache.CacheException e) {
throw new CacheException(e);
}
}
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("Hibernate cache on GemFire region: ");
buffer.append(region);
return buffer.toString();
}
/**
* If this is a clustered cache, unlock the item
*/
public void unlock(Object key) throws CacheException {
GemFireCacheProvider.getLogger().info(
"GemFireCache: unlock called for: " + key);
if (!clientRegion) {
// If we're using GLOBAL scope, we don't have to worry about locking.
if (!Scope.GLOBAL.equals(region.getAttributes().getScope())) {
this.distributedLockService.unlock(key);
}
}
else {
GemFireCacheProvider.getLogger().info(
"GemFireCache: client region, ignoring lock : " + key);
}
}
public void update(Object key, Object value) throws CacheException {
GemFireCacheProvider.getLogger().info(
"GemFireCache: update called for: " + key);
this.region.put(key, value);
}
public Map<?, ?> toMap() {
return null;
}
}