Skip to content
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

Merged
merged 2 commits into from
Apr 4, 2022

Conversation

ringles
Copy link
Contributor

@ringles ringles commented Feb 28, 2022

GEODE-9953: Implement LTRIM Command

Implements the Redis LTRIM command using the new versioning scheme.

@jdeppe-pivotal jdeppe-pivotal added the redis Issues related to the geode-for-redis module label Mar 1, 2022
Comment on lines 177 to 240
synchronized (this) {
if (version != this.version) {
elementsRemove(indexes);
}
this.version = version;
Copy link
Contributor

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.

@ringles ringles force-pushed the GEODE-9953-Implement-LTRIM-command branch 3 times, most recently from ce67f72 to 266c68e Compare March 10, 2022 23:14
@ringles ringles marked this pull request as ready for review March 11, 2022 13:03
assertThat(jedis.llen(key)).isEqualTo(elementCount);
elementCount--;
i++;
} catch (Exception ex) {
Copy link
Contributor

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);
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

@ringles ringles force-pushed the GEODE-9953-Implement-LTRIM-command branch from 5be5ea3 to 737659d Compare March 22, 2022 14:39
Copy link
Contributor

@DonalEvans DonalEvans left a 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);
Copy link
Contributor

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++) {
Copy link
Contributor

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.

Comment on lines 160 to 166
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);
Copy link
Contributor

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.

Comment on lines 37 to 38
Region<RedisKey, RedisData> region = context.getRegion();
RedisKey key = command.getKey();
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minorly updated.

Comment on lines 40 to 45
long start;
long end;

try {
start = Coder.bytesToLong(commandElems.get(startIndex));
end = Coder.bytesToLong(commandElems.get(stopIndex));
Copy link
Contributor

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.

Copy link
Contributor Author

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() {
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Comment on lines 209 to 192
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);
});
Copy link
Contributor

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).

Copy link
Contributor Author

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.

Comment on lines +71 to +72
// Remove all but last element
jedis.ltrim(key, INITIAL_LIST_SIZE - 1, INITIAL_LIST_SIZE);
Copy link
Contributor

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.

Copy link
Contributor Author

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);
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworked

Comment on lines 151 to 153
jedis.ltrim(key, 0, lastElementIndex - 1);
assertThat(jedis.llen(key)).as("Key: %s ", key).isEqualTo(lastElementIndex);
lastElementIndex--;
Copy link
Contributor

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.

Copy link
Contributor Author

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.)

@ringles ringles force-pushed the GEODE-9953-Implement-LTRIM-command branch from c6e8e66 to f5779ea Compare March 23, 2022 21:33
Copy link
Contributor

@nonbinaryprogrammer nonbinaryprogrammer left a 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.

@ringles ringles force-pushed the GEODE-9953-Implement-LTRIM-command branch from 4266dda to 7bf0499 Compare March 28, 2022 14:18
Copy link
Contributor

@jdeppe-pivotal jdeppe-pivotal left a 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...

Comment on lines 146 to 158
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());
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exceptions thrown by the asserts 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;
        }

Copy link
Contributor Author

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.

@lgtm-com
Copy link

lgtm-com bot commented Mar 28, 2022

This pull request fixes 1 alert when merging ac9b48b into dfedcbd - view on LGTM.com

fixed alerts:

  • 1 for Spurious Javadoc @param tags

@lgtm-com
Copy link

lgtm-com bot commented Mar 29, 2022

This pull request fixes 1 alert when merging 18c118a into 41844a5 - view on LGTM.com

fixed alerts:

  • 1 for Spurious Javadoc @param tags

Copy link
Contributor

@DonalEvans DonalEvans left a 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.

Comment on lines +265 to +281
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;
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 230 to 263
* @return the element actually popped
*/
public byte[] ltrim(long start, long end, Region<RedisKey, RedisData> region,
Copy link
Contributor

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.

Comment on lines 305 to 313
private int getBoundedEndIndex(long index, int size) {
if (index >= 0L) {
return (int) Math.min(index, size);
} else {
return (int) Math.max(index + size, -1);
}
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

Comment on lines 282 to 289
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);
}
Copy link
Contributor

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);

Copy link
Contributor Author

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) {
Copy link
Contributor

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.

Copy link
Contributor Author

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);
Copy link
Contributor

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.

Copy link
Contributor Author

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 {
Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Contributor

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

Comment on lines 275 to 287
if (boundedStart == 0 && boundedEnd == length) {
// No-op, return without modifying the list
return null;
}
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Comment on lines 144 to 162
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();
}
Copy link
Contributor

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();
      }

Copy link
Contributor Author

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++) {
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conditionalized.

Copy link
Contributor

@DonalEvans DonalEvans left a 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.

Comment on lines 290 to 298
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) {
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tweaked.

@lgtm-com
Copy link

lgtm-com bot commented Mar 30, 2022

This pull request fixes 1 alert when merging 69ef004 into f3b9636 - view on LGTM.com

fixed alerts:

  • 1 for Spurious Javadoc @param tags

@lgtm-com
Copy link

lgtm-com bot commented Mar 31, 2022

This pull request fixes 1 alert when merging 9202fef into 6806179 - view on LGTM.com

fixed alerts:

  • 1 for Spurious Javadoc @param tags

@SuppressWarnings("unused")
private Object[] getRangesForOneElementList() {
// Values are start, end, expected
// For initial list of {e4, e3, e2, e1}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is incorrect

Copy link
Contributor Author

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.

Comment on lines 292 to 294
return (int) Math.min(index, size);
} else {
return (int) Math.max(index + size, 0);
Copy link
Contributor

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().

Copy link
Contributor Author

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);
Copy link
Contributor

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.

Copy link
Contributor Author

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});
Copy link
Contributor

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?

Copy link
Contributor Author

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 {
Copy link
Contributor

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

@lgtm-com
Copy link

lgtm-com bot commented Apr 1, 2022

This pull request fixes 1 alert when merging fc2fd52 into 5dce03c - view on LGTM.com

fixed alerts:

  • 1 for Spurious Javadoc @param tags

@ringles ringles force-pushed the GEODE-9953-Implement-LTRIM-command branch from 2495f07 to f64db77 Compare April 1, 2022 18:28
@lgtm-com
Copy link

lgtm-com bot commented Apr 1, 2022

This pull request fixes 1 alert when merging f64db77 into 4a73cb7 - view on LGTM.com

fixed alerts:

  • 1 for Spurious Javadoc @param tags

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<>();
Copy link
Contributor

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.

@ringles ringles merged commit 3cc3bdb into apache:develop Apr 4, 2022
@ringles ringles deleted the GEODE-9953-Implement-LTRIM-command branch April 4, 2022 19:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
redis Issues related to the geode-for-redis module
Projects
None yet
5 participants