-
Notifications
You must be signed in to change notification settings - Fork 683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GEODE-9953: Implement LTRIM Command #7403
GEODE-9953: Implement LTRIM Command #7403
Conversation
synchronized (this) { | ||
if (version != this.version) { | ||
elementsRemove(indexes); | ||
} | ||
this.version = version; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There shouldn't be any need to synchronize here since this is a delta application and there will be locking at the Geode level to protect the entry. I think this should just be:
< Deleted 'cos I'm an idiot>
You want to update the version to match the change being applied. Similarly in applyAddByteArrayVersionedDelta
.
ce67f72
to
266c68e
Compare
assertThat(jedis.llen(key)).isEqualTo(elementCount); | ||
elementCount--; | ||
i++; | ||
} catch (Exception ex) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want a failing assertion to stop this loop (and thus the test) you'll have to catch a Throwable
here. Prefer rather to add an .as
clause to the assertion with the details you're adding to the RuntimeException and just rethrow the caught exception.
assertThat(length).isCloseTo(ITERATION_COUNT * 2 * PUSH_LIST_SIZE, within(6L)); | ||
assertThat(length % 3).isEqualTo(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this assertion can be exact and shouldn't need the offset.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, this assertion should not be using isCloseTo()
since we should not be seeing duplicated commands here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have seen failures, but that was an earlier version. Ran a bunch of these without failures, so I'm making it exact.
...edis/src/main/java/org/apache/geode/redis/internal/commands/executor/list/LTrimExecutor.java
Outdated
Show resolved
Hide resolved
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisList.java
Show resolved
Hide resolved
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisList.java
Outdated
Show resolved
Hide resolved
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisList.java
Outdated
Show resolved
Hide resolved
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisList.java
Outdated
Show resolved
Hide resolved
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisList.java
Outdated
Show resolved
Hide resolved
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisList.java
Outdated
Show resolved
Hide resolved
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisList.java
Show resolved
Hide resolved
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisSet.java
Outdated
Show resolved
Hide resolved
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisSet.java
Outdated
Show resolved
Hide resolved
...ava/org/apache/geode/redis/internal/commands/executor/list/AbstractLTrimIntegrationTest.java
Outdated
Show resolved
Hide resolved
...ava/org/apache/geode/redis/internal/commands/executor/list/AbstractLTrimIntegrationTest.java
Outdated
Show resolved
Hide resolved
...ava/org/apache/geode/redis/internal/commands/executor/list/AbstractLTrimIntegrationTest.java
Outdated
Show resolved
Hide resolved
...edis/src/main/java/org/apache/geode/redis/internal/commands/executor/list/LTrimExecutor.java
Outdated
Show resolved
Hide resolved
...edis/src/main/java/org/apache/geode/redis/internal/commands/executor/list/LTrimExecutor.java
Outdated
Show resolved
Hide resolved
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisList.java
Outdated
Show resolved
Hide resolved
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisSet.java
Outdated
Show resolved
Hide resolved
5be5ea3
to
737659d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR should also add LTRIM to the list of supported commands in geode_for_redis.html.md.erb
assertThat(length).isCloseTo(ITERATION_COUNT * 2 * PUSH_LIST_SIZE, within(6L)); | ||
assertThat(length % 3).isEqualTo(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, this assertion should not be using isCloseTo()
since we should not be seeing duplicated commands here.
assertThat(length % 3).isEqualTo(0); | ||
validateListContents(key, length, keyToElementListMap); | ||
} | ||
} | ||
|
||
private void lpushPerformAndVerify(String key, List<String> elementList, | ||
AtomicLong runningCount) { | ||
for (int i = 0; i < MINIMUM_ITERATIONS; i++) { | ||
for (int i = 0; i < ITERATION_COUNT; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than having this test always do a fixed number of LPUSH operations and moving buckets while they're ongoing, it would be better to have a fixed number of bucket moves performed (25 seems like a reasonable number) and have LPUSH happening continuously until those bucket moves are finished, since what we really want to test here is how LPUSH behaves when we move buckets, so we should make sure that we always do the same number of bucket moves.
This can be achieved by replacing the for loop in this method with a while loop, having an AtomicBoolean
rather than an AtomicInteger
as the condition (named something like continueRunning maybe), and setting that AtomicBoolean
to false after the for loop that moves buckets completes. A similar approach is used in LInsertDUnitTest
.
length = jedis.llen(key); | ||
while (length > 0) { | ||
List<String> elementList = keyToElementListMap.get(key); | ||
assertThat(jedis.lpop(key)).isEqualTo(elementList.get(2)); | ||
assertThat(jedis.lpop(key)).isEqualTo(elementList.get(1)); | ||
assertThat(jedis.lpop(key)).isEqualTo(elementList.get(0)); | ||
length = jedis.llen(key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change seems unnecessary. It would probably be better to just remove length
from the method signature and keep the while loop as it was.
Region<RedisKey, RedisData> region = context.getRegion(); | ||
RedisKey key = command.getKey(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor performance improvement, but these lines should be moved to below the try/catch as it's possible we return from this method before needing them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minorly updated.
long start; | ||
long end; | ||
|
||
try { | ||
start = Coder.bytesToLong(commandElems.get(startIndex)); | ||
end = Coder.bytesToLong(commandElems.get(stopIndex)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having these values be long
here but then casting them to int
inside the ltrim()
method could potentially lead to overflows, so it might be safer to wrap these calls to bytesToLong()
in narrowLongToInt()
to safely convert from long
to int
and have the values be int
throughout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Demoted.
} | ||
|
||
@Test | ||
public void removesKey_whenLastElementRemoved_multipleTimes() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not super clear on what this test is showing, since we already have a test that shows that the key is removed if all elements are trimmed, and a test that shows the behaviour when LTRIM is called on a non-existent key. I think this can probably just be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, really only there during development for TDD.
final AtomicReference<String> lpopReference = new AtomicReference<>(); | ||
new ConcurrentLoopingThreads(1000, | ||
i -> jedis.lpush(KEY, valuesToAdd), | ||
i -> jedis.ltrim(KEY, 0, 2), | ||
i -> lpopReference.set(jedis.lpop(KEY))) | ||
.runWithAction(() -> { | ||
assertThat(lpopReference).satisfiesAnyOf( | ||
lpopResult -> assertThat(lpopReference.get()).isEqualTo("orange"), | ||
lpopResult -> assertThat(lpopReference.get()).isEqualTo("troix")); | ||
jedis.del(KEY); | ||
jedis.lpush(KEY, valuesInitial); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The call to LPOP here should be removed, since we're not trying to test the concurrent behaviour of LPUSH, LTRIM and LPOP. With the test as it is, we could do the push, then do the pop, then do the trim, which is not what we're trying to test.
Instead, we should be calling LRANGE in the runWithAction
lambda and asserting that the contents of the list is either {"un", "deux", "trois"}
if the LPUSH happened first or {"plum", "peach", "orange"}
if the LTRIM happened first (but with the elements in reverse order, because LPUSH likes to complicate things).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the test was written, we didn't have LRANGE. Reworked.
// Remove all but last element | ||
jedis.ltrim(key, INITIAL_LIST_SIZE - 1, INITIAL_LIST_SIZE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make this test a bit more robust, it would be good to select start and end indexes such that we remove some elements from the start and some elements form the end of the list. That way we're checking that we're using both start and end indexes correctly in the Delta that we send.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Significantly reworked.
|
||
@Test | ||
public void givenBucketsMoveDuringLtrim_thenOperationsAreNotLost() throws Exception { | ||
AtomicLong runningCount = new AtomicLong(3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test would be better if instead of running until we've done a certain number of LTRIM calls, we instead do constant LTRIM calls until we've done a certain number of bucket moves. The LRemDUnitTest that does bucket moves that's being added as part of the LREM PR is a great example of how we want to be approaching these sort of tests, I think, so it could be helpful to use it as a guide.
The basic idea is that we do our operation constantly until we're finished moving buckets, but since LTRIM removes elements, we need to reset the list to its initial state once it's been emptied, then continue calling LTRIM. That way we can be sure that we do enough bucket moves to make the test consistent and useful, without having to worry that we run out of elements to trim.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reworked
jedis.ltrim(key, 0, lastElementIndex - 1); | ||
assertThat(jedis.llen(key)).as("Key: %s ", key).isEqualTo(lastElementIndex); | ||
lastElementIndex--; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we choose indexes for start and end here so that we're keeping some middle part of the list instead of just trimming the last element? That way we make sure that we're exercising the whole of the Delta that we send, not just the end index. Maybe just trim the first and last elements?
Also, it would be good to assert on the entire contents of the list (using LRANGE) rather than just the size, as we want to make sure that we're not removing the wrong elements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got a test that removes the first and last each step, and verifies the values along the way. (Didn't have LRANGE when the test was first written.)
c6e8e66
to
f5779ea
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not re-review all the changes, but the concerns/suggestions that I raised have been addressed. I am on vacation next week so I'm going to go ahead and approve so that my review doesn't hold up merging.
4266dda
to
7bf0499
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. One minor optional suggestion...
try { | ||
assertThat(jedis.lindex(key, 0)).isEqualTo(makeElementString(key, INITIAL_LIST_SIZE - i)); | ||
assertThat(jedis.lindex(key, lastIndex)).isEqualTo(makeElementString(key, i)); | ||
jedis.ltrim(key, 1, lastIndex); | ||
assertThat(jedis.llen(key)).as("Key: %s ", key).isEqualTo(lastIndex); | ||
} catch (Exception ex) { | ||
isRunning.set(false); // test is over | ||
throw new RuntimeException("Exception performing LTRIM for list '" | ||
+ key + "' at step " + i + ": " + ex.getMessage()); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exceptions thrown by the assert
s won't be caught by the catch
block and so won't stop the test. Not critical, but you could change this to:
try {
assertThat(jedis.lindex(key, 0))
.as("lpush head verification failed at iteration " + i)
.isEqualTo(makeElementString(key, INITIAL_LIST_SIZE - i));
assertThat(jedis.lindex(key, lastIndex))
.as("lpush tail verification failed at iteration " + i)
.isEqualTo(makeElementString(key, i));
jedis.ltrim(key, 1, lastIndex);
assertThat(jedis.llen(key)).as("Key: %s ", key).isEqualTo(lastIndex);
} catch (Throwable ex) {
isRunning.set(false); // test is over
throw ex;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I get what you mean by the throwable comment earlier. Done.
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisList.java
Outdated
Show resolved
Hide resolved
This pull request fixes 1 alert when merging ac9b48b into dfedcbd - view on LGTM.com fixed alerts:
|
This pull request fixes 1 alert when merging 18c118a into 41844a5 - view on LGTM.com fixed alerts:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR also needs to update the docs in geode_for_redis.html.md.erb. The README.md file is intended for developers, not users (and I'm pretty sure we have a story somewhere to just delete it) so it doesn't really need to be updated with every supported command, since a developer could just look in RedisCommandType
.
int length = elementList.size(); | ||
int boundedStart = getBoundedStartIndex(start, length); | ||
int boundedEnd = getBoundedEndIndex(end, length); | ||
|
||
if (boundedStart > boundedEnd || boundedStart == length) { | ||
// Remove everything | ||
region.remove(key); | ||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth adding an implementation of ltrim()
to NullRedisList
that just returns immediately, since then we can avoid doing these steps. I'm not sure how expensive a call to region.remove()
for a non-existent key is, but it's probably worth avoiding if we can.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
* @return the element actually popped | ||
*/ | ||
public byte[] ltrim(long start, long end, Region<RedisKey, RedisData> region, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the method return type being Void
here would still be a nice improvement, since it's misleading to imply that a byte[]
is returned when this method always returns null
. Also, start
and end
are now passed in as int
, so the method signature (and the signatures of getBoundedStartIndex()
and getBoundedEndIndex()
) should be changed to reflect that.
private int getBoundedEndIndex(long index, int size) { | ||
if (index >= 0L) { | ||
return (int) Math.min(index, size); | ||
} else { | ||
return (int) Math.max(index + size, -1); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is still inconsistent, since for a list of size n
, passing in n
as the index returns a different value than passing in -1
, when they should be equivalent. This can lead to us failing to hit the early return in ltrim()
when the operation is a no-op and sending a delta that we don't need to.
This method should return the exclusive index to be used in clearSublist()
so that we can be consistent with how Java deals with indexes and not have to add 1 to the value before passing it into other methods, i.e. it should return size -1
if the index passed to it is greater than or equal to size
, or if the index is -1
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
if (boundedEnd < length) { | ||
// trim stuff at end of list | ||
elementList.clearSublist(boundedEnd + 1, length); | ||
} | ||
if (boundedStart > 0) { | ||
// trim stuff at start of list | ||
elementList.clearSublist(0, boundedStart); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To prevent code duplication, this should probably be replaced with elementsRetainByIndexRange(boundedStart, boundedEnd);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
De-duped.
@@ -83,6 +83,39 @@ | |||
return indexesRemoved; | |||
} | |||
|
|||
public void clearSublist(int fromIndex, int toIndex) { | |||
if (fromIndex < size() / 2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This attempt at optimization is not working the way you intend, I think. For a list of 100 elements with fromIndex = 49
, toIndex = 100
, you end up starting at the beginning of the list and iterating all 100 elements, rather than starting at the end and only having to iterate 51. The correct optimization would be to check which of fromIndex
and toIndex
is closer to its respective end of the list, and then clear from that side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optimized.
public void removesKey_whenAllElementsTrimmed() { | ||
initializeTestList(); | ||
|
||
jedis.ltrim(KEY, 0, -5); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test could be expanded to "removesKey_whenRangeIsEmpty()" and parameterized to use various ranges that do not contain any elements e.g. both start and end are past the end of the list, both start and end are before the start of the list etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parameterized.
import org.apache.geode.test.junit.runners.GeodeParamsRunner; | ||
|
||
@RunWith(GeodeParamsRunner.class) | ||
public abstract class AbstractLTrimIntegrationTest implements RedisIntegrationTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To help catch potential edge cases, could we have a parameterized test for the behaviour when the list contains only one element? I added some trace logging and played around a bit and noticed that there was some inconsistent/unexpected behaviour when the list contains only one element that it would be good to explicitly test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you think of more cases to add to the new trimsToSpecifiedRange_givenListWithOneElement() test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What you have looks comprehensive to me
if (boundedStart == 0 && boundedEnd == length) { | ||
// No-op, return without modifying the list | ||
return null; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be nice to add a test to RedisListTest.java
to confirm that we hit this early return under various conditions, as I noticed that for lists with just one element, we were still sending a delta in some situations even though the list wasn't modified at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking this in tests now.
for (int i = 1; i <= INITIAL_LIST_SIZE / 2 && isRunning.get(); i++) { | ||
long lastIndex = jedis.llen(key) - 2; | ||
try { | ||
assertThat(jedis.lindex(key, 0)) | ||
.as("lpush head verification failed at iteration " + i) | ||
.isEqualTo(makeElementString(key, INITIAL_LIST_SIZE - i)); | ||
assertThat(jedis.lindex(key, lastIndex)) | ||
.as("lpush tail verification failed at iteration " + i) | ||
.isEqualTo(makeElementString(key, i)); | ||
jedis.ltrim(key, 1, lastIndex); | ||
assertThat(jedis.llen(key)).as("Key: %s ", key).isEqualTo(lastIndex); | ||
} catch (Throwable ex) { | ||
isRunning.set(false); // test is over | ||
throw ex; | ||
} | ||
} | ||
if (isRunning.get()) { | ||
assertThat(jedis.exists(key)).isFalse(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be simplified somewhat by using negative indexes and doing the assertions after performing LTRIM (since we already assert on the contents of the list as part of lpushPerformAndVerify()
so we should never see the list be wrong before we've even done an LTRIM):
for (int i = 1; i < INITIAL_LIST_SIZE / 2 && isRunning.get(); i++) {
try {
jedis.ltrim(key, 1, -2);
assertThat(jedis.llen(key)).as("Key: %s ", key).isEqualTo(INITIAL_LIST_SIZE - (i * 2L));
assertThat(jedis.lindex(key, 0))
.as("LTRIM head verification failed at iteration " + i)
.isEqualTo(makeElementString(key, INITIAL_LIST_SIZE - 1 - i));
assertThat(jedis.lindex(key, -1))
.as("LTRIM tail verification failed at iteration " + i)
.isEqualTo(makeElementString(key, i));
} catch (Throwable ex) {
isRunning.set(false); // test is over
throw ex;
}
}
if (isRunning.get()) {
jedis.ltrim(key, 1, -2);
assertThat(jedis.exists(key)).isFalse();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reworked.
Future<Void> future2 = executor.runAsync(task2); | ||
Future<Void> future3 = executor.runAsync(task3); | ||
|
||
for (int i = 0; i < 100; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in order to have the test stop early if ltrimPerformAndVerify()
encounters an exception, you need to also include a check for isRunning.get()
in the for loop condition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conditionalized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docs (not the README) still need to be updated to include LTRIM in this PR.
private int getBoundedStartIndex(long index, int size) { | ||
if (index >= 0L) { | ||
return (int) Math.min(index, size); | ||
} else { | ||
return (int) Math.max(index + size, 0); | ||
} | ||
} | ||
|
||
private int getBoundedEndIndex(long index, int size) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
index
in these two methods is always an int
so the method signatures should be updated to reflect this and then the casts to int
in the method can be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tweaked.
This pull request fixes 1 alert when merging 69ef004 into f3b9636 - view on LGTM.com fixed alerts:
|
This pull request fixes 1 alert when merging 9202fef into 6806179 - view on LGTM.com fixed alerts:
|
@SuppressWarnings("unused") | ||
private Object[] getRangesForOneElementList() { | ||
// Values are start, end, expected | ||
// For initial list of {e4, e3, e2, e1} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is incorrect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yanked, since it's pretty simple for a one-element list.
return (int) Math.min(index, size); | ||
} else { | ||
return (int) Math.max(index + size, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These casts are now redundant and can be removed, as are the ones in getBoundedEndIndex()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Swept away.
RedisList list = createRedisListWithDuplicateElements(); | ||
|
||
byte originalVersion = list.getVersion(); | ||
list.ltrim(0, 5, region, null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make it more obvious what this is doing, could the end index be -1
? That way, regardless of the size of the list, we're guaranteed to always do a no-op.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
private RedisList createRedisListWithOneElement(int e1) { | ||
RedisList newList = new RedisList(); | ||
newList.elementPushHead(new byte[] {(byte) e1}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For simplicity, could this method just take a byte[]
as the argument rather than an int that we then have to fiddle with to put into the list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we don't care about the contents of the element, now there's no arg at all.
import org.apache.geode.test.junit.runners.GeodeParamsRunner; | ||
|
||
@RunWith(GeodeParamsRunner.class) | ||
public abstract class AbstractLTrimIntegrationTest implements RedisIntegrationTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What you have looks comprehensive to me
This pull request fixes 1 alert when merging fc2fd52 into 5dce03c - view on LGTM.com fixed alerts:
|
2495f07
to
f64db77
Compare
This pull request fixes 1 alert when merging f64db77 into 4a73cb7 - view on LGTM.com fixed alerts:
|
jedis.lpush(KEY, valuesInitial); | ||
List<String> valuesInitialReversed = new ArrayList<>(Arrays.asList("trois", "deux", "un")); | ||
List<String> valuesToAddReversed = new ArrayList<>(Arrays.asList("orange", "peach", "plum")); | ||
final AtomicReference<String> lpopReference = new AtomicReference<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This variable is unused and should be removed.
GEODE-9953: Implement LTRIM Command
Implements the Redis LTRIM command using the new versioning scheme.