Skip to content

Commit 8b0913a

Browse files
committed
Redis doesn't do the BLMOVE check when the initial key does not exist.
1 parent 407a80c commit 8b0913a

File tree

2 files changed

+44
-41
lines changed

2 files changed

+44
-41
lines changed

libs/server/Objects/ItemBroker/CollectionItemBroker.cs

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,10 @@ private static unsafe bool TryGetNextSetObjects(byte[] key, SortedSetObject sort
427427
}
428428
}
429429

430+
/// <summary>
431+
/// Try to get available item(s) from sorted set object based on command type and arguments
432+
/// When run from initializer (initial = true), can return WRONGTYPE errors
433+
/// </summary>
430434
private unsafe bool TryGetResult(byte[] key, StorageSession storageSession,
431435
RespCommand command, ArgSlice[] cmdArgs, bool initial,
432436
out int currCount, out CollectionItemResult result)
@@ -442,13 +446,13 @@ private unsafe bool TryGetResult(byte[] key, StorageSession storageSession,
442446
_ => throw new NotSupportedException()
443447
};
444448

449+
var asKey = storageSession.scratchBufferManager.CreateArgSlice(key);
445450
ArgSlice dstKey = default;
446451
if (command == RespCommand.BLMOVE)
447452
{
448453
dstKey = cmdArgs[0];
449454
}
450455

451-
var asKey = storageSession.scratchBufferManager.CreateArgSlice(key);
452456
// Create a transaction if not currently in a running transaction
453457
if (storageSession.txnManager.state != TxnState.Running)
454458
{
@@ -470,8 +474,6 @@ private unsafe bool TryGetResult(byte[] key, StorageSession storageSession,
470474

471475
var lockableContext = storageSession.txnManager.LockableContext;
472476
var objectLockableContext = storageSession.txnManager.ObjectStoreLockableContext;
473-
IGarnetObject dstObj = null;
474-
byte[] arrDstKey = default;
475477

476478
try
477479
{
@@ -482,42 +484,18 @@ private unsafe bool TryGetResult(byte[] key, StorageSession storageSession,
482484
if (!initial)
483485
return false;
484486

487+
// Check the string store as well to see if WRONGTYPE should be returned.
485488
statusOp = storageSession.GET(asKey, out ArgSlice _, ref lockableContext);
486489

487490
if (statusOp != GarnetStatus.NOTFOUND)
488491
{
489492
result = new CollectionItemResult(GarnetStatus.WRONGTYPE);
490-
return true;
491-
}
492-
493-
if (command == RespCommand.BLMOVE)
494-
{
495-
arrDstKey = dstKey.ToArray();
496-
var dstStatusOp = storageSession.GET(arrDstKey, out var osDstObject, ref objectLockableContext);
497-
if (dstStatusOp != GarnetStatus.NOTFOUND && osDstObject.GarnetObject is not ListObject)
498-
{
499-
result = new CollectionItemResult(GarnetStatus.WRONGTYPE);
500-
return true;
501-
}
502-
503-
dstStatusOp = storageSession.GET(dstKey, out ArgSlice _, ref lockableContext);
504-
if (dstStatusOp != GarnetStatus.NOTFOUND)
505-
{
506-
result = new CollectionItemResult(GarnetStatus.WRONGTYPE);
507-
return true;
508-
}
493+
return initial;
509494
}
510495

511496
return false;
512497
}
513498

514-
if (command == RespCommand.BLMOVE)
515-
{
516-
arrDstKey = dstKey.ToArray();
517-
var dstStatusOp = storageSession.GET(arrDstKey, out var osDstObject, ref objectLockableContext);
518-
if (dstStatusOp != GarnetStatus.NOTFOUND) dstObj = osDstObject.GarnetObject;
519-
}
520-
521499
// Check for type match between the observer and the actual object type
522500
// If types match, get next item based on item type
523501
switch (osObject.GarnetObject)
@@ -541,21 +519,46 @@ private unsafe bool TryGetResult(byte[] key, StorageSession storageSession,
541519
result = new CollectionItemResult(key, nextItem);
542520
break;
543521
case RespCommand.BLMOVE:
522+
var arrDstKey = dstKey.ToArray();
523+
var dstStatusOp = storageSession.GET(arrDstKey, out var osDstObject, ref objectLockableContext);
524+
544525
ListObject dstList;
545526
var newObj = false;
546-
if (dstObj == null)
547-
{
548-
dstList = new ListObject();
549-
newObj = true;
550-
}
551-
else if (dstObj is ListObject tmpDstList)
527+
528+
if (dstStatusOp != GarnetStatus.NOTFOUND)
552529
{
553-
dstList = tmpDstList;
530+
var dstObj = osDstObject.GarnetObject;
531+
532+
if (dstObj == null)
533+
{
534+
dstList = new ListObject();
535+
newObj = true;
536+
}
537+
else if (dstObj is ListObject tmpDstList)
538+
{
539+
dstList = tmpDstList;
540+
}
541+
else
542+
{
543+
result = new CollectionItemResult(GarnetStatus.WRONGTYPE);
544+
return initial;
545+
}
554546
}
555547
else
556548
{
557-
result = new CollectionItemResult(GarnetStatus.WRONGTYPE);
558-
return initial;
549+
if (initial)
550+
{
551+
// Check string store for wrongtype errors on initial run.
552+
dstStatusOp = storageSession.GET(dstKey, out ArgSlice _, ref lockableContext);
553+
if (dstStatusOp != GarnetStatus.NOTFOUND)
554+
{
555+
result = new CollectionItemResult(GarnetStatus.WRONGTYPE);
556+
return initial;
557+
}
558+
}
559+
560+
dstList = new ListObject();
561+
newObj = true;
559562
}
560563

561564
isSuccessful = TryMoveNextListItem(listObj, dstList, (OperationDirection)cmdArgs[1].ReadOnlySpan[0],

test/Garnet.test/RespBlockingCollectionTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -656,16 +656,16 @@ public void PopWrongTypeTest()
656656
response = lightClientRequest.SendCommand("BLMOVE set foo RIGHT RIGHT 0");
657657
TestUtils.AssertEqualUpToExpectedLength(expectedResponse, response);
658658

659-
response = lightClientRequest.SendCommand("BLMOVE foo key LEFT LEFT 0");
659+
response = lightClientRequest.SendCommand("BLMOVE list set LEFT LEFT 0");
660660
TestUtils.AssertEqualUpToExpectedLength(expectedResponse, response);
661661

662-
response = lightClientRequest.SendCommand("BLMOVE foo set LEFT LEFT 0");
662+
response = lightClientRequest.SendCommand("BLMOVE list key LEFT LEFT 0");
663663
TestUtils.AssertEqualUpToExpectedLength(expectedResponse, response);
664664

665665
response = lightClientRequest.SendCommand("BRPOPLPUSH key foo 0");
666666
TestUtils.AssertEqualUpToExpectedLength(expectedResponse, response);
667667

668-
response = lightClientRequest.SendCommand("BRPOPLPUSH foo key 0");
668+
response = lightClientRequest.SendCommand("BRPOPLPUSH list key 0");
669669
TestUtils.AssertEqualUpToExpectedLength(expectedResponse, response);
670670

671671
response = lightClientRequest.SendCommand("BLPOP key 0");

0 commit comments

Comments
 (0)