Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix bug with application of max idle time (#176)
* add failing tests for lifo checkout order * add LifoQueue and use it in MemberSingle
- Loading branch information
1 parent
ae50abf
commit 5e5a4bc
Showing
4 changed files
with
154 additions
and
2 deletions.
There are no files selected for viewing
58 changes: 58 additions & 0 deletions
58
rxjava2-pool/src/main/java/org/davidmoten/rx/internal/LifoQueue.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package org.davidmoten.rx.internal; | ||
|
||
import java.util.concurrent.atomic.AtomicReference; | ||
|
||
import io.reactivex.annotations.NonNull; | ||
import io.reactivex.annotations.Nullable; | ||
|
||
/** | ||
* Thread-safe Last-In-First-Out queue. Current usage is multi-producer, single | ||
* consumer but LIFO use case doesn't seem to offer opportunity for performance | ||
* enhancements like the MpscLinkedQueue does for FIFO use case. | ||
* | ||
* @param <T> queued item type | ||
*/ | ||
public final class LifoQueue<T> { | ||
|
||
private final AtomicReference<Node<T>> head = new AtomicReference<>(); | ||
|
||
public void offer(@NonNull T t) { | ||
while (true) { | ||
Node<T> a = head.get(); | ||
Node<T> b = new Node<>(t, a); | ||
if (head.compareAndSet(a, b)) { | ||
return; | ||
} | ||
} | ||
} | ||
|
||
public @Nullable T poll() { | ||
Node<T> a = head.get(); | ||
if (a == null) { | ||
return null; | ||
} else { | ||
while (true) { | ||
if (head.compareAndSet(a, a.next)) { | ||
return a.value; | ||
} else { | ||
a = head.get(); | ||
} | ||
} | ||
} | ||
} | ||
|
||
public void clear() { | ||
head.set(null); | ||
} | ||
|
||
static final class Node<T> { | ||
final @NonNull T value; | ||
final @Nullable Node<T> next; | ||
|
||
Node(T value, Node<T> next) { | ||
this.value = value; | ||
this.next = next; | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
rxjava2-pool/src/test/java/org/davidmoten/rx/internal/LifoQueueTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package org.davidmoten.rx.internal; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertNull; | ||
|
||
import org.junit.Test; | ||
|
||
public class LifoQueueTest { | ||
|
||
@Test | ||
public void testIsLifo() { | ||
LifoQueue<Integer> q = new LifoQueue<>(); | ||
q.offer(1); | ||
q.offer(2); | ||
assertEquals(2, (int) q.poll()); | ||
assertEquals(1, (int) q.poll()); | ||
assertNull(q.poll()); | ||
} | ||
|
||
@Test | ||
public void testClear() { | ||
LifoQueue<Integer> q = new LifoQueue<>(); | ||
q.offer(1); | ||
q.offer(2); | ||
q.clear(); | ||
assertNull(q.poll()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters