DonalEvans commented on a change in pull request #7219:
URL: https://github.com/apache/geode/pull/7219#discussion_r778402027



##########
File path: 
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisSortedSet.java
##########
@@ -323,18 +339,48 @@ public long zinterstore(RegionProvider regionProvider, 
RedisKey key, List<ZKeyWe
           }
         }
       }
+
       if (addToSet) {
-        memberAdd(member, newScore);
+        OrderedSetEntry entry = interMembers.get(member);
+        if (entry == null) {
+          entry = new OrderedSetEntry(member, newScore);
+          interMembers.put(member, entry);
+          interScores.add(entry);
+        } else if (entry.getScore() != newScore) {
+          interScores.remove(entry);
+          entry.updateScore(newScore);
+          interScores.add(entry);
+        }
       }
     }
 
-    if (removeFromRegion()) {
-      regionProvider.getDataRegion().remove(key);
-    } else {
-      regionProvider.getLocalDataRegion().put(key, this);
+    return sortedSetOpStoreResult(regionProvider, key, interMembers, 
interScores);
+  }
+
+  @VisibleForTesting
+  static long sortedSetOpStoreResult(RegionProvider regionProvider, RedisKey 
destinationKey,
+      MemberMap interMembers, ScoreSet interScores) {
+    RedisSortedSet destinationSet =
+        regionProvider.getTypedRedisDataElseRemove(REDIS_SORTED_SET, 
destinationKey, false);

Review comment:
       The `getTypedRedisDataElseRemove()` method has a `TODO` on it saying it 
should be removed once SDIFFSTORE is merged. With its use here, I assume that 
is no longer correct. Could the comment be removed?

##########
File path: 
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisSortedSet.java
##########
@@ -323,18 +339,48 @@ public long zinterstore(RegionProvider regionProvider, 
RedisKey key, List<ZKeyWe
           }
         }
       }
+
       if (addToSet) {
-        memberAdd(member, newScore);
+        OrderedSetEntry entry = interMembers.get(member);
+        if (entry == null) {
+          entry = new OrderedSetEntry(member, newScore);
+          interMembers.put(member, entry);
+          interScores.add(entry);
+        } else if (entry.getScore() != newScore) {
+          interScores.remove(entry);
+          entry.updateScore(newScore);
+          interScores.add(entry);
+        }
       }
     }
 
-    if (removeFromRegion()) {
-      regionProvider.getDataRegion().remove(key);
-    } else {
-      regionProvider.getLocalDataRegion().put(key, this);
+    return sortedSetOpStoreResult(regionProvider, key, interMembers, 
interScores);
+  }
+
+  @VisibleForTesting
+  static long sortedSetOpStoreResult(RegionProvider regionProvider, RedisKey 
destinationKey,
+      MemberMap interMembers, ScoreSet interScores) {
+    RedisSortedSet destinationSet =
+        regionProvider.getTypedRedisDataElseRemove(REDIS_SORTED_SET, 
destinationKey, false);
+
+    if (interMembers == null || interScores.isEmpty()) {

Review comment:
       The LGTM warning here can be fixed either by making this:
   ```
   if (interMembers == null || interScores == null || interScores.isEmpty()) {
   ```
   or by changing it to:
   ```
   if (interMembers.isEmpty() || interScores.isEmpty()) {
   ```
   and changing the call to `sortedSetOpStoreResult()` on line 299 to pass an 
empty `MemberMap` and empty `ScoreSet` rather than `null`. I would tend to 
prefer the second approach, as avoiding passing null around is generally better.

##########
File path: 
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisSortedSet.java
##########
@@ -463,18 +509,24 @@ public long zrevrank(byte[] member) {
     return null;
   }
 
-  public long zunionstore(RegionProvider regionProvider, RedisKey key, 
List<ZKeyWeight> keyWeights,
+  public static long zunionstore(RegionProvider regionProvider, RedisKey key,
+      List<ZKeyWeight> keyWeights,
       ZAggregator aggregator) {
+    MemberMap unionMembers = null;
+    ScoreSet unionScores = null;
     for (ZKeyWeight keyWeight : keyWeights) {
       RedisSortedSet set =
           regionProvider.getTypedRedisData(REDIS_SORTED_SET, 
keyWeight.getKey(), false);
       if (set == NULL_REDIS_SORTED_SET) {
         continue;
+      } else if (unionMembers == null) {
+        unionMembers = new MemberMap((int) set.zcard());
+        unionScores = new ScoreSet();
       }
       double weight = keyWeight.getWeight();
 
       for (AbstractOrderedSetEntry entry : set.members.values()) {

Review comment:
       Minor thing, but the code in this for loop could be made a little more 
readable by changing the if to and if/else, removing the `continue` and having 
the if condition be `if (existingValue != null)`. This puts the smaller block 
of code at the top of the if statement, which improves readability, and makes 
it clear that there are two possible cases with two different behaviours rather 
than an if followed by other code, which could imply that the code outside the 
if is expected to execute regardless of how the if condition evaluates.

##########
File path: 
geode-for-redis/src/test/java/org/apache/geode/redis/internal/data/RedisSortedSetTest.java
##########
@@ -153,6 +157,58 @@ public void zadd_stores_delta_that_is_stable() {
     assertThat(sortedSet1.hasDelta()).isFalse();
   }
 
+  @Test
+  public void zstoreoperations_stores_delta_that_is_stable() {

Review comment:
       This test  and the one below it should probably be renamed 
"sortedSetOpStoreResult_*" as there is no method named "zstoreoperations".

##########
File path: 
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisSortedSet.java
##########
@@ -463,18 +509,24 @@ public long zrevrank(byte[] member) {
     return null;
   }
 
-  public long zunionstore(RegionProvider regionProvider, RedisKey key, 
List<ZKeyWeight> keyWeights,
+  public static long zunionstore(RegionProvider regionProvider, RedisKey key,
+      List<ZKeyWeight> keyWeights,
       ZAggregator aggregator) {
+    MemberMap unionMembers = null;
+    ScoreSet unionScores = null;

Review comment:
       Rather than declaring these as null and only assigning them if we find a 
set, I think it might be better to create them up front and avoid them ever 
being null when passed into `sortedSetOpStoreResult()`. While this doesn't 
allow an initial size to be set for `unionMembers`, that's not much of a loss 
of optimization, since even if we do use the first set we find to set an 
initial size, it's entirely possible that the initial size is far smaller than 
the final size and so we end up doing a bunch of resizes anyway.

##########
File path: 
geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/RedisSortedSet.java
##########
@@ -323,18 +339,48 @@ public long zinterstore(RegionProvider regionProvider, 
RedisKey key, List<ZKeyWe
           }
         }
       }
+
       if (addToSet) {
-        memberAdd(member, newScore);
+        OrderedSetEntry entry = interMembers.get(member);
+        if (entry == null) {

Review comment:
       This check will always return true, because we are iterating the 
contents of `smallestSet` (which we know doesn't contain any duplicate entries) 
and only adding to `interMembers` in one place, so it's not possible that it 
will already contain the member.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to