33
44import java .util .ArrayList ;
55import java .util .Collection ;
6- import java .util .List ;
76import java .util .function .BiConsumer ;
8- import java .util .function .BiFunction ;
97import java .util .function .Function ;
108import java .util .stream .Collectors ;
119
1210public final class Ops {
1311
14- private Ops () {}
12+ private Ops () {
13+ }
1514
16- public static <I , O > ComputerOp <I , O > asComputer (final Function <I , O > op ,
17- final BiConsumer <O , O > copy )
18- {
15+ public static <I , O > ComputerOp <I , O > asComputer (final Function <I , O > op , final BiConsumer <O , O > copy ) {
1916 return (in , out ) -> {
2017 final O temp = op .apply (in );
2118 copy .accept (temp , out );
2219 };
2320 }
24- public <IO > ComputerOp <IO , IO > asComputer (final InplaceOp <IO > op ,
25- final BiConsumer <IO , IO > copy )
26- {
21+
22+ public <IO > ComputerOp <IO , IO > asComputer (final InplaceOp <IO > op , final BiConsumer <IO , IO > copy ) {
2723 return (in , out ) -> {
2824 copy .accept (in , out );
2925 op .accept (out );
3026 };
3127 }
32- // TODO: add more adapters! Yay!
33-
34- // TODO: consider whether (some of?) these should be service methods,
35- // for extensibility. Or better: plugins of type OpAdapter. Later!
36- // E.g.: expressing tree-reduce as a function may depend on type details.
37- // net.imagej.ops.map ops are a special case for e.g. IterableInterval.
38-
39- public static <I , O > Function <Collection <I >, O > asFunction (
40- final TreeReduceOp <I , O > op )
41- {
42- return in -> {
43- final BiFunction <O , I , O > acc = op .accumulator ();
44- final O zero = op .createZero (in .iterator ().next ());
45- // TODO: use spliterator for multi-threading and use combiner
46- in .stream ().forEach (e -> acc .apply (zero , e ));
47- return zero ;
48- };
49- }
5028
51- public <IO , F extends InplaceOp <IO > & OutputAware <IO , IO >> Function <IO , IO >
52- asFunction (final F op , final BiConsumer <IO , IO > copy )
53- {
29+ public <IO , F extends InplaceOp <IO > & OutputAware <IO , IO >> Function <IO , IO > asFunction (final F op ,
30+ final BiConsumer <IO , IO > copy ) {
5431 return in -> {
5532 IO o = op .createOutput (in );
5633 copy .accept (in , o );
@@ -59,64 +36,65 @@ public static <I, O> Function<Collection<I>, O> asFunction(
5936 };
6037 }
6138
62- // FIXME: lame.
63- public static <I , O > Function <I , O > asFunction (final MapOp <I , O > op ) {
64- return new Function <I , O >() {
65- private List <O > out = new ArrayList <>(1 );
66-
67- @ Override
68- public O apply (final I in ) {
69- op .accept (in , in1 -> out .set (0 , in1 ));
70- return out .get (0 );
71- }};
39+ public static <I , O > Function <I , Collection <O >> asFunction (final FlatMapOp <I , O > op ) {
40+ return in -> {
41+ final ArrayList <O > out = new ArrayList <>();
42+ op .accept (in , (o ) -> out .add (o ));
43+ return out ;
44+ };
7245 }
7346
74- public static <I , O , OP extends ComputerOp <I , O > & OutputAware <I , O >>
75- Function <I , O > asFunction (final OP op )
76- {
47+ public static <I , O , OP extends ComputerOp <I , O > & OutputAware <I , O >> Function <I , O > asFunction (final OP op ) {
7748 return in -> {
7849 final O out = op .createOutput (in );
7950 op .accept (in , out );
8051 return out ;
8152 };
8253 }
8354
84- public static <I , O > MapOp <I , O > asMap (final Function <I , O > op ) {
55+ public static <I , O > FlatMapOp <I , O > asFlatMap (final Function <I , O > op ) {
8556 return (in , out ) -> out .accept (op .apply (in ));
8657 }
8758
88- // TODO: add more adapters! Yay!
59+ public static <I > InplaceOp <I > asInplace (Function <I , I > func , final BiConsumer <I , I > copy ) {
60+ return (in ) -> {
61+ final I res = func .apply (in );
62+ copy .accept (res , in );
63+ };
64+ }
65+
66+ public static <I > InplaceOp <I > asInplace (ComputerOp <I , I > func ) {
67+ return (in ) -> func .accept (in , in );
68+ }
8969
90- public static <I , O > Function <Collection <I >, Collection <O >> lift (
91- final Function <I , O > op )
92- {
70+ public static <I , C extends OutputAware <I , I > & ComputerOp <I , I >> InplaceOp <I > asInplace (C func ,
71+ final BiConsumer <I , I > copy ) {
72+ return (in ) -> {
73+ I out = func .createOutput (in );
74+ func .accept (in , out );
75+ copy .accept (out , in );
76+ };
77+ }
78+
79+ public static <I , O > Function <Collection <I >, O > asFunction (final AggregateOp <I , O > op ) {
80+ return in -> {
81+ final O memo = op .createMemo (in .iterator ().next ());
82+ return in .parallelStream ().reduce (memo , op .accumulator (), op .combiner ());
83+ };
84+ }
85+
86+ public static <I , O > Function <Collection <I >, Collection <O >> lift (final Function <I , O > op ) {
9387 // START HERE: need to make this an explicit subclass a la Views
9488 // maybe LiftedFunctionOp or something. It implements SelfAware,
95- // which defines OpInfo info(), allowing this guy to define how it works.
89+ // which defines OpInfo info(), allowing this guy to define how it
90+ // works.
9691 // That way, the wrapped op's extra parameters can be propagated into
9792 // the wrapped guy here.
9893 return in -> in .parallelStream ().map (op ).collect (Collectors .toList ());
9994 }
10095
101- // TODO: consider whether (some of?) these should be service methods,
102- // for extensibility. Or better: plugins of type OpAdapter. Later!
103- // E.g.: expressing tree-reduce as a function may depend on type details.
104- // net.imagej.ops.map ops are a special case for e.g. IterableInterval.
105-
106-
107-
108- ////////////////////
109- // Possibly problematic
110- // Consider whether to have these, can throw exception if incompatible
111-
112- // use function as inplace --------- only allowed if Function<T, T> and structures match
113- // mutate(arg):
114- // o = f(arg)
115- // copy(o -> arg)
116-
117- // use computer as inplace ---------
118- // mutate(arg):
119- // o = create(arg)
120- // compute(arg, o)
121- // copy(o -> arg)
122- }
96+ public static <I , O > Function <Collection <I >, Collection <O >> lift (final FlatMapOp <I , O > op ) {
97+ return (in ) -> in .parallelStream ().flatMap ((i ) -> asFunction (op ).apply (i ).parallelStream ())
98+ .collect (Collectors .toList ());
99+ }
100+ }
0 commit comments