Package org.solbase.cache

Source Code of org.solbase.cache.MemcacheCache

package org.solbase.cache;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.UUID;

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.command.BinaryCommandFactory;
import net.rubyeye.xmemcached.transcoders.SerializingTranscoder;
import net.rubyeye.xmemcached.utils.AddrUtil;

public class MemcacheCache<K, V, Z> extends VersionedCache<K, V, Z> {

  /*
   * static Process memcacheProcess; static { try { memcacheProcess =
   * Runtime.getRuntime().exec("/opt/local/bin/memcached"); Thread
   * closeChildThread = new Thread() { public void run() {
   * memcacheProcess.destroy(); } };
   *
   * Runtime.getRuntime().addShutdownHook(closeChildThread);
   *
   * } catch (IOException e) { e.printStackTrace(); } }
   */

  private static final int memcacheSize = (1024 * 1024) - 1024;
  private MemcachedClient memcachedClient = null;

  public MemcacheCache() {
    this(null, null);
  }

  public MemcacheCache(String hostName, Integer port) {
    String memcacheHostName;
    String memcachePort;

    if (hostName == null) {
      memcacheHostName = System.getProperty("solbase.memcache.hostname");
      if (memcacheHostName == null && ResourceBundle.getBundle("solbase") != null) {
        memcacheHostName = ResourceBundle.getBundle("solbase").getString("memcache.hostname");
      }

      if (memcacheHostName == null) {
        memcacheHostName = "localhost";
      }
    } else {
      memcacheHostName = hostName;
    }

    if (hostName == null) {
      memcachePort = System.getProperty("solbase.memcache.port");

      if (memcachePort == null && ResourceBundle.getBundle("solbase") != null) {
        memcachePort = ResourceBundle.getBundle("solbase").getString("memcache.port");
      }

      if (memcachePort == null) {
        memcachePort = "11211";
      }
    } else {
      memcachePort = port.toString();
    }

    MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(memcacheHostName + ":" + memcachePort));
    builder.setCommandFactory(new BinaryCommandFactory());
    builder.setConnectionPoolSize(100);

    try {
      memcachedClient = builder.build();
      memcachedClient.setOpTimeout(30000);
      SerializingTranscoder st = new SerializingTranscoder(memcacheSize);
      memcachedClient.setTranscoder(st);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void resetCacheTime(K key, Long time) throws IOException {
    MemcacheCachedObjectWrapper<V, Z> value = getInternal(key);
    value.setCacheTime(time);
    try {
      memcachedClient.set(key.toString() + key.getClass().getName().hashCode(), 0, value);
    } catch (Exception ex) {
      throw new IOException(ex);
    }
  }

  protected MemcacheCachedObjectWrapper<V, Z> getInternal(K key) throws IOException {
    try {
      MemcacheCachedObjectWrapper<V, Z> tmp = memcachedClient.get(key.toString() + key.getClass().getName().hashCode());
      if (tmp != null) {
        if (tmp.getUuids() == null) {
          tmp.setValue(deserialize(tmp.getValueBytes()));
          tmp.setValueBytes(null);
        } else {
          ByteArrayOutputStream baos = new ByteArrayOutputStream(tmp.getUuids().size() * memcacheSize);
          Map<String, byte[]> results = memcachedClient.get(tmp.getUuids());

          for (String uuid : tmp.getUuids()) {
            byte[] tmpBytes = results.get(uuid);
            if (tmpBytes == null) {// part is missing, clean it all
                        // up
              memcachedClient.delete(key.toString() + key.getClass().getName().hashCode());
              for (String uuidToRemove : tmp.getUuids()) {
                memcachedClient.delete(uuidToRemove);
                return null;
              }
            }
            baos.write(tmpBytes);
          }

          tmp.setValue(deserialize(decompress(baos.toByteArray())));
        }
      }

      return tmp;
    } catch (Exception ex) {
      throw new IOException(ex);
    }
  }

  public void put(K key, CachedObjectWrapper<V, Z> aValue) throws IOException {
    try {
      MemcacheCachedObjectWrapper<V, Z> value = new MemcacheCachedObjectWrapper<V, Z>(aValue.getValue(), aValue.getVersionIdentifier(), aValue.getCacheTime());
      byte[] serializedBytes = serialize(value.getValue());

      if (serializedBytes.length > ((memcacheSize) - 1000)) {
        ArrayList<String> uuids = new ArrayList<String>(serializedBytes.length / memcacheSize);
        ByteBuffer bb = ByteBuffer.wrap(compress(serializedBytes));
        int remaining = 0;
        while ((remaining = bb.remaining()) > 0) {
          byte[] chunk = new byte[remaining < memcacheSize ? remaining : memcacheSize];
          bb.get(chunk);
          String uuid = UUID.randomUUID().toString();
          uuids.add(uuid);
          memcachedClient.set(uuid, 0, chunk);
        }

        value.setUuids(uuids);
      } else {
        value.setValueBytes(serializedBytes);
      }
      value.setValue(null);
      memcachedClient.set(key.toString() + key.getClass().getName().hashCode(), 0, value);
    } catch (Exception ex) {
      throw new IOException(ex);
    }
  }

  public void clear() throws IOException {
    try {
      memcachedClient.flushAll();
    } catch (Exception ex) {
      throw new IOException(ex);
    }
  }
}
TOP

Related Classes of org.solbase.cache.MemcacheCache

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.