diff options
Diffstat (limited to 'subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/aggregators/ExtremumOperator.java')
-rw-r--r-- | subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/aggregators/ExtremumOperator.java | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/aggregators/ExtremumOperator.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/aggregators/ExtremumOperator.java new file mode 100644 index 00000000..ee4ceeb8 --- /dev/null +++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/aggregators/ExtremumOperator.java | |||
@@ -0,0 +1,135 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2016, Gabor Bergmann, IncQueryLabs Ltd. | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package tools.refinery.viatra.runtime.matchers.aggregators; | ||
10 | |||
11 | import java.util.Comparator; | ||
12 | import java.util.SortedMap; | ||
13 | import java.util.TreeMap; | ||
14 | import java.util.stream.Stream; | ||
15 | |||
16 | import tools.refinery.viatra.runtime.matchers.psystem.aggregations.IMultisetAggregationOperator; | ||
17 | |||
18 | /** | ||
19 | * Incrementally computes the minimum or maximum of java.lang.Comparable values, using the default comparison | ||
20 | * | ||
21 | * @author Gabor Bergmann | ||
22 | * @since 1.4 | ||
23 | */ | ||
24 | public class ExtremumOperator<T extends Comparable<T>> | ||
25 | implements IMultisetAggregationOperator<T, SortedMap<T, Integer>, T> { | ||
26 | |||
27 | public enum Extreme { | ||
28 | MIN, MAX; | ||
29 | |||
30 | /** | ||
31 | * @since 2.0 | ||
32 | */ | ||
33 | public <T> T pickFrom(SortedMap<T, Integer> nonEmptyMultiSet) { | ||
34 | switch(this) { | ||
35 | case MIN: | ||
36 | return nonEmptyMultiSet.firstKey(); | ||
37 | case MAX: | ||
38 | return nonEmptyMultiSet.lastKey(); | ||
39 | default: | ||
40 | return null; | ||
41 | } | ||
42 | } | ||
43 | } | ||
44 | |||
45 | private static final ExtremumOperator MIN_OP = new ExtremumOperator<>(Extreme.MIN); | ||
46 | private static final ExtremumOperator MAX_OP = new ExtremumOperator<>(Extreme.MAX); | ||
47 | |||
48 | public static <T extends Comparable<T>> ExtremumOperator<T> getMin() { | ||
49 | return MIN_OP; | ||
50 | } | ||
51 | public static <T extends Comparable<T>> ExtremumOperator<T> getMax() { | ||
52 | return MAX_OP; | ||
53 | } | ||
54 | |||
55 | Extreme extreme; | ||
56 | private ExtremumOperator(Extreme extreme) { | ||
57 | super(); | ||
58 | this.extreme = extreme; | ||
59 | } | ||
60 | |||
61 | @Override | ||
62 | public String getShortDescription() { | ||
63 | String opName = getName(); | ||
64 | return String.format( | ||
65 | "%s incrementally computes the %simum of java.lang.Comparable values, using the default comparison", | ||
66 | opName, opName); | ||
67 | } | ||
68 | |||
69 | @Override | ||
70 | public String getName() { | ||
71 | return extreme.name().toLowerCase(); | ||
72 | } | ||
73 | |||
74 | /** | ||
75 | * @since 2.0 | ||
76 | */ | ||
77 | @Override | ||
78 | public SortedMap<T, Integer> createNeutral() { | ||
79 | return new TreeMap<>(); | ||
80 | } | ||
81 | |||
82 | /** | ||
83 | * @since 2.0 | ||
84 | */ | ||
85 | @Override | ||
86 | public boolean isNeutral(SortedMap<T, Integer> result) { | ||
87 | return result.isEmpty(); | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * @since 2.0 | ||
92 | */ | ||
93 | @Override | ||
94 | public SortedMap<T, Integer> update(SortedMap<T, Integer> oldResult, T updateValue, boolean isInsertion) { | ||
95 | oldResult.compute(updateValue, (value, c) -> { | ||
96 | int count = (c == null) ? 0 : c; | ||
97 | int result = (isInsertion) ? count+1 : count-1; | ||
98 | return (result == 0) ? null : result; | ||
99 | }); | ||
100 | return oldResult; | ||
101 | } | ||
102 | |||
103 | /** | ||
104 | * @since 2.0 | ||
105 | */ | ||
106 | @Override | ||
107 | public T getAggregate(SortedMap<T, Integer> result) { | ||
108 | return result.isEmpty() ? null : | ||
109 | extreme.pickFrom(result); | ||
110 | } | ||
111 | |||
112 | /** | ||
113 | * @since 2.0 | ||
114 | */ | ||
115 | @Override | ||
116 | public T aggregateStream(Stream<T> stream) { | ||
117 | switch (extreme) { | ||
118 | case MIN: | ||
119 | return stream.min(Comparator.naturalOrder()).orElse(null); | ||
120 | case MAX: | ||
121 | return stream.max(Comparator.naturalOrder()).orElse(null); | ||
122 | default: | ||
123 | return null; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | /** | ||
128 | * @since 2.4 | ||
129 | */ | ||
130 | @Override | ||
131 | public SortedMap<T, Integer> clone(SortedMap<T, Integer> original) { | ||
132 | return new TreeMap<T, Integer>(original); | ||
133 | } | ||
134 | |||
135 | } | ||