Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client-side cache related naming changes #3758

Merged
merged 6 commits into from
Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;

import redis.clients.jedis.csc.hash.CommandLongHashing;
import redis.clients.jedis.csc.hash.OpenHftHashing;
import redis.clients.jedis.csc.hash.CommandLongHasher;
import redis.clients.jedis.csc.hash.OpenHftCommandHasher;

public class CaffeineCSC extends ClientSideCache {
public class CaffeineClientSideCache extends ClientSideCache {

private final Cache<Long, Object> cache;

public CaffeineCSC(Cache<Long, Object> caffeineCache) {
this(caffeineCache, new OpenHftHashing(OpenHftHashing.DEFAULT_HASH_FUNCTION), DefaultClientSideCacheable.INSTANCE);
public CaffeineClientSideCache(Cache<Long, Object> caffeineCache) {
this(caffeineCache, DefaultClientSideCacheable.INSTANCE);
}

public CaffeineCSC(Cache<Long, Object> caffeineCache, ClientSideCacheable cacheable) {
this(caffeineCache, new OpenHftHashing(OpenHftHashing.DEFAULT_HASH_FUNCTION), cacheable);
public CaffeineClientSideCache(Cache<Long, Object> caffeineCache, ClientSideCacheable cacheable) {
this(caffeineCache, new OpenHftCommandHasher(OpenHftCommandHasher.DEFAULT_HASH_FUNCTION), cacheable);
}

public CaffeineCSC(Cache<Long, Object> caffeineCache, CommandLongHashing hashing, ClientSideCacheable cacheable) {
super(hashing, cacheable);
public CaffeineClientSideCache(Cache<Long, Object> caffeineCache, CommandLongHasher commandHasher, ClientSideCacheable cacheable) {
super(commandHasher, cacheable);
this.cache = caffeineCache;
}

Expand Down Expand Up @@ -55,7 +55,7 @@ public static class Builder {
private final TimeUnit expireTimeUnit = TimeUnit.SECONDS;

// not using a default value to avoid an object creation like 'new OpenHftHashing(hashFunction)'
private CommandLongHashing longHashing = null;
private CommandLongHasher commandHasher = null;

private ClientSideCacheable cacheable = DefaultClientSideCacheable.INSTANCE;

Expand All @@ -71,8 +71,8 @@ public Builder ttl(int seconds) {
return this;
}

public Builder hashing(CommandLongHashing hashing) {
this.longHashing = hashing;
public Builder commandHasher(CommandLongHasher commandHasher) {
this.commandHasher = commandHasher;
return this;
}

Expand All @@ -81,16 +81,15 @@ public Builder cacheable(ClientSideCacheable cacheable) {
return this;
}

public CaffeineCSC build() {
public CaffeineClientSideCache build() {
Caffeine cb = Caffeine.newBuilder();

cb.maximumSize(maximumSize);

cb.expireAfterWrite(expireTime, expireTimeUnit);

return longHashing != null
? new CaffeineCSC(cb.build(), longHashing, cacheable)
: new CaffeineCSC(cb.build(), cacheable);
return commandHasher != null ? new CaffeineClientSideCache(cb.build(), commandHasher, cacheable)
: new CaffeineClientSideCache(cb.build(), cacheable);
}
}
}
19 changes: 10 additions & 9 deletions src/main/java/redis/clients/jedis/csc/ClientSideCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,31 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

import redis.clients.jedis.CommandObject;
import redis.clients.jedis.csc.hash.CommandLongHashing;
import redis.clients.jedis.csc.hash.CommandLongHasher;
import redis.clients.jedis.util.SafeEncoder;

/**
* The class to manage the client-side caching. User can provide any of implementation of this class to the client
* object; e.g. {@link redis.clients.jedis.csc.CaffeineCSC CaffeineCSC} or
* {@link redis.clients.jedis.csc.GuavaCSC GuavaCSC} or a custom implementation of their own.
* object; e.g. {@link redis.clients.jedis.csc.CaffeineClientSideCache CaffeineClientSideCache} or
* {@link redis.clients.jedis.csc.GuavaClientSideCache GuavaClientSideCache} or a custom implementation of their own.
*/
public abstract class ClientSideCache {

protected static final int DEFAULT_MAXIMUM_SIZE = 10_000;
protected static final int DEFAULT_EXPIRE_SECONDS = 100;

private final Map<ByteBuffer, Set<Long>> keyToCommandHashes = new ConcurrentHashMap<>();
private final CommandLongHashing commandHashing;
private final CommandLongHasher commandHasher;
private final ClientSideCacheable cacheable;

protected ClientSideCache(CommandLongHashing commandHashing) {
this(commandHashing, DefaultClientSideCacheable.INSTANCE);
protected ClientSideCache(CommandLongHasher commandHasher) {
this(commandHasher, DefaultClientSideCacheable.INSTANCE);
}

protected ClientSideCache(CommandLongHashing commandHashing, ClientSideCacheable cacheable) {
this.commandHashing = commandHashing;
protected ClientSideCache(CommandLongHasher commandHasher, ClientSideCacheable cacheable) {
this.commandHasher = commandHasher;
this.cacheable = cacheable;
}

Expand Down Expand Up @@ -80,7 +81,7 @@ public final <T> T get(Function<CommandObject<T>, T> loader, CommandObject<T> co
return loader.apply(command);
}

final long hash = commandHashing.hash(command);
final long hash = commandHasher.hash(command);

T value = (T) getValue(hash);
if (value != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,32 @@
import com.google.common.hash.HashFunction;
import java.util.concurrent.TimeUnit;

import redis.clients.jedis.csc.hash.CommandLongHashing;
import redis.clients.jedis.csc.hash.GuavaHashing;
import redis.clients.jedis.csc.hash.CommandLongHasher;
import redis.clients.jedis.csc.hash.GuavaCommandHasher;

public class GuavaCSC extends ClientSideCache {
public class GuavaClientSideCache extends ClientSideCache {

private final Cache<Long, Object> cache;

public GuavaCSC(Cache<Long, Object> guavaCache) {
this(guavaCache, GuavaHashing.DEFAULT_HASH_FUNCTION);
public GuavaClientSideCache(Cache<Long, Object> guavaCache) {
this(guavaCache, GuavaCommandHasher.DEFAULT_HASH_FUNCTION);
}

public GuavaCSC(Cache<Long, Object> guavaCache, HashFunction hashFunction) {
this(guavaCache, new GuavaHashing(hashFunction));
public GuavaClientSideCache(Cache<Long, Object> guavaCache, HashFunction hashFunction) {
this(guavaCache, new GuavaCommandHasher(hashFunction));
}

public GuavaCSC(Cache<Long, Object> guavaCache, CommandLongHashing hashing) {
super(hashing);
public GuavaClientSideCache(Cache<Long, Object> guavaCache, CommandLongHasher commandHasher) {
super(commandHasher);
this.cache = guavaCache;
}

public GuavaCSC(Cache<Long, Object> guavaCache, ClientSideCacheable cacheable) {
this(guavaCache, new GuavaHashing(GuavaHashing.DEFAULT_HASH_FUNCTION), cacheable);
public GuavaClientSideCache(Cache<Long, Object> guavaCache, ClientSideCacheable cacheable) {
this(guavaCache, new GuavaCommandHasher(GuavaCommandHasher.DEFAULT_HASH_FUNCTION), cacheable);
}

public GuavaCSC(Cache<Long, Object> cache, CommandLongHashing hashing, ClientSideCacheable cacheable) {
super(hashing, cacheable);
public GuavaClientSideCache(Cache<Long, Object> cache, CommandLongHasher commandHasher, ClientSideCacheable cacheable) {
super(commandHasher, cacheable);
this.cache = cache;
}

Expand Down Expand Up @@ -66,7 +66,7 @@ public static class Builder {

// not using a default value to avoid an object creation like 'new GuavaHashing(hashFunction)'
private HashFunction hashFunction = null;
private CommandLongHashing longHashing = null;
private CommandLongHasher commandHasher = null;

private ClientSideCacheable cacheable = DefaultClientSideCacheable.INSTANCE;

Expand All @@ -84,12 +84,12 @@ public Builder ttl(int seconds) {

public Builder hashFunction(HashFunction function) {
this.hashFunction = function;
this.longHashing = null;
this.commandHasher = null;
return this;
}

public Builder hashing(CommandLongHashing hashing) {
this.longHashing = hashing;
public Builder commandHasher(CommandLongHasher commandHasher) {
this.commandHasher = commandHasher;
this.hashFunction = null;
return this;
}
Expand All @@ -99,16 +99,16 @@ public Builder cacheable(ClientSideCacheable cacheable) {
return this;
}

public GuavaCSC build() {
public GuavaClientSideCache build() {
CacheBuilder cb = CacheBuilder.newBuilder();

cb.maximumSize(maximumSize);

cb.expireAfterWrite(expireTime, expireTimeUnit);

return longHashing != null ? new GuavaCSC(cb.build(), longHashing, cacheable)
: hashFunction != null ? new GuavaCSC(cb.build(), new GuavaHashing(hashFunction), cacheable)
: new GuavaCSC(cb.build(), cacheable);
return hashFunction != null ? new GuavaClientSideCache(cb.build(), new GuavaCommandHasher(hashFunction), cacheable)
: commandHasher != null ? new GuavaClientSideCache(cb.build(), commandHasher, cacheable)
: new GuavaClientSideCache(cb.build(), cacheable);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import redis.clients.jedis.CommandObject;
import redis.clients.jedis.args.Rawable;

public abstract class AbstractCommandHashing implements CommandLongHashing {
public abstract class AbstractCommandHasher implements CommandLongHasher {

@Override
public final long hash(CommandObject command) {
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/redis/clients/jedis/csc/hash/CommandLongHasher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package redis.clients.jedis.csc.hash;

import redis.clients.jedis.CommandObject;

/**
* The interface for hashing a command object to support client-side caching.
*/
public interface CommandLongHasher {

/**
* Produce a 64-bit signed hash value from a command object.
* @param command the command object
* @return 64-bit signed hash value
*/
long hash(CommandObject command);
}
16 changes: 0 additions & 16 deletions src/main/java/redis/clients/jedis/csc/hash/CommandLongHashing.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
import com.google.common.hash.Hasher;
import redis.clients.jedis.CommandObject;

public class GuavaHashing implements CommandLongHashing {
public class GuavaCommandHasher implements CommandLongHasher {

public static final HashFunction DEFAULT_HASH_FUNCTION = com.google.common.hash.Hashing.fingerprint2011();

private final HashFunction function;

public GuavaHashing(HashFunction function) {
public GuavaCommandHasher(HashFunction function) {
this.function = function;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import net.openhft.hashing.LongHashFunction;

public class OpenHftHashing extends PrimitiveArrayHashing implements CommandLongHashing {
public class OpenHftCommandHasher extends PrimitiveArrayCommandHasher implements CommandLongHasher {

public static final LongHashFunction DEFAULT_HASH_FUNCTION = LongHashFunction.xx3();

private final LongHashFunction function;

public OpenHftHashing(LongHashFunction function) {
public OpenHftCommandHasher(LongHashFunction function) {
this.function = function;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
import redis.clients.jedis.Builder;
import redis.clients.jedis.args.Rawable;

public abstract class PrimitiveArrayHashing extends AbstractCommandHashing {
/**
* It is possible to extend {@link PrimitiveArrayCommandHasher this abstract class} in order to implement
* {@link CommandLongHasher} as {@link PrimitiveArrayCommandHasher#hashLongs(long[])} and
* {@link PrimitiveArrayCommandHasher#hashBytes(byte[])} can be supported by almost all Java hashing libraries.
*/
public abstract class PrimitiveArrayCommandHasher extends AbstractCommandHasher {

@Override
protected final long hashRawable(Rawable raw) {
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/redis/clients/jedis/util/JedisURIHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Protocol;
import redis.clients.jedis.RedisProtocol;
import redis.clients.jedis.csc.CaffeineCSC;
import redis.clients.jedis.csc.CaffeineClientSideCache;
import redis.clients.jedis.csc.ClientSideCache;
import redis.clients.jedis.csc.GuavaCSC;
import redis.clients.jedis.csc.GuavaClientSideCache;

public final class JedisURIHelper {

Expand Down Expand Up @@ -137,12 +137,12 @@ public static ClientSideCache getClientSideCache(URI uri) {
}

if (guava) {
GuavaCSC.Builder guavaBuilder = GuavaCSC.builder();
GuavaClientSideCache.Builder guavaBuilder = GuavaClientSideCache.builder();
if (maxSize != null) guavaBuilder.maximumSize(maxSize);
if (ttl != null) guavaBuilder.ttl(ttl);
return guavaBuilder.build();
} else if (caffeine) {
CaffeineCSC.Builder caffeineBuilder = CaffeineCSC.builder();
CaffeineClientSideCache.Builder caffeineBuilder = CaffeineClientSideCache.builder();
if (maxSize != null) caffeineBuilder.maximumSize(maxSize);
if (ttl != null) caffeineBuilder.ttl(ttl);
return caffeineBuilder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public void tearDown() throws Exception {
public void none() {
HashMap<Long, Object> map = new HashMap<>();
try (JedisPooled jedis = new JedisPooled(hnp, clientConfig.get(),
new MapCSC(map, new AllowAndDenyListWithStringKeys(null, null, null, null)),
new MapClientSideCache(map, new AllowAndDenyListWithStringKeys(null, null, null, null)),
singleConnectionPoolConfig.get())) {
control.set("foo", "bar");
assertThat(map, Matchers.aMapWithSize(0));
Expand All @@ -67,7 +67,7 @@ public void none() {
public void whiteListCommand() {
HashMap<Long, Object> map = new HashMap<>();
try (JedisPooled jedis = new JedisPooled(hnp, clientConfig.get(),
new MapCSC(map, new AllowAndDenyListWithStringKeys(singleton(Protocol.Command.GET), null, null, null)),
new MapClientSideCache(map, new AllowAndDenyListWithStringKeys(singleton(Protocol.Command.GET), null, null, null)),
singleConnectionPoolConfig.get())) {
control.set("foo", "bar");
assertThat(map, Matchers.aMapWithSize(0));
Expand All @@ -80,7 +80,7 @@ public void whiteListCommand() {
public void blackListCommand() {
HashMap<Long, Object> map = new HashMap<>();
try (JedisPooled jedis = new JedisPooled(hnp, clientConfig.get(),
new MapCSC(map, new AllowAndDenyListWithStringKeys(null, singleton(Protocol.Command.GET), null, null)),
new MapClientSideCache(map, new AllowAndDenyListWithStringKeys(null, singleton(Protocol.Command.GET), null, null)),
singleConnectionPoolConfig.get())) {
control.set("foo", "bar");
assertThat(map, Matchers.aMapWithSize(0));
Expand All @@ -93,7 +93,7 @@ public void blackListCommand() {
public void whiteListKey() {
HashMap<Long, Object> map = new HashMap<>();
try (JedisPooled jedis = new JedisPooled(hnp, clientConfig.get(),
new MapCSC(map, new AllowAndDenyListWithStringKeys(null, null, singleton("foo"), null)),
new MapClientSideCache(map, new AllowAndDenyListWithStringKeys(null, null, singleton("foo"), null)),
singleConnectionPoolConfig.get())) {
control.set("foo", "bar");
assertThat(map, Matchers.aMapWithSize(0));
Expand All @@ -106,7 +106,7 @@ public void whiteListKey() {
public void blackListKey() {
HashMap<Long, Object> map = new HashMap<>();
try (JedisPooled jedis = new JedisPooled(hnp, clientConfig.get(),
new MapCSC(map, new AllowAndDenyListWithStringKeys(null, null, null, singleton("foo"))),
new MapClientSideCache(map, new AllowAndDenyListWithStringKeys(null, null, null, singleton("foo"))),
singleConnectionPoolConfig.get())) {
control.set("foo", "bar");
assertThat(map, Matchers.aMapWithSize(0));
Expand Down
Loading
Loading