DATAREDIS-746 - Add Zset intersect operation aggregation support.
We now support aggregation and weight options for ZINTERSTORE. We also encapsulate weights used for ZUNIONSTORE and ZINTERSTORE within a Weights value object. zSetOps.intersectAndStore(set1, Arrays.asList(set2, set3), out, Aggregate.MAX, Weights.of(1, 2, 1)); Related ticket: DATAREDIS-515. Original Pull Request: #314
This commit is contained in:
committed by
Christoph Strobl
parent
7d6524bace
commit
56a01625d5
@@ -844,6 +844,10 @@ public class RedisConnectionUnitTests {
|
||||
return delegate.zUnionStore(destKey, aggregate, weights, sets);
|
||||
}
|
||||
|
||||
public Long zUnionStore(byte[] destKey, Aggregate aggregate, Weights weights, byte[]... sets) {
|
||||
return delegate.zUnionStore(destKey, aggregate, weights, sets);
|
||||
}
|
||||
|
||||
public Long zInterStore(byte[] destKey, byte[]... sets) {
|
||||
return delegate.zInterStore(destKey, sets);
|
||||
}
|
||||
@@ -852,6 +856,10 @@ public class RedisConnectionUnitTests {
|
||||
return delegate.zInterStore(destKey, aggregate, weights, sets);
|
||||
}
|
||||
|
||||
public Long zInterStore(byte[] destKey, Aggregate aggregate, Weights weights, byte[]... sets) {
|
||||
return delegate.zInterStore(destKey, aggregate, weights, sets);
|
||||
}
|
||||
|
||||
public Cursor<Tuple> zScan(byte[] key, ScanOptions options) {
|
||||
return delegate.zScan(key, options);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.connection;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Weights;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link org.springframework.data.redis.connection.RedisZSetCommands.Weights}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class WeightsUnitTests {
|
||||
|
||||
@Test // DATAREDIS-746
|
||||
public void shouldCreateWeights() {
|
||||
|
||||
assertThat(Weights.of(1, 2, 3).toArray()).contains(1, 2, 3);
|
||||
assertThat(Weights.of(1, 2d, 3).toArray()).contains(1d, 2d, 3d);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-746
|
||||
public void shouldRejectCreationWithNull() {
|
||||
|
||||
assertThatThrownBy(() -> Weights.of((int[]) null)).isInstanceOf(IllegalArgumentException.class);
|
||||
assertThatThrownBy(() -> Weights.of((double[]) null)).isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-746
|
||||
public void shouldCreateEqualWeights() {
|
||||
|
||||
Weights weights = Weights.fromSetCount(3);
|
||||
assertThat(weights.getWeight(0)).isOne();
|
||||
assertThat(weights.getWeight(1)).isOne();
|
||||
assertThat(weights.getWeight(2)).isOne();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-746
|
||||
public void getShouldThrowIndexOutOfBoundsException() {
|
||||
|
||||
assertThatThrownBy(() -> Weights.fromSetCount(1).getWeight(1)).isInstanceOf(IndexOutOfBoundsException.class);
|
||||
assertThatThrownBy(() -> Weights.fromSetCount(1).getWeight(-1)).isInstanceOf(IndexOutOfBoundsException.class);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-746
|
||||
public void shouldMultiplyDouble() {
|
||||
|
||||
Weights weights = Weights.of(1, 2, 3).multiply(2.5);
|
||||
assertThat(weights.getWeight(0)).isEqualTo(2.5);
|
||||
assertThat(weights.getWeight(2)).isEqualTo(7.5);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-746
|
||||
public void shouldMultiplyInt() {
|
||||
|
||||
Weights weights = Weights.of(1, 2, 3).multiply(2);
|
||||
assertThat(weights.getWeight(0)).isEqualTo(2);
|
||||
assertThat(weights.getWeight(2)).isEqualTo(6);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
@@ -35,7 +36,9 @@ import org.springframework.data.redis.ConnectionFactoryTracker;
|
||||
import org.springframework.data.redis.ObjectFactory;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Limit;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Weights;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
@@ -484,6 +487,33 @@ public class DefaultReactiveZSetOperationsIntegrationTests<K, V> {
|
||||
StepVerifier.create(zSetOperations.range(destKey, new Range<>(0L, 100L))).expectNextCount(3).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-746
|
||||
public void unionAndStoreWithAggregation() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
K otherKey = keyFactory.instance();
|
||||
K destKey = keyFactory.instance();
|
||||
|
||||
V onlyInKey = valueFactory.instance();
|
||||
V shared = valueFactory.instance();
|
||||
V onlyInOtherKey = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, onlyInKey, 10)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, shared, 11)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(otherKey, onlyInOtherKey, 10)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(otherKey, shared, 11)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.unionAndStore(key, Collections.singleton(otherKey), destKey, Aggregate.SUM))
|
||||
.expectNext(3L).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.score(destKey, shared)).expectNext(22d).verifyComplete();
|
||||
|
||||
StepVerifier.create(
|
||||
zSetOperations.unionAndStore(key, Collections.singleton(otherKey), destKey, Aggregate.SUM, Weights.of(2, 1)))
|
||||
.expectNext(3L).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.score(destKey, shared)).expectNext(33d).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
public void intersectAndStore() {
|
||||
|
||||
@@ -507,7 +537,39 @@ public class DefaultReactiveZSetOperationsIntegrationTests<K, V> {
|
||||
StepVerifier.create(zSetOperations.range(destKey, new Range<>(0L, 5L))) //
|
||||
.expectNextCount(1) //
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-746
|
||||
public void intersectAndStoreWithAggregation() {
|
||||
|
||||
K key = keyFactory.instance();
|
||||
K otherKey = keyFactory.instance();
|
||||
K destKey = keyFactory.instance();
|
||||
|
||||
V onlyInKey = valueFactory.instance();
|
||||
V shared = valueFactory.instance();
|
||||
V onlyInOtherKey = valueFactory.instance();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(key, onlyInKey, 10)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(key, shared, 11)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.add(otherKey, onlyInOtherKey, 10)).expectNext(true).verifyComplete();
|
||||
StepVerifier.create(zSetOperations.add(otherKey, shared, 11)).expectNext(true).verifyComplete();
|
||||
|
||||
StepVerifier
|
||||
.create(zSetOperations.intersectAndStore(key, Collections.singletonList(otherKey), destKey, Aggregate.SUM))
|
||||
.expectNext(1L).expectComplete().verify();
|
||||
|
||||
StepVerifier.create(zSetOperations.score(destKey, shared)) //
|
||||
.expectNext(22d) //
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(zSetOperations.intersectAndStore(key, Collections.singletonList(otherKey), destKey,
|
||||
Aggregate.SUM, Weights.of(1, 2))).expectNext(1L).expectComplete().verify();
|
||||
|
||||
StepVerifier.create(zSetOperations.score(destKey, shared)) //
|
||||
.expectNext(33d) //
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-602
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.springframework.data.redis.LongAsStringObjectFactory;
|
||||
import org.springframework.data.redis.LongObjectFactory;
|
||||
import org.springframework.data.redis.ObjectFactory;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Weights;
|
||||
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
|
||||
import org.springframework.data.redis.test.util.MinimumRedisVersionRule;
|
||||
import org.springframework.test.annotation.IfProfileValue;
|
||||
@@ -394,9 +395,42 @@ public class DefaultZSetOperationsTests<K, V> {
|
||||
zSetOps.add(key1, value1, 4.0);
|
||||
zSetOps.add(key2, value1, 3.0);
|
||||
|
||||
int weight[] = { 1, 2 };
|
||||
zSetOps.unionAndStore(key1, Collections.singletonList(key2), key1, RedisZSetCommands.Aggregate.MAX,
|
||||
Weights.of(1, 2));
|
||||
|
||||
zSetOps.unionAndStore(key1, Collections.singletonList(key2), weight, key1, RedisZSetCommands.Aggregate.MAX);
|
||||
assertThat(zSetOps.score(key1, value1), closeTo(6.0, 0.1));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-746
|
||||
public void testZsetIntersectWithAggregate() {
|
||||
|
||||
K key1 = keyFactory.instance();
|
||||
K key2 = keyFactory.instance();
|
||||
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
|
||||
zSetOps.add(key1, value1, 1.0);
|
||||
zSetOps.add(key1, value2, 2.0);
|
||||
zSetOps.add(key2, value2, 3.0);
|
||||
|
||||
zSetOps.intersectAndStore(key1, Collections.singletonList(key2), key1, RedisZSetCommands.Aggregate.MIN);
|
||||
|
||||
assertThat(zSetOps.score(key1, value2), closeTo(2.0, 0.1));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-746
|
||||
public void testZsetIntersectWithAggregateWeights() {
|
||||
|
||||
K key1 = keyFactory.instance();
|
||||
K key2 = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
|
||||
zSetOps.add(key1, value1, 4.0);
|
||||
zSetOps.add(key2, value1, 3.0);
|
||||
|
||||
zSetOps.intersectAndStore(key1, Collections.singletonList(key2), key1, RedisZSetCommands.Aggregate.MAX,
|
||||
Weights.of(1, 2));
|
||||
|
||||
assertThat(zSetOps.score(key1, value1), closeTo(6.0, 0.1));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user