All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.spy.memcached.plugin.LocalCacheManager Maven / Gradle / Ivy

There is a newer version: 1.13.2
Show newest version
/*
 * arcus-java-client : Arcus Java client
 * Copyright 2010-2014 NAVER Corp.
 *
 * 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.spy.memcached.plugin;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.config.PersistenceConfiguration;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
import net.spy.memcached.compat.log.Logger;
import net.spy.memcached.compat.log.LoggerFactory;
import net.spy.memcached.transcoders.Transcoder;

/**
 * Local cache storage based on ehcache.
 */
public class LocalCacheManager {

	private Logger logger = LoggerFactory.getLogger(getClass());
	
	protected Cache cache;
	protected String name;

	public LocalCacheManager() {
		this("DEFAULT_ARCUS_LOCAL_CACHE");
	}
	
	public LocalCacheManager(String name) {
		this.name = name;
		// create a undecorated Cache object.
		this.cache = CacheManager.getInstance().getCache(name);
	}
	
	public LocalCacheManager(String name, int max, int exptime, boolean copyOnRead, boolean copyOnWrite) {
		this.cache = CacheManager.getInstance().getCache(name);
		if (cache == null) {
			CacheConfiguration config =
							new CacheConfiguration(name, max)
							.copyOnRead(copyOnRead)
							.copyOnWrite(copyOnWrite)
							.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
							.eternal(false)
							.timeToLiveSeconds(exptime)
							.timeToIdleSeconds(exptime)
							.diskExpiryThreadIntervalSeconds(60)
							.persistence(new PersistenceConfiguration().strategy(PersistenceConfiguration.Strategy.NONE));
			this.cache = new Cache(config, null, null);
			CacheManager.getInstance().addCache(cache);
			
			if (logger.isInfoEnabled()) {
				logger.info("Arcus k/v local cache is enabled : %s", cache.toString());
			}
		}
	}
	
	public  T get(String key, Transcoder tc) {
		if (cache == null) {
			return null;
		}
		
		try {
			Element element = cache.get(key);
			if(null != element) {
				@SuppressWarnings("unchecked") T ret = (T) element.getObjectValue();
				return ret;
			}
		} catch (Exception e) {
			logger.info("failed to get from the local cache : %s", e.getMessage());
			return null;
		}

		return null;
	}
	
	public  Future asyncGet(final String key, final Transcoder tc) {
		Task task = new Task(new Callable() {
			public T call() throws Exception {
				return get(key, tc);
			}
		});
		return task;
	}
	
	public  Future asyncPreFetch(final String key, final Transcoder tc) {
		Task task = new Task(new Callable() {
			// pre-fetch the locally cached data.
			T v = get(key, tc);
			
			public T call() throws Exception {
				return v;
			}
		});
		return task;
	}
	
	public Element getElement(String key) {
		return cache.get(key);
	}
	
	public  boolean put(String k, T v) {
		if (v == null) {
			return false;
		}
		
		try {
			cache.put(new Element(k, v));
			return true;
		} catch (Exception e) {
			if (logger.isInfoEnabled()) {
				logger.info("failed to put to the local cache : %s", e.getMessage());
			}
			return false;
		}
	}
	
	public  boolean put(String k, Future future, long timeout) {
		if (future == null) {
			return false;
		}

		try {
			T v = future.get(timeout, TimeUnit.MILLISECONDS);
			return put(k, v);
		} catch (Exception e) {
			logger.info("failed to put to the local cache : %s", e.getMessage());
			return false;
		}
	}
	
	public void delete(String k) {
		try {
			cache.remove(k);
		} catch (Exception e) {
			logger.info("failed to remove the locally cached item : %s", e.getMessage());
		}
	}
	
	public static class Task extends FutureTask {
		private final AtomicBoolean isRunning = new AtomicBoolean(false);

		public Task(Callable callable) {
			super(callable);
		}

		@Override
		public T get() throws InterruptedException, ExecutionException {
			this.run();
			return super.get();
		}

		@Override
		public T get(long timeout, TimeUnit unit) throws InterruptedException,
				ExecutionException, TimeoutException {
			this.run();
			return super.get(timeout, unit);
		}

		@Override
		public void run() {
			if (this.isRunning.compareAndSet(false, true)) {
				super.run();
			}
		}
	}
	
	@Override
	public String toString() {
		return cache.toString();
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy