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

com.landawn.abacus.cache.SpyMemcached Maven / Gradle / Ivy

/*
 * Copyright (C) 2015 HaiYang Li
 *
 * 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 com.landawn.abacus.cache;

import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import com.landawn.abacus.exception.UncheckedIOException;
import com.landawn.abacus.logging.Logger;
import com.landawn.abacus.logging.LoggerFactory;
import com.landawn.abacus.util.AddrUtil;
import com.landawn.abacus.util.N;

import net.spy.memcached.ConnectionFactory;
import net.spy.memcached.DefaultConnectionFactory;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.transcoders.Transcoder;

/**
 * 
 * @since 0.8
 * 
 * @author Haiyang Li
 */
public class SpyMemcached extends AbstractDistributedCacheClient {
    private static final Logger logger = LoggerFactory.getLogger(SpyMemcached.class);
    private MemcachedClient mc;

    public SpyMemcached(final String serverUrl) {
        this(serverUrl, DEFAULT_TIMEOUT);
    }

    public SpyMemcached(final String serverUrl, final long timeout) {
        this(serverUrl, timeout, null);

    }

    public SpyMemcached(final String serverUrl, final long timeout, final Transcoder transcoder) {
        super(serverUrl);

        ConnectionFactory connFactory = new DefaultConnectionFactory() {
            @Override
            public long getOperationTimeout() {
                return timeout;
            }

            @Override
            public Transcoder getDefaultTranscoder() {
                if (transcoder != null) {
                    return transcoder;
                } else {
                    return super.getDefaultTranscoder();
                }
            }
        };

        mc = createSpyMemcachedClient(serverUrl, connFactory);
    }

    @SuppressWarnings("unchecked")
    @Override
    public T get(String key) {
        return (T) mc.get(key);
    }

    @SuppressWarnings("unchecked")
    public Future asyncGet(String key) {
        return (Future) mc.asyncGet(key);
    }

    @SuppressWarnings("unchecked")
    @Override
    @SafeVarargs
    public final Map getBulk(String... keys) {
        return (Map) mc.getBulk(keys);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @SafeVarargs
    public final Future> asyncGetBulk(String... keys) {
        return (Future) mc.asyncGetBulk(keys);
    }

    @SuppressWarnings("unchecked")
    @Override
    public Map getBulk(Collection keys) {
        return (Map) mc.getBulk(keys);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public Future> asyncGetBulk(Collection keys) {
        return (Future) mc.asyncGetBulk(keys);
    }

    @Override
    public boolean set(String key, T obj, long liveTime) {
        return resultOf(mc.set(key, toSeconds(liveTime), obj));
    }

    public Future asyncSet(String key, T obj, long liveTime) {
        return mc.set(key, toSeconds(liveTime), obj);
    }

    public boolean add(String key, T obj, long liveTime) {
        return resultOf(mc.add(key, toSeconds(liveTime), obj));
    }

    public Future asyncAdd(String key, T obj, long liveTime) {
        return mc.add(key, toSeconds(liveTime), obj);
    }

    public boolean replace(String key, T obj, long liveTime) {
        return resultOf(mc.replace(key, toSeconds(liveTime), obj));
    }

    public Future asyncReplace(String key, T obj, long liveTime) {
        return mc.replace(key, toSeconds(liveTime), obj);
    }

    @Override
    public boolean delete(String key) {
        return resultOf(mc.delete(key));
    }

    public Future asyncDelete(String key) {
        return mc.delete(key);
    }

    @Override
    public long incr(String key) {
        return mc.incr(key, 1);
    }

    @Override
    public long incr(String key, int deta) {
        return mc.incr(key, deta);
    }

    public long incr(String key, int deta, long defaultValue) {
        return mc.incr(key, deta, defaultValue, -1);
    }

    public long incr(String key, int deta, long defaultValue, long liveTime) {
        return mc.incr(key, deta, defaultValue, toSeconds(liveTime));
    }

    @Override
    public long decr(String key) {
        return mc.decr(key, 1);
    }

    @Override
    public long decr(String key, int deta) {
        return mc.decr(key, deta);
    }

    public long decr(String key, int deta, long defaultValue) {
        return mc.decr(key, deta, defaultValue, -1);
    }

    public long decr(String key, int deta, long defaultValue, long liveTime) {
        return mc.decr(key, deta, defaultValue, toSeconds(liveTime));
    }

    @Override
    public void flushAll() {
        resultOf(mc.flush());
    }

    public Future asyncFlushAll() {
        return mc.flush();
    }

    public boolean flushAll(long delay) {
        return resultOf(mc.flush(toSeconds(delay)));
    }

    public Future asyncFlushAll(long delay) {
        return mc.flush(toSeconds(delay));
    }

    @Override
    public void disconnect() {
        mc.shutdown();
    }

    public void disconnect(long timeout) {
        mc.shutdown(timeout, TimeUnit.MICROSECONDS);
    }

    protected  R resultOf(Future future) {
        try {
            return future.get();
        } catch (InterruptedException e) {
            throw N.toRuntimeException(e);
        } catch (ExecutionException e) {
            throw N.toRuntimeException(e);
        }
    }

    protected net.spy.memcached.MemcachedClient createSpyMemcachedClient(String serverUrl, ConnectionFactory connFactory) {
        try {
            return new net.spy.memcached.MemcachedClient(connFactory, AddrUtil.getAddressList(serverUrl));
        } catch (IOException e) {
            String msg = "Failed to create Memcached client.";
            logger.warn(msg, e);
            throw new UncheckedIOException(msg, e);
        }
    }
}