/** * Creates an unbounded replay subject with the bounded-implementation for testing purposes. * <p> * This variant behaves like the regular unbounded {@code ReplaySubject} created via {@link #create()} but * uses the structures of the bounded-implementation. This is by no means intended for the replacement of * the original, array-backed and unbounded {@code ReplaySubject} due to the additional overhead of the * linked-list based internal buffer. The sole purpose is to allow testing and reasoning about the behavior * of the bounded implementations without the interference of the eviction policies. * * @param <T> * the type of items observed and emitted by the Subject * @return the created subject */ /* test */ static <T> ReplaySubject<T> createUnbounded() { return new ReplaySubject<T>(new SizeBoundReplayBuffer<T>(Integer.MAX_VALUE)); }
/** * Creates an unbounded replay subject with the bounded-implementation for testing purposes. * <p> * This variant behaves like the regular unbounded {@code ReplaySubject} created via {@link #create()} but * uses the structures of the bounded-implementation. This is by no means intended for the replacement of * the original, array-backed and unbounded {@code ReplaySubject} due to the additional overhead of the * linked-list based internal buffer. The sole purpose is to allow testing and reasoning about the behavior * of the bounded implementations without the interference of the eviction policies. * * @param <T> * the type of items observed and emitted by the Subject * @return the created subject */ /* test */ static <T> ReplaySubject<T> createUnbounded() { return new ReplaySubject<T>(new SizeBoundReplayBuffer<T>(Integer.MAX_VALUE)); }
/** * Creates an unbounded replay subject. * <p> * The internal buffer is backed by an {@link ArrayList} and starts with an initial capacity of 16. Once the * number of items reaches this capacity, it will grow as necessary (usually by 50%). However, as the * number of items grows, this causes frequent array reallocation and copying, and may hurt performance * and latency. This can be avoided with the {@link #create(int)} overload which takes an initial capacity * parameter and can be tuned to reduce the array reallocation frequency as needed. * * @param <T> * the type of items observed and emitted by the Subject * @return the created subject */ @CheckReturnValue @NonNull public static <T> ReplaySubject<T> create() { return new ReplaySubject<T>(new UnboundedReplayBuffer<T>(16)); }
/** * Creates an unbounded replay subject with the specified initial buffer capacity. * <p> * Use this method to avoid excessive array reallocation while the internal buffer grows to accommodate new * items. For example, if you know that the buffer will hold 32k items, you can ask the * {@code ReplaySubject} to preallocate its internal array with a capacity to hold that many items. Once * the items start to arrive, the internal array won't need to grow, creating less garbage and no overhead * due to frequent array-copying. * * @param <T> * the type of items observed and emitted by the Subject * @param capacityHint * the initial buffer capacity * @return the created subject */ @CheckReturnValue @NonNull public static <T> ReplaySubject<T> create(int capacityHint) { return new ReplaySubject<T>(new UnboundedReplayBuffer<T>(capacityHint)); }
/** * Creates a size-bounded replay subject. * <p> * In this setting, the {@code ReplaySubject} holds at most {@code size} items in its internal buffer and * discards the oldest item. * <p> * When observers subscribe to a terminated {@code ReplaySubject}, they are guaranteed to see at most * {@code size} {@code onNext} events followed by a termination event. * <p> * If an observer subscribes while the {@code ReplaySubject} is active, it will observe all items in the * buffer at that point in time and each item observed afterwards, even if the buffer evicts items due to * the size constraint in the mean time. In other words, once an Observer subscribes, it will receive items * without gaps in the sequence. * * @param <T> * the type of items observed and emitted by the Subject * @param maxSize * the maximum number of buffered items * @return the created subject */ @CheckReturnValue @NonNull public static <T> ReplaySubject<T> createWithSize(int maxSize) { return new ReplaySubject<T>(new SizeBoundReplayBuffer<T>(maxSize)); }
@NonNull public static <T> ReplaySubject<T> createWithTime(long maxAge, TimeUnit unit, Scheduler scheduler) { return new ReplaySubject<T>(new SizeAndTimeBoundReplayBuffer<T>(Integer.MAX_VALUE, maxAge, unit, scheduler));
@NonNull public static <T> ReplaySubject<T> createWithTimeAndSize(long maxAge, TimeUnit unit, Scheduler scheduler, int maxSize) { return new ReplaySubject<T>(new SizeAndTimeBoundReplayBuffer<T>(maxSize, maxAge, unit, scheduler));
/** * Creates an unbounded replay subject. * <p> * The internal buffer is backed by an {@link ArrayList} and starts with an initial capacity of 16. Once the * number of items reaches this capacity, it will grow as necessary (usually by 50%). However, as the * number of items grows, this causes frequent array reallocation and copying, and may hurt performance * and latency. This can be avoided with the {@link #create(int)} overload which takes an initial capacity * parameter and can be tuned to reduce the array reallocation frequency as needed. * * @param <T> * the type of items observed and emitted by the Subject * @return the created subject */ @CheckReturnValue @NonNull public static <T> ReplaySubject<T> create() { return new ReplaySubject<T>(new UnboundedReplayBuffer<T>(16)); }
/** * Creates an unbounded replay subject with the specified initial buffer capacity. * <p> * Use this method to avoid excessive array reallocation while the internal buffer grows to accommodate new * items. For example, if you know that the buffer will hold 32k items, you can ask the * {@code ReplaySubject} to preallocate its internal array with a capacity to hold that many items. Once * the items start to arrive, the internal array won't need to grow, creating less garbage and no overhead * due to frequent array-copying. * * @param <T> * the type of items observed and emitted by the Subject * @param capacityHint * the initial buffer capacity * @return the created subject */ @CheckReturnValue @NonNull public static <T> ReplaySubject<T> create(int capacityHint) { return new ReplaySubject<T>(new UnboundedReplayBuffer<T>(capacityHint)); }
/** * Creates a size-bounded replay subject. * <p> * In this setting, the {@code ReplaySubject} holds at most {@code size} items in its internal buffer and * discards the oldest item. * <p> * When observers subscribe to a terminated {@code ReplaySubject}, they are guaranteed to see at most * {@code size} {@code onNext} events followed by a termination event. * <p> * If an observer subscribes while the {@code ReplaySubject} is active, it will observe all items in the * buffer at that point in time and each item observed afterwards, even if the buffer evicts items due to * the size constraint in the mean time. In other words, once an Observer subscribes, it will receive items * without gaps in the sequence. * * @param <T> * the type of items observed and emitted by the Subject * @param maxSize * the maximum number of buffered items * @return the created subject */ @CheckReturnValue @NonNull public static <T> ReplaySubject<T> createWithSize(int maxSize) { return new ReplaySubject<T>(new SizeBoundReplayBuffer<T>(maxSize)); }
@NonNull public static <T> ReplaySubject<T> createWithTime(long maxAge, TimeUnit unit, Scheduler scheduler) { return new ReplaySubject<T>(new SizeAndTimeBoundReplayBuffer<T>(Integer.MAX_VALUE, maxAge, unit, scheduler));
@NonNull public static <T> ReplaySubject<T> createWithTimeAndSize(long maxAge, TimeUnit unit, Scheduler scheduler, int maxSize) { return new ReplaySubject<T>(new SizeAndTimeBoundReplayBuffer<T>(maxSize, maxAge, unit, scheduler));