36
36
import rx .concurrency .Schedulers ;
37
37
import rx .concurrency .TestScheduler ;
38
38
import rx .subscriptions .Subscriptions ;
39
+ import rx .util .BufferClosing ;
40
+ import rx .util .BufferClosings ;
41
+ import rx .util .BufferOpening ;
42
+ import rx .util .BufferOpenings ;
39
43
import rx .util .functions .Action0 ;
40
44
import rx .util .functions .Action1 ;
41
45
import rx .util .functions .Func0 ;
@@ -346,6 +350,15 @@ public Subscription call(final Observer<List<T>> observer) {
346
350
};
347
351
}
348
352
353
+ /**
354
+ * This {@link BufferObserver} object can be constructed using a {@link Buffers} object,
355
+ * a {@link Observer} object, and a {@link BufferCreator} object. The {@link BufferCreator}
356
+ * will manage the creation, and in some rare cases emission of internal {@link Buffer} objects
357
+ * in the specified {@link Buffers} object. Under normal circumstances the {@link Buffers}
358
+ * object specifies when a created {@link Buffer} is emitted.
359
+ *
360
+ * @param <T> The type of object all internal {@link Buffer} objects record.
361
+ */
349
362
private static class BufferObserver <T > implements Observer <T > {
350
363
351
364
private final Buffers <T > buffers ;
@@ -379,11 +392,31 @@ public void onNext(T args) {
379
392
}
380
393
}
381
394
395
+ /**
396
+ * This interface defines a way which specifies when to create a new internal {@link Buffer} object.
397
+ *
398
+ * @param <T> The type of object all internal {@link Buffer} objects record.
399
+ */
382
400
private interface BufferCreator <T > {
401
+ /**
402
+ * Signifies a onNext event.
403
+ */
383
404
void onValuePushed ();
405
+
406
+ /**
407
+ * Signifies a onCompleted or onError event. Should be used to clean up open
408
+ * subscriptions and other still running background tasks.
409
+ */
384
410
void stop ();
385
411
}
386
412
413
+ /**
414
+ * This {@link BufferCreator} creates a new {@link Buffer} when it is initialized, but
415
+ * provides no additional functionality. This class should primarily be used when the
416
+ * internal {@link Buffer} is closed externally.
417
+ *
418
+ * @param <T> The type of object all internal {@link Buffer} objects record.
419
+ */
387
420
private static class SingleBufferCreator <T > implements BufferCreator <T > {
388
421
389
422
public SingleBufferCreator (Buffers <T > buffers ) {
@@ -401,6 +434,13 @@ public void stop() {
401
434
}
402
435
}
403
436
437
+ /**
438
+ * This {@link BufferCreator} creates a new {@link Buffer} whenever it receives an
439
+ * object from the provided {@link Observable} created with the
440
+ * bufferClosingSelector {@link Func0}.
441
+ *
442
+ * @param <T> The type of object all internal {@link Buffer} objects record.
443
+ */
404
444
private static class ObservableBasedSingleBufferCreator <T > implements BufferCreator <T > {
405
445
406
446
private final AtomicObservableSubscription subscription = new AtomicObservableSubscription ();
@@ -437,11 +477,19 @@ public void stop() {
437
477
}
438
478
}
439
479
480
+ /**
481
+ * This {@link BufferCreator} creates a new {@link Buffer} whenever it receives
482
+ * an object from the provided bufferOpenings {@link Observable}, and closes the corresponding
483
+ * {@link Buffer} object when it receives an object from the provided {@link Observable} created
484
+ * with the bufferClosingSelector {@link Func1}.
485
+ *
486
+ * @param <T> The type of object all internal {@link Buffer} objects record.
487
+ */
440
488
private static class ObservableBasedMultiBufferCreator <T > implements BufferCreator <T > {
441
489
442
490
private final AtomicObservableSubscription subscription = new AtomicObservableSubscription ();
443
491
444
- public ObservableBasedMultiBufferCreator (final Buffers <T > buffers , Observable <BufferOpening > bufferOpenings , final Func1 <BufferOpening , Observable <BufferClosing >> bufferClosingSelector ) {
492
+ public ObservableBasedMultiBufferCreator (final OverlappingBuffers <T > buffers , Observable <BufferOpening > bufferOpenings , final Func1 <BufferOpening , Observable <BufferClosing >> bufferClosingSelector ) {
445
493
subscription .wrap (bufferOpenings .subscribe (new Action1 <BufferOpening >() {
446
494
@ Override
447
495
public void call (BufferOpening opening ) {
@@ -469,6 +517,12 @@ public void stop() {
469
517
}
470
518
}
471
519
520
+ /**
521
+ * This {@link BufferCreator} creates a new {@link Buffer} every time after a fixed
522
+ * period of time has elapsed.
523
+ *
524
+ * @param <T> The type of object all internal {@link Buffer} objects record.
525
+ */
472
526
private static class TimeBasedBufferCreator <T > implements BufferCreator <T > {
473
527
474
528
private final AtomicObservableSubscription subscription = new AtomicObservableSubscription ();
@@ -502,6 +556,12 @@ public void stop() {
502
556
}
503
557
}
504
558
559
+ /**
560
+ * This {@link BufferCreator} creates a new {@link Buffer} every time after it has
561
+ * seen a certain amount of elements.
562
+ *
563
+ * @param <T> The type of object all internal {@link Buffer} objects record.
564
+ */
505
565
private static class SkippingBufferCreator <T > implements BufferCreator <T > {
506
566
507
567
private final AtomicInteger skipped = new AtomicInteger (1 );
@@ -527,6 +587,12 @@ public void stop() {
527
587
}
528
588
}
529
589
590
+ /**
591
+ * This class is an extension on the {@link Buffers} class which only supports one
592
+ * active (not yet emitted) internal {@link Buffer} object.
593
+ *
594
+ * @param <T> The type of object all internal {@link Buffer} objects record.
595
+ */
530
596
private static class NonOverlappingBuffers <T > extends Buffers <T > {
531
597
532
598
private final Object lock = new Object ();
@@ -550,13 +616,27 @@ public void pushValue(T value) {
550
616
}
551
617
}
552
618
619
+ /**
620
+ * This class is an extension on the {@link Buffers} class which actually has no additional
621
+ * behavior than its super class. Classes extending this class, are expected to support
622
+ * two or more active (not yet emitted) internal {@link Buffer} objects.
623
+ *
624
+ * @param <T> The type of object all internal {@link Buffer} objects record.
625
+ */
553
626
private static class OverlappingBuffers <T > extends Buffers <T > {
554
-
555
627
public OverlappingBuffers (Observer <List <T >> observer ) {
556
628
super (observer );
557
629
}
558
630
}
559
631
632
+ /**
633
+ * This class is an extension on the {@link Buffers} class. Every internal buffer has
634
+ * a has a maximum time to live and a maximum internal capacity. When the buffer has
635
+ * reached the end of its life, or reached its maximum internal capacity it is
636
+ * automatically emitted.
637
+ *
638
+ * @param <T> The type of object all internal {@link Buffer} objects record.
639
+ */
560
640
private static class TimeAndSizeBasedBuffers <T > extends Buffers <T > {
561
641
562
642
private final ConcurrentMap <Buffer <T >, Subscription > subscriptions = new ConcurrentHashMap <Buffer <T >, Subscription >();
@@ -615,6 +695,13 @@ public void pushValue(T value) {
615
695
}
616
696
}
617
697
698
+ /**
699
+ * This class is an extension on the {@link Buffers} class. Every internal buffer has
700
+ * a has a maximum time to live. When the buffer has reached the end of its life it is
701
+ * automatically emitted.
702
+ *
703
+ * @param <T> The type of object all internal {@link Buffer} objects record.
704
+ */
618
705
private static class TimeBasedBuffers <T > extends OverlappingBuffers <T > {
619
706
620
707
private final ConcurrentMap <Buffer <T >, Subscription > subscriptions = new ConcurrentHashMap <Buffer <T >, Subscription >();
@@ -649,6 +736,13 @@ public void emitBuffer(Buffer<T> buffer) {
649
736
}
650
737
}
651
738
739
+ /**
740
+ * This class is an extension on the {@link Buffers} class. Every internal buffer has
741
+ * a fixed maximum capacity. When the buffer has reached its maximum capacity it is
742
+ * automatically emitted.
743
+ *
744
+ * @param <T> The type of object all internal {@link Buffer} objects record.
745
+ */
652
746
private static class SizeBasedBuffers <T > extends Buffers <T > {
653
747
654
748
private final int size ;
@@ -674,28 +768,55 @@ public void pushValue(T value) {
674
768
}
675
769
}
676
770
771
+ /**
772
+ * This class represents an object which contains and manages multiple {@link Buffer} objects.
773
+ *
774
+ * @param <T> The type of objects which the internal {@link Buffer} objects record.
775
+ */
677
776
private static class Buffers <T > {
678
777
679
778
private final Queue <Buffer <T >> buffers = new ConcurrentLinkedQueue <Buffer <T >>();
680
779
private final Observer <List <T >> observer ;
681
780
781
+ /**
782
+ * Constructs a new {@link Buffers} object for the specified {@link Observer}.
783
+ *
784
+ * @param observer
785
+ * The {@link Observer} to which this object will emit its internal
786
+ * {@link Buffer} objects to when requested.
787
+ */
682
788
public Buffers (Observer <List <T >> observer ) {
683
789
this .observer = observer ;
684
790
}
685
791
792
+ /**
793
+ * This method will instantiate a new {@link Buffer} object and register it internally.
794
+ *
795
+ * @return
796
+ * The constructed empty {@link Buffer} object.
797
+ */
686
798
public Buffer <T > createBuffer () {
687
799
Buffer <T > buffer = new Buffer <T >();
688
800
buffers .add (buffer );
689
801
return buffer ;
690
802
}
691
803
804
+ /**
805
+ * This method emits all not yet emitted {@link Buffer} objects.
806
+ */
692
807
public void emitAllBuffers () {
693
808
Buffer <T > buffer ;
694
809
while ((buffer = buffers .poll ()) != null ) {
695
810
observer .onNext (buffer .getContents ());
696
811
}
697
812
}
698
813
814
+ /**
815
+ * This method emits the specified {@link Buffer} object.
816
+ *
817
+ * @param buffer
818
+ * The {@link Buffer} to emit.
819
+ */
699
820
public void emitBuffer (Buffer <T > buffer ) {
700
821
if (!buffers .remove (buffer )) {
701
822
// Concurrency issue: Buffer is already emitted!
@@ -704,10 +825,20 @@ public void emitBuffer(Buffer<T> buffer) {
704
825
observer .onNext (buffer .getContents ());
705
826
}
706
827
828
+ /**
829
+ * @return
830
+ * The oldest (in case there are multiple) {@link Buffer} object.
831
+ */
707
832
public Buffer <T > getBuffer () {
708
833
return buffers .peek ();
709
834
}
710
835
836
+ /**
837
+ * This method pushes a value to all not yet emitted {@link Buffer} objects.
838
+ *
839
+ * @param value
840
+ * The value to push to all not yet emitted {@link Buffer} objects.
841
+ */
711
842
public void pushValue (T value ) {
712
843
List <Buffer <T >> copy = new ArrayList <Buffer <T >>(buffers );
713
844
for (Buffer <T > buffer : copy ) {
@@ -716,47 +847,34 @@ public void pushValue(T value) {
716
847
}
717
848
}
718
849
850
+ /**
851
+ * This class represents a single buffer: A sequence of recorded values.
852
+ *
853
+ * @param <T> The type of objects which this {@link Buffer} can hold.
854
+ */
719
855
private static class Buffer <T > {
720
856
private final List <T > contents = new ArrayList <T >();
721
857
858
+ /**
859
+ * Appends a specified value to the {@link Buffer}.
860
+ *
861
+ * @param value
862
+ * The value to append to the {@link Buffer}.
863
+ */
722
864
public void pushValue (T value ) {
723
865
contents .add (value );
724
866
}
725
867
868
+ /**
869
+ * @return
870
+ * The mutable underlying {@link List} which contains all the
871
+ * recorded values in this {@link Buffer} object.
872
+ */
726
873
public List <T > getContents () {
727
874
return contents ;
728
875
}
729
876
}
730
877
731
- public interface BufferOpening {
732
- // Tagging interface for objects which can open buffers.
733
- }
734
-
735
- public interface BufferClosing {
736
- // Tagging interface for objects which can close buffers.
737
- }
738
-
739
- public static class BufferOpenings {
740
-
741
- public static BufferOpening create () {
742
- return new BufferOpening () {};
743
- }
744
-
745
- private BufferOpenings () {
746
- // Prevent instantation.
747
- }
748
- }
749
- public static class BufferClosings {
750
-
751
- public static BufferClosing create () {
752
- return new BufferClosing () {};
753
- }
754
-
755
- private BufferClosings () {
756
- // Prevent instantation.
757
- }
758
- }
759
-
760
878
public static class UnitTest {
761
879
762
880
private Observer <List <String >> observer ;
0 commit comments