Skip to content

Commit 000e07b

Browse files
committed
Merge branch '5.2.0' into csc-hashing-interface
Conflicts: src/main/java/redis/clients/jedis/csc/ClientSideCache.java src/main/java/redis/clients/jedis/csc/util/CaffeineCSC.java src/main/java/redis/clients/jedis/csc/util/GuavaCSC.java src/test/java/redis/clients/jedis/csc/ClientSideCacheLibsTest.java src/test/java/redis/clients/jedis/csc/MapCSC.java
2 parents c620950 + 333dcd7 commit 000e07b

25 files changed

+347
-72
lines changed

Diff for: src/main/java/redis/clients/jedis/Connection.java

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import redis.clients.jedis.args.ClientAttributeOption;
1919
import redis.clients.jedis.args.Rawable;
2020
import redis.clients.jedis.commands.ProtocolCommand;
21+
import redis.clients.jedis.csc.ClientSideCache;
2122
import redis.clients.jedis.exceptions.JedisConnectionException;
2223
import redis.clients.jedis.exceptions.JedisDataException;
2324
import redis.clients.jedis.exceptions.JedisException;

Diff for: src/main/java/redis/clients/jedis/ConnectionFactory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import org.apache.commons.pool2.impl.DefaultPooledObject;
77
import org.slf4j.Logger;
88
import org.slf4j.LoggerFactory;
9-
9+
import redis.clients.jedis.csc.ClientSideCache;
1010
import redis.clients.jedis.exceptions.JedisException;
1111

1212
/**

Diff for: src/main/java/redis/clients/jedis/ConnectionPool.java

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.apache.commons.pool2.PooledObjectFactory;
44
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
5+
import redis.clients.jedis.csc.ClientSideCache;
56
import redis.clients.jedis.util.Pool;
67

78
public class ConnectionPool extends Pool<Connection> {

Diff for: src/main/java/redis/clients/jedis/JedisCluster.java

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
99
import redis.clients.jedis.providers.ClusterConnectionProvider;
10+
import redis.clients.jedis.csc.ClientSideCache;
1011
import redis.clients.jedis.util.JedisClusterCRC16;
1112

1213
public class JedisCluster extends UnifiedJedis {

Diff for: src/main/java/redis/clients/jedis/JedisClusterInfoCache.java

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.slf4j.Logger;
2323
import org.slf4j.LoggerFactory;
24+
import redis.clients.jedis.csc.ClientSideCache;
2425
import redis.clients.jedis.exceptions.JedisClusterOperationException;
2526
import redis.clients.jedis.exceptions.JedisException;
2627
import redis.clients.jedis.util.SafeEncoder;

Diff for: src/main/java/redis/clients/jedis/JedisPooled.java

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import org.apache.commons.pool2.PooledObjectFactory;
99
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
10+
import redis.clients.jedis.csc.ClientSideCache;
1011
import redis.clients.jedis.providers.PooledConnectionProvider;
1112
import redis.clients.jedis.util.JedisURIHelper;
1213
import redis.clients.jedis.util.Pool;

Diff for: src/main/java/redis/clients/jedis/JedisSentineled.java

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.Set;
44
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
5+
import redis.clients.jedis.csc.ClientSideCache;
56
import redis.clients.jedis.providers.SentineledConnectionProvider;
67

78
public class JedisSentineled extends UnifiedJedis {

Diff for: src/main/java/redis/clients/jedis/Protocol.java

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import redis.clients.jedis.exceptions.*;
1212
import redis.clients.jedis.args.Rawable;
1313
import redis.clients.jedis.commands.ProtocolCommand;
14+
import redis.clients.jedis.csc.ClientSideCache;
1415
import redis.clients.jedis.util.KeyValue;
1516
import redis.clients.jedis.util.RedisInputStream;
1617
import redis.clients.jedis.util.RedisOutputStream;

Diff for: src/main/java/redis/clients/jedis/UnifiedJedis.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import redis.clients.jedis.commands.SampleBinaryKeyedCommands;
1818
import redis.clients.jedis.commands.SampleKeyedCommands;
1919
import redis.clients.jedis.commands.RedisModuleCommands;
20+
import redis.clients.jedis.csc.ClientSideCache;
2021
import redis.clients.jedis.exceptions.JedisException;
2122
import redis.clients.jedis.executors.*;
2223
import redis.clients.jedis.gears.TFunctionListParams;
@@ -300,11 +301,11 @@ public void setBroadcastAndRoundRobinConfig(JedisBroadcastAndRoundRobinConfig co
300301
}
301302

302303
private <T> T checkAndClientSideCacheCommand(CommandObject<T> command, Object... keys) {
303-
if (clientSideCache == null) {
304-
return executeCommand(command);
304+
if (clientSideCache != null) {
305+
return clientSideCache.get((cmd) -> executeCommand(cmd), command, keys);
305306
}
306307

307-
return clientSideCache.getValue((cmd) -> executeCommand(cmd), command, keys);
308+
return executeCommand(command);
308309
}
309310

310311
public String ping() {

Diff for: src/main/java/redis/clients/jedis/ClientSideCache.java renamed to src/main/java/redis/clients/jedis/csc/ClientSideCache.java

+25-16
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,52 @@
1-
package redis.clients.jedis;
1+
package redis.clients.jedis.csc;
22

33
import java.nio.ByteBuffer;
44
import java.util.HashSet;
55
import java.util.List;
66
import java.util.Map;
77
import java.util.Set;
88
import java.util.concurrent.ConcurrentHashMap;
9-
109
import java.util.function.Function;
10+
import redis.clients.jedis.CommandObject;
1111
import redis.clients.jedis.csc.hash.CommandLongHashing;
1212
import redis.clients.jedis.util.SafeEncoder;
1313

1414
/**
1515
* The class to manage the client-side caching. User can provide any of implementation of this class to the client
16-
* object; e.g. {@link redis.clients.jedis.util.CaffeineCSC CaffeineCSC} or
17-
* {@link redis.clients.jedis.util.GuavaCSC GuavaCSC} or a custom implementation of their own.
16+
* object; e.g. {@link redis.clients.jedis.csc.util.CaffeineCSC CaffeineCSC} or
17+
* {@link redis.clients.jedis.csc.util.GuavaCSC GuavaCSC} or a custom implementation of their own.
1818
*/
1919
public abstract class ClientSideCache {
2020

2121
protected static final int DEFAULT_MAXIMUM_SIZE = 10_000;
2222
protected static final int DEFAULT_EXPIRE_SECONDS = 100;
2323

24+
private final Map<ByteBuffer, Set<Long>> keyToCommandHashes = new ConcurrentHashMap<>();
2425
private final CommandLongHashing commandHashing;
25-
private final Map<ByteBuffer, Set<Long>> keyToCommandHashes;
26+
private final ClientSideCacheable cacheable;
2627

2728
protected ClientSideCache(CommandLongHashing commandHashing) {
29+
this(commandHashing, DefaultClientSideCacheable.INSTANCE);
30+
}
31+
32+
protected ClientSideCache(CommandLongHashing commandHashing, ClientSideCacheable cacheable) {
2833
this.commandHashing = commandHashing;
29-
this.keyToCommandHashes = new ConcurrentHashMap<>();
34+
this.cacheable = cacheable;
3035
}
3136

32-
protected abstract void invalidateAllCommandHashes();
37+
protected abstract void invalidateAllHashes();
3338

34-
protected abstract void invalidateCommandHashes(Iterable<Long> hashes);
39+
protected abstract void invalidateHashes(Iterable<Long> hashes);
3540

36-
protected abstract void put(long hash, Object value);
41+
protected abstract void putValue(long hash, Object value);
3742

38-
protected abstract Object get(long hash);
43+
protected abstract Object getValue(long hash);
3944

4045
public final void clear() {
4146
invalidateAllKeysAndCommandHashes();
4247
}
4348

44-
final void invalidate(List list) {
49+
public final void invalidate(List list) {
4550
if (list == null) {
4651
invalidateAllKeysAndCommandHashes();
4752
return;
@@ -51,7 +56,7 @@ final void invalidate(List list) {
5156
}
5257

5358
private void invalidateAllKeysAndCommandHashes() {
54-
invalidateAllCommandHashes();
59+
invalidateAllHashes();
5560
keyToCommandHashes.clear();
5661
}
5762

@@ -64,23 +69,27 @@ private void invalidateKeyAndRespectiveCommandHashes(Object key) {
6469

6570
Set<Long> hashes = keyToCommandHashes.get(mapKey);
6671
if (hashes != null) {
67-
invalidateCommandHashes(hashes);
72+
invalidateHashes(hashes);
6873
keyToCommandHashes.remove(mapKey);
6974
}
7075
}
7176

72-
final <T> T getValue(Function<CommandObject<T>, T> loader, CommandObject<T> command, Object... keys) {
77+
public final <T> T get(Function<CommandObject<T>, T> loader, CommandObject<T> command, Object... keys) {
78+
79+
if (!cacheable.isCacheable(command.getArguments().getCommand(), keys)) {
80+
return loader.apply(command);
81+
}
7382

7483
final long hash = commandHashing.hash(command);
7584

76-
T value = (T) get(hash);
85+
T value = (T) getValue(hash);
7786
if (value != null) {
7887
return value;
7988
}
8089

8190
value = loader.apply(command);
8291
if (value != null) {
83-
put(hash, value);
92+
putValue(hash, value);
8493
for (Object key : keys) {
8594
ByteBuffer mapKey = makeKeyForKeyToCommandHashes(key);
8695
if (keyToCommandHashes.containsKey(mapKey)) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package redis.clients.jedis.csc;
2+
3+
import redis.clients.jedis.commands.ProtocolCommand;
4+
5+
public interface ClientSideCacheable {
6+
7+
boolean isCacheable(ProtocolCommand command, Object... keys);
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package redis.clients.jedis.csc;
2+
3+
import redis.clients.jedis.commands.ProtocolCommand;
4+
5+
public class DefaultClientSideCacheable implements ClientSideCacheable {
6+
7+
public static final DefaultClientSideCacheable INSTANCE = new DefaultClientSideCacheable();
8+
9+
public DefaultClientSideCacheable() { }
10+
11+
@Override
12+
public boolean isCacheable(ProtocolCommand command, Object... keys) {
13+
return true;
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package redis.clients.jedis.csc.util;
2+
3+
import java.util.Set;
4+
import redis.clients.jedis.commands.ProtocolCommand;
5+
import redis.clients.jedis.csc.ClientSideCacheable;
6+
7+
public class AllowAndDenyListWithStringKeys implements ClientSideCacheable {
8+
9+
private final Set<ProtocolCommand> allowCommands;
10+
private final Set<ProtocolCommand> denyCommands;
11+
12+
private final Set<String> allowKeys;
13+
private final Set<String> denyKeys;
14+
15+
public AllowAndDenyListWithStringKeys(Set<ProtocolCommand> allowCommands, Set<ProtocolCommand> denyCommands,
16+
Set<String> allowKeys, Set<String> denyKeys) {
17+
this.allowCommands = allowCommands;
18+
this.denyCommands = denyCommands;
19+
this.allowKeys = allowKeys;
20+
this.denyKeys = denyKeys;
21+
}
22+
23+
@Override
24+
public boolean isCacheable(ProtocolCommand command, Object... keys) {
25+
if (allowCommands != null && !allowCommands.contains(command)) return false;
26+
if (denyCommands != null && denyCommands.contains(command)) return false;
27+
28+
for (Object key : keys) {
29+
if (!(key instanceof String)) return false;
30+
if (allowKeys != null && !allowKeys.contains((String) key)) return false;
31+
if (denyKeys != null && denyKeys.contains((String) key)) return false;
32+
}
33+
34+
return true;
35+
}
36+
}

Diff for: src/main/java/redis/clients/jedis/util/CaffeineCSC.java renamed to src/main/java/redis/clients/jedis/csc/util/CaffeineCSC.java

+26-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
package redis.clients.jedis.util;
1+
package redis.clients.jedis.csc.util;
22

33
import com.github.benmanes.caffeine.cache.Cache;
44
import com.github.benmanes.caffeine.cache.Caffeine;
55
import java.util.concurrent.TimeUnit;
6-
import redis.clients.jedis.ClientSideCache;
6+
7+
import redis.clients.jedis.csc.ClientSideCache;
8+
import redis.clients.jedis.csc.ClientSideCacheable;
9+
import redis.clients.jedis.csc.DefaultClientSideCacheable;
710
import redis.clients.jedis.csc.hash.CommandLongHashing;
811
import redis.clients.jedis.csc.hash.OpenHftHashing;
912

@@ -12,31 +15,35 @@ public class CaffeineCSC extends ClientSideCache {
1215
private final Cache<Long, Object> cache;
1316

1417
public CaffeineCSC(Cache<Long, Object> caffeineCache) {
15-
this(caffeineCache, new OpenHftHashing(OpenHftHashing.DEFAULT_HASH_FUNCTION));
18+
this(caffeineCache, new OpenHftHashing(OpenHftHashing.DEFAULT_HASH_FUNCTION), DefaultClientSideCacheable.INSTANCE);
19+
}
20+
21+
public CaffeineCSC(Cache<Long, Object> caffeineCache, ClientSideCacheable cacheable) {
22+
this(caffeineCache, new OpenHftHashing(OpenHftHashing.DEFAULT_HASH_FUNCTION), cacheable);
1623
}
1724

18-
public CaffeineCSC(Cache<Long, Object> caffeineCache, CommandLongHashing hashing) {
19-
super(hashing);
25+
public CaffeineCSC(Cache<Long, Object> caffeineCache, CommandLongHashing hashing, ClientSideCacheable cacheable) {
26+
super(hashing, cacheable);
2027
this.cache = caffeineCache;
2128
}
2229

2330
@Override
24-
protected final void invalidateAllCommandHashes() {
31+
protected final void invalidateAllHashes() {
2532
cache.invalidateAll();
2633
}
2734

2835
@Override
29-
protected void invalidateCommandHashes(Iterable<Long> hashes) {
36+
protected void invalidateHashes(Iterable<Long> hashes) {
3037
cache.invalidateAll(hashes);
3138
}
3239

3340
@Override
34-
protected void put(long hash, Object value) {
41+
protected void putValue(long hash, Object value) {
3542
cache.put(hash, value);
3643
}
3744

3845
@Override
39-
protected Object get(long hash) {
46+
protected Object getValue(long hash) {
4047
return cache.getIfPresent(hash);
4148
}
4249

@@ -53,6 +60,8 @@ public static class Builder {
5360
// not using a default value to avoid an object creation like 'new OpenHftHashing(hashFunction)'
5461
private CommandLongHashing longHashing = null;
5562

63+
private ClientSideCacheable cacheable = DefaultClientSideCacheable.INSTANCE;
64+
5665
private Builder() { }
5766

5867
public Builder maximumSize(int size) {
@@ -70,14 +79,21 @@ public Builder hashing(CommandLongHashing hashing) {
7079
return this;
7180
}
7281

82+
public Builder cacheable(ClientSideCacheable cacheable) {
83+
this.cacheable = cacheable;
84+
return this;
85+
}
86+
7387
public CaffeineCSC build() {
7488
Caffeine cb = Caffeine.newBuilder();
7589

7690
cb.maximumSize(maximumSize);
7791

7892
cb.expireAfterWrite(expireTime, expireTimeUnit);
7993

80-
return longHashing != null ? new CaffeineCSC(cb.build(), longHashing) : new CaffeineCSC(cb.build());
94+
return longHashing != null
95+
? new CaffeineCSC(cb.build(), longHashing, cacheable)
96+
: new CaffeineCSC(cb.build(), cacheable);
8197
}
8298
}
8399
}

0 commit comments

Comments
 (0)