Skip to content

Commit

Permalink
use CursorId in ScanIteration to avoid long overflow
Browse files Browse the repository at this point in the history
 - Spring Data 3.3 deprecated `long cursorId` in favor of String-backed `CursorId` object to avoid `NumberFormatException` when then cursor ID is bigger than max long
 - more info: spring-projects/spring-data-redis#2796
  • Loading branch information
Vlastimil Kotas committed Nov 11, 2024
1 parent 2ae4f54 commit 370452a
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ public Cursor<byte[]> scan(RedisClusterNode node, ScanOptions options) {
private RedisClient client = getEntry(node);

@Override
protected ScanIteration<byte[]> doScan(long cursorId, ScanOptions options) {
protected ScanIteration<byte[]> doScan(CursorId cursorId, ScanOptions options) {
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'SSCAN' cannot be called in pipeline / transaction mode.");
}
Expand All @@ -399,7 +399,7 @@ protected ScanIteration<byte[]> doScan(long cursorId, ScanOptions options) {
}

List<Object> args = new ArrayList<Object>();
args.add(Long.toUnsignedString(cursorId));
args.add(cursorId);
if (options.getPattern() != null) {
args.add("MATCH");
args.add(options.getPattern());
Expand All @@ -413,11 +413,11 @@ protected ScanIteration<byte[]> doScan(long cursorId, ScanOptions options) {
ListScanResult<byte[]> res = syncFuture(f);
String pos = res.getPos();
client = res.getRedisClient();
if ("0".equals(pos)) {
if (CursorId.isInitial(pos)) {
client = null;
}

return new ScanIteration<byte[]>(Long.parseUnsignedLong(pos), res.getValues());
return new ScanIteration<byte[]>(CursorId.of(pos), res.getValues());
}
}.open();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,14 @@ public Set<byte[]> keys(byte[] pattern) {

@Override
public Cursor<byte[]> scan(ScanOptions options) {
return new ScanCursor<byte[]>(0, options) {
return new ScanCursor<byte[]>(Cursor.CursorId.initial(), options) {

private RedisClient client;
private Iterator<MasterSlaveEntry> entries = redisson.getConnectionManager().getEntrySet().iterator();
private MasterSlaveEntry entry = entries.next();

@Override
protected ScanIteration<byte[]> doScan(long cursorId, ScanOptions options) {
protected ScanIteration<byte[]> doScan(CursorId cursorId, ScanOptions options) {
if (isQueueing() || isPipelined()) {
throw new UnsupportedOperationException("'SSCAN' cannot be called in pipeline / transaction mode.");
}
Expand All @@ -269,10 +269,10 @@ protected ScanIteration<byte[]> doScan(long cursorId, ScanOptions options) {
}

List<Object> args = new ArrayList<Object>();
if (cursorId == 101010101010101010L) {
cursorId = 0;
if (CursorId.of("101010101010101010").equals(cursorId)) {
cursorId = CursorId.initial();
}
args.add(Long.toUnsignedString(cursorId));
args.add(cursorId);
if (options.getPattern() != null) {
args.add("MATCH");
args.add(options.getPattern());
Expand All @@ -286,7 +286,7 @@ protected ScanIteration<byte[]> doScan(long cursorId, ScanOptions options) {
ListScanResult<byte[]> res = syncFuture(f);
String pos = res.getPos();
client = res.getRedisClient();
if ("0".equals(pos)) {
if (CursorId.isInitial(pos)) {
if (entries.hasNext()) {
pos = "101010101010101010";
entry = entries.next();
Expand All @@ -296,7 +296,7 @@ protected ScanIteration<byte[]> doScan(long cursorId, ScanOptions options) {
}
}

return new ScanIteration<byte[]>(Long.parseUnsignedLong(pos), res.getValues());
return new ScanIteration<byte[]>(CursorId.of(pos), res.getValues());
}
}.open();
}
Expand Down

0 comments on commit 370452a

Please sign in to comment.