Skip to content

Commit 00bcbb3

Browse files
committed
ignore "_#RL#" and "_#TS#" prefix
1 parent 96ff47e commit 00bcbb3

File tree

4 files changed

+87
-6
lines changed

4 files changed

+87
-6
lines changed

jetcache-anno-api/src/main/java/com/alicp/jetcache/anno/KeyConvertor.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
/**
66
* Created on 2016/12/12.
77
*
8+
* A custom key convertor implements Function<Object, Object> is enough.
9+
* If a key convertor implements this interface, it can process byte[] and String, see AbstractExternalCache.
10+
*
811
* @author <a href="mailto:areyouok@gmail.com">huangli</a>
912
*/
1013
public interface KeyConvertor extends Function<Object, Object> {

jetcache-core/src/main/java/com/alicp/jetcache/RefreshCache.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
import org.slf4j.LoggerFactory;
88

99
import java.nio.ByteBuffer;
10-
import java.util.*;
10+
import java.util.ArrayList;
11+
import java.util.Arrays;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.Set;
1115
import java.util.concurrent.ConcurrentHashMap;
1216
import java.util.concurrent.ScheduledFuture;
1317
import java.util.concurrent.TimeUnit;
@@ -22,6 +26,9 @@ public class RefreshCache<K, V> extends LoadingCache<K, V> {
2226

2327
private static final Logger logger = LoggerFactory.getLogger(RefreshCache.class);
2428

29+
public static final byte[] LOCK_KEY_SUFFIX = "_#RL#".getBytes();
30+
public static final byte[] TIMESTAMP_KEY_SUFFIX = "_#TS#".getBytes();
31+
2532
private ConcurrentHashMap<Object, RefreshTask> taskMap = new ConcurrentHashMap<>();
2633

2734
private boolean multiLevelCache;
@@ -174,10 +181,10 @@ private void load() throws Throwable {
174181
private void externalLoad(final Cache concreteCache, final long currentTime)
175182
throws Throwable {
176183
byte[] newKey = ((AbstractExternalCache) concreteCache).buildKey(key);
177-
byte[] lockKey = combine(newKey, "_#RL#".getBytes());
184+
byte[] lockKey = combine(newKey, LOCK_KEY_SUFFIX);
178185
long loadTimeOut = RefreshCache.this.config.getRefreshPolicy().getRefreshLockTimeoutMillis();
179186
long refreshMillis = config.getRefreshPolicy().getRefreshMillis();
180-
byte[] timestampKey = combine(newKey, "_#TS#".getBytes());
187+
byte[] timestampKey = combine(newKey, TIMESTAMP_KEY_SUFFIX);
181188

182189
// AbstractExternalCache buildKey method will not convert byte[]
183190
CacheGetResult refreshTimeResult = concreteCache.GET(timestampKey);

jetcache-core/src/main/java/com/alicp/jetcache/external/AbstractExternalCache.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.alicp.jetcache.AbstractCache;
44
import com.alicp.jetcache.CacheConfigException;
55
import com.alicp.jetcache.CacheException;
6+
import com.alicp.jetcache.RefreshCache;
67
import com.alicp.jetcache.anno.KeyConvertor;
78

89
import java.io.IOException;
@@ -28,7 +29,7 @@ protected void checkConfig() {
2829
if (config.getValueDecoder() == null) {
2930
throw new CacheConfigException("no value decoder");
3031
}
31-
if (config.getKeyPrefix() == null){
32+
if (config.getKeyPrefix() == null) {
3233
throw new CacheConfigException("keyPrefix is required");
3334
}
3435
}
@@ -38,8 +39,10 @@ public byte[] buildKey(K key) {
3839
Object newKey = key;
3940
if (config.getKeyConvertor() != null) {
4041
if (config.getKeyConvertor() instanceof KeyConvertor) {
41-
// since 2.7.3 KeyConvertor extends Function<Object, Object>
42-
newKey = config.getKeyConvertor().apply(key);
42+
if (!isPreservedKey(key)) {
43+
// since 2.7.3 KeyConvertor extends Function<Object, Object>
44+
newKey = config.getKeyConvertor().apply(key);
45+
}
4346
} else {
4447
// before 2.7.3, KeyConvertor is interface only place some constants.
4548
// "key convertor" is Function<Object, Object> and can't process byte[] and String
@@ -58,4 +61,27 @@ public byte[] buildKey(K key) {
5861
}
5962
}
6063

64+
private boolean isPreservedKey(Object key) {
65+
if (key instanceof byte[]) {
66+
byte[] keyBytes = (byte[]) key;
67+
return endWith(keyBytes, RefreshCache.LOCK_KEY_SUFFIX)
68+
|| endWith(keyBytes, RefreshCache.TIMESTAMP_KEY_SUFFIX);
69+
}
70+
return false;
71+
}
72+
73+
private boolean endWith(byte[] key, byte[] suffix) {
74+
int len = suffix.length;
75+
if (key.length < len) {
76+
return false;
77+
}
78+
int startPos = key.length - len;
79+
for (int i = 0; i < len; i++) {
80+
if (key[startPos + i] != suffix[i]) {
81+
return false;
82+
}
83+
}
84+
return true;
85+
}
86+
6187
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* Created on 2023/01/05.
3+
*/
4+
package com.alicp.jetcache.external;
5+
6+
import com.alicp.jetcache.RefreshCache;
7+
import com.alicp.jetcache.anno.KeyConvertor;
8+
import com.alicp.jetcache.support.Fastjson2KeyConvertor;
9+
import org.junit.jupiter.api.Test;
10+
11+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
12+
13+
/**
14+
* @author <a href="mailto:areyouok@gmail.com">huangli</a>
15+
*/
16+
public class ExternalCacheBuildKeyTest {
17+
@Test
18+
public void testBuildKey() {
19+
MockRemoteCache c = (MockRemoteCache) MockRemoteCacheBuilder.createMockRemoteCacheBuilder()
20+
.keyPrefix("")
21+
.buildCache();
22+
byte[] byteKey = new byte[]{1, 2, 3};
23+
String strKey = "123";
24+
assertArrayEquals(byteKey, c.buildKey(byteKey));
25+
assertArrayEquals(strKey.getBytes(), c.buildKey(strKey));
26+
27+
c.config().setKeyConvertor(Fastjson2KeyConvertor.INSTANCE);
28+
assertArrayEquals(byteKey, c.buildKey(byteKey));
29+
assertArrayEquals(strKey.getBytes(), c.buildKey(strKey));
30+
31+
String convertedKey = "456";
32+
c.config().setKeyConvertor((KeyConvertor) o -> convertedKey);
33+
assertArrayEquals(convertedKey.getBytes(), c.buildKey(byteKey));
34+
assertArrayEquals(convertedKey.getBytes(), c.buildKey(strKey));
35+
assertArrayEquals(convertedKey.getBytes(), c.buildKey("long long long str"));
36+
assertArrayEquals(convertedKey.getBytes(), c.buildKey(1));
37+
38+
strKey = "123" + new String(RefreshCache.LOCK_KEY_SUFFIX);
39+
assertArrayEquals(strKey.getBytes(), c.buildKey(strKey.getBytes()));
40+
strKey = "123" + new String(RefreshCache.TIMESTAMP_KEY_SUFFIX);
41+
assertArrayEquals(strKey.getBytes(), c.buildKey(strKey.getBytes()));
42+
strKey = "" + new String(RefreshCache.TIMESTAMP_KEY_SUFFIX);
43+
assertArrayEquals(strKey.getBytes(), c.buildKey(strKey.getBytes()));
44+
}
45+
}

0 commit comments

Comments
 (0)