Skip to content

Commit 739b917

Browse files
mp911dechristophstrobl
authored andcommitted
Add popFirst and popLast methods to RedisZSet.
See #2007 Original Pull Request: #2088
1 parent 0f2039d commit 739b917

File tree

3 files changed

+177
-0
lines changed

3 files changed

+177
-0
lines changed

src/main/java/org/springframework/data/redis/support/collections/DefaultRedisZSet.java

+65
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Iterator;
2020
import java.util.NoSuchElementException;
2121
import java.util.Set;
22+
import java.util.concurrent.TimeUnit;
2223

2324
import org.springframework.data.redis.connection.DataType;
2425
import org.springframework.data.redis.connection.RedisZSetCommands.Limit;
@@ -380,6 +381,38 @@ public E first() {
380381
throw new NoSuchElementException();
381382
}
382383

384+
/*
385+
* (non-Javadoc)
386+
* @see org.springframework.data.redis.support.collections.RedisZSet#popFirst()
387+
*/
388+
@Override
389+
public E popFirst() {
390+
391+
TypedTuple<E> tuple = boundZSetOps.popMin();
392+
393+
if (tuple != null) {
394+
return tuple.getValue();
395+
}
396+
397+
throw new NoSuchElementException();
398+
}
399+
400+
/*
401+
* (non-Javadoc)
402+
* @see org.springframework.data.redis.support.collections.RedisZSet#popFirst(long, java.util.concurrent.TimeUnit)
403+
*/
404+
@Override
405+
public E popFirst(long timeout, TimeUnit unit) {
406+
407+
TypedTuple<E> tuple = boundZSetOps.popMin(timeout, unit);
408+
409+
if (tuple != null) {
410+
return tuple.getValue();
411+
}
412+
413+
throw new NoSuchElementException();
414+
}
415+
383416
/*
384417
* (non-Javadoc)
385418
* @see org.springframework.data.redis.support.collections.RedisZSet#last()
@@ -397,6 +430,38 @@ public E last() {
397430
throw new NoSuchElementException();
398431
}
399432

433+
/*
434+
* (non-Javadoc)
435+
* @see org.springframework.data.redis.support.collections.RedisZSet#popLast()
436+
*/
437+
@Override
438+
public E popLast() {
439+
440+
TypedTuple<E> tuple = boundZSetOps.popMax();
441+
442+
if (tuple != null) {
443+
return tuple.getValue();
444+
}
445+
446+
throw new NoSuchElementException();
447+
}
448+
449+
/*
450+
* (non-Javadoc)
451+
* @see org.springframework.data.redis.support.collections.RedisZSet#popLast(long, java.util.concurrent.TimeUnit)
452+
*/
453+
@Override
454+
public E popLast(long timeout, TimeUnit unit) {
455+
456+
TypedTuple<E> tuple = boundZSetOps.popMax(timeout, unit);
457+
458+
if (tuple != null) {
459+
return tuple.getValue();
460+
}
461+
462+
throw new NoSuchElementException();
463+
}
464+
400465
/*
401466
* (non-Javadoc)
402467
* @see org.springframework.data.redis.support.collections.RedisZSet#rank(java.lang.Object)

src/main/java/org/springframework/data/redis/support/collections/RedisZSet.java

+45
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.NoSuchElementException;
2222
import java.util.Set;
2323
import java.util.SortedSet;
24+
import java.util.concurrent.TimeUnit;
2425

2526
import org.springframework.data.redis.connection.RedisZSetCommands.Limit;
2627
import org.springframework.data.redis.connection.RedisZSetCommands.Range;
@@ -217,6 +218,28 @@ default boolean addIfAbsent(E e) {
217218
*/
218219
E first();
219220

221+
/**
222+
* Removes the first (lowest) object at the top of this sorted set and returns that object as the value of this
223+
* function.
224+
*
225+
* @return the first (lowest) element currently in this sorted set.
226+
* @throws NoSuchElementException sorted set is empty.
227+
* @since 2.6
228+
*/
229+
E popFirst();
230+
231+
/**
232+
* Removes the first (lowest) object at the top of this sorted set and returns that object as the value of this
233+
* function. <b>Blocks connection</b> until element available or {@code timeout} reached.
234+
*
235+
* @param timeout
236+
* @param unit must not be {@literal null}.
237+
* @return the first (lowest) element currently in this sorted set.
238+
* @throws NoSuchElementException sorted set is empty.
239+
* @since 2.6
240+
*/
241+
E popFirst(long timeout, TimeUnit unit);
242+
220243
/**
221244
* Returns the last (highest) element currently in this sorted set.
222245
*
@@ -225,6 +248,28 @@ default boolean addIfAbsent(E e) {
225248
*/
226249
E last();
227250

251+
/**
252+
* Removes the last (highest) object at the top of this sorted set and returns that object as the value of this
253+
* function.
254+
*
255+
* @return the last (highest) element currently in this sorted set.
256+
* @throws NoSuchElementException sorted set is empty.
257+
* @since 2.6
258+
*/
259+
E popLast();
260+
261+
/**
262+
* Removes the last (highest) object at the top of this sorted set and returns that object as the value of this
263+
* function. <b>Blocks connection</b> until element available or {@code timeout} reached.
264+
*
265+
* @param timeout
266+
* @param unit must not be {@literal null}.
267+
* @return the last (highest) element currently in this sorted set.
268+
* @throws NoSuchElementException sorted set is empty.
269+
* @since 2.6
270+
*/
271+
E popLast(long timeout, TimeUnit unit);
272+
228273
/**
229274
* @since 1.4
230275
* @return

src/test/java/org/springframework/data/redis/support/collections/AbstractRedisZSetTestIntegration.java

+67
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Iterator;
2424
import java.util.NoSuchElementException;
2525
import java.util.Set;
26+
import java.util.concurrent.TimeUnit;
2627

2728
import org.assertj.core.data.Offset;
2829
import org.junit.jupiter.api.BeforeEach;
@@ -37,6 +38,7 @@
3738
import org.springframework.data.redis.core.Cursor;
3839
import org.springframework.data.redis.core.RedisTemplate;
3940
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
41+
import org.springframework.data.redis.test.condition.EnabledOnCommand;
4042
import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest;
4143

4244
/**
@@ -119,13 +121,46 @@ void testFirst() {
119121
assertThat(zSet.first()).isEqualTo(t1);
120122
}
121123

124+
@ParameterizedRedisTest
125+
@EnabledOnCommand("ZPOPMIN")
126+
void testPopFirst() {
127+
128+
T t1 = getT();
129+
T t2 = getT();
130+
T t3 = getT();
131+
132+
zSet.add(t1, 3);
133+
zSet.add(t2, 4);
134+
zSet.add(t3, 5);
135+
136+
assertThat(zSet.popFirst()).isEqualTo(t1);
137+
assertThat(zSet).hasSize(2);
138+
}
139+
140+
@ParameterizedRedisTest
141+
@EnabledOnCommand("ZPOPMIN")
142+
void testPopFirstWithTimeout() {
143+
144+
T t1 = getT();
145+
T t2 = getT();
146+
T t3 = getT();
147+
148+
zSet.add(t1, 3);
149+
zSet.add(t2, 4);
150+
zSet.add(t3, 5);
151+
152+
assertThat(zSet.popFirst(1, TimeUnit.SECONDS)).isEqualTo(t1);
153+
assertThat(zSet).hasSize(2);
154+
}
155+
122156
@ParameterizedRedisTest
123157
void testFirstException() {
124158
assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(() -> zSet.first());
125159
}
126160

127161
@ParameterizedRedisTest
128162
void testLast() {
163+
129164
T t1 = getT();
130165
T t2 = getT();
131166
T t3 = getT();
@@ -138,6 +173,38 @@ void testLast() {
138173
assertThat(zSet.last()).isEqualTo(t3);
139174
}
140175

176+
@ParameterizedRedisTest
177+
@EnabledOnCommand("ZPOPMAX")
178+
void testPopLast() {
179+
180+
T t1 = getT();
181+
T t2 = getT();
182+
T t3 = getT();
183+
184+
zSet.add(t1, 3);
185+
zSet.add(t2, 4);
186+
zSet.add(t3, 5);
187+
188+
assertThat(zSet.popLast()).isEqualTo(t3);
189+
assertThat(zSet).hasSize(2);
190+
}
191+
192+
@ParameterizedRedisTest
193+
@EnabledOnCommand("ZPOPMAX")
194+
void testPopLastWithTimeout() {
195+
196+
T t1 = getT();
197+
T t2 = getT();
198+
T t3 = getT();
199+
200+
zSet.add(t1, 3);
201+
zSet.add(t2, 4);
202+
zSet.add(t3, 5);
203+
204+
assertThat(zSet.popLast(1, TimeUnit.SECONDS)).isEqualTo(t3);
205+
assertThat(zSet).hasSize(2);
206+
}
207+
141208
@ParameterizedRedisTest
142209
void testLastException() {
143210
assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(() -> zSet.last());

0 commit comments

Comments
 (0)