redisson
基于 org.redisson:redisson-spring-data-27:3.27.2
版本
在 java
中,操作 redis
一般都会选择 redisson
框架, 我们需要了解常用功能的实现原理, 这次来介绍 RedissonSortedSet
。
使用方式
1
2
3
4
5
6
7
8
9
10
11
| @Test
void testOrderedSet() {
RSortedSet<String> set = redissonClient.getSortedSet("set");
set.clear();
set.add("3");
set.add("2");
set.add("1");
for (String s : set.readAll()) {
System.out.println(s);
}
}
|
RedissonSortedSet
是通过 list
数据结构来实现的。但如果 value
是 string
类型的,可以使用 RedissonLexSortedSet
来优化操作。
add
源码位置: org.redisson.RedissonSortedSet#add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| @Override
public boolean add(V value) {
// 加分布式锁,防止并发
lock.lock();
try {
// 通过二分法查找插入位置
BinarySearchResult<V> res = binarySearch(value, codec);
if (res.getIndex() < 0) {
int index = -(res.getIndex() + 1);
// 编码
ByteBuf encodedValue = encode(value);
// 执行 lua 脚本,插入元素
commandExecutor.get(commandExecutor.evalWriteNoRetryAsync(list.getRawName(), codec, RedisCommands.EVAL_VOID,
"local len = redis.call('llen', KEYS[1]);"
+ "if tonumber(ARGV[1]) < len then "
// 获取插入位置的元素值
+ "local pivot = redis.call('lindex', KEYS[1], ARGV[1]);"
// 插入值
+ "redis.call('linsert', KEYS[1], 'before', pivot, ARGV[2]);"
+ "return;"
+ "end;"
+ "redis.call('rpush', KEYS[1], ARGV[2]);", Arrays.<Object>asList(list.getRawName()), index, encodedValue));
return true;
} else {
return false;
}
} finally {
lock.unlock();
}
}
|