Created
July 24, 2018 09:25
-
-
Save pangda0xff/a012daa3713a865b1f55a2b03e196971 to your computer and use it in GitHub Desktop.
A Cache implement using redis and kryo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.keruyun.ca.selection.site.cache; | |
import com.esotericsoftware.kryo.Kryo; | |
import com.esotericsoftware.kryo.io.Input; | |
import com.esotericsoftware.kryo.io.Output; | |
import com.esotericsoftware.kryo.pool.KryoPool; | |
import org.springframework.cache.Cache; | |
import redis.clients.jedis.Jedis; | |
import redis.clients.jedis.JedisPool; | |
import java.util.concurrent.Callable; | |
/** | |
* A redis cache using kryo and prefix | |
*/ | |
public class RedisCache implements Cache { | |
private static final int KEY_BUFFER_SIZE = 200; | |
private static final int VALUE_BUFFER_SIZE = 3000; | |
private JedisPool jedisPool; | |
private KryoPool kryoPool; | |
private String name; | |
private int duration; | |
public RedisCache(JedisPool jedisPool, KryoPool kryoPool, String name, int duration) { | |
this.jedisPool = jedisPool; | |
this.kryoPool = kryoPool; | |
this.name = name; | |
this.duration = duration; | |
} | |
@Override | |
public String getName() { | |
return name; | |
} | |
@Override | |
public Object getNativeCache() { | |
return jedisPool; | |
} | |
@Override | |
public ValueWrapper get(Object key) { | |
Kryo kryo = kryoPool.borrow(); | |
try { | |
Output output = new Output(KEY_BUFFER_SIZE); | |
kryo.writeObject(output, name + key); | |
byte[] value; | |
try (Jedis jedis = jedisPool.getResource()) { | |
value = jedis.get(output.toBytes()); | |
} | |
if (value == null) { | |
return null; | |
} else { | |
return () -> value; | |
} | |
} finally { | |
kryoPool.release(kryo); | |
} | |
} | |
@Override | |
public <T> T get(Object key, Class<T> type) { | |
Kryo kryo = kryoPool.borrow(); | |
try { | |
Output output = new Output(KEY_BUFFER_SIZE); | |
kryo.writeObject(output, name + key); | |
byte[] value; | |
try (Jedis jedis = jedisPool.getResource()) { | |
value = jedis.get(output.toBytes()); | |
} | |
return value == null ? null : kryo.readObject(new Input(value), type); | |
} finally { | |
kryoPool.release(kryo); | |
} | |
} | |
@Override | |
public <T> T get(Object key, Callable<T> valueLoader) { | |
ValueWrapper valueWrapper = get(key); | |
if (valueLoader != null) { | |
return (T) valueWrapper.get(); | |
} | |
try { | |
T ret = valueLoader.call(); | |
put(key, ret); | |
return ret; | |
} catch (Exception e) { | |
throw new ValueRetrievalException(key, valueLoader, e); | |
} | |
} | |
@Override | |
public void put(Object key, Object value) { | |
Kryo kryo = kryoPool.borrow(); | |
try { | |
Output keyOutput = new Output(KEY_BUFFER_SIZE); | |
kryo.writeObject(keyOutput, name + key); | |
Output valueOutput = new Output(VALUE_BUFFER_SIZE); | |
kryo.writeObject(valueOutput, value); | |
try (Jedis jedis = jedisPool.getResource()) { | |
jedis.setex(keyOutput.toBytes(), duration, valueOutput.toBytes()); | |
} | |
} finally { | |
kryoPool.release(kryo); | |
} | |
} | |
@Override | |
public ValueWrapper putIfAbsent(Object key, Object value) { | |
ValueWrapper ret = get(key); | |
if (ret != null) { | |
return ret; | |
} | |
Kryo kryo = kryoPool.borrow(); | |
try { | |
Output keyOutput = new Output(KEY_BUFFER_SIZE); | |
kryo.writeObject(keyOutput, name + key); | |
Output valueOutput = new Output(VALUE_BUFFER_SIZE); | |
kryo.writeObject(valueOutput, value); | |
try (Jedis jedis = jedisPool.getResource()) { | |
byte[] keybytes = keyOutput.toBytes(); | |
long effect = jedis.setnx(keybytes, valueOutput.toBytes()); | |
if (effect > 0) { | |
jedis.expire(keybytes, duration); | |
} | |
} | |
} finally { | |
kryoPool.release(kryo); | |
} | |
return null; | |
} | |
@Override | |
public void evict(Object key) { | |
Kryo kryo = kryoPool.borrow(); | |
try { | |
Output keyOutput = new Output(KEY_BUFFER_SIZE); | |
kryo.writeObject(keyOutput, name + key); | |
try (Jedis jedis = jedisPool.getResource()) { | |
jedis.del(name + key); | |
} | |
} finally { | |
kryoPool.release(kryo); | |
} | |
} | |
@Override | |
public void clear() { | |
// not support | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment