mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-08 21:30:57 +00:00
Started creating a test for polar fix grouping
This commit is contained in:
1 parent
af51393773
commit
c861ab5b3d
11 files changed
+343
-32
No files matched your search
@@ -16,4 +16,8 @@ public interface WindStepping extends Serializable{
|
||||
|
||||
double getDistanceToLevelFloor(double speed);
|
||||
|
||||
int hashCode();
|
||||
|
||||
boolean equals(Object obj);
|
||||
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
package com.sap.sailing.polars.mining.test;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl;
|
||||
import com.sap.sailing.polars.mining.PolarDataMiner;
|
||||
|
||||
public class PolarDataMinerTest {
|
||||
|
||||
private static final int MILLISECONDS_OVER_WHICH_TO_AVERAGE_SPEED = 30;
|
||||
|
||||
@Test
|
||||
public void testGrouping() throws InterruptedException, TimeoutException {
|
||||
PolarDataMiner miner = new PolarDataMiner();
|
||||
|
||||
GPSFixMoving fix = createMockedFix();
|
||||
Competitor competitor = mock(Competitor.class);
|
||||
TrackedRace trackedRace = createMockedTrackedRace(competitor, fix);
|
||||
miner.addFix(fix, competitor, trackedRace);
|
||||
int millisLeft = 500000;
|
||||
while (miner.isCurrentlyActiveAndOrHasQueue() && millisLeft > 0) {
|
||||
System.out.println("Executor active");
|
||||
Thread.sleep(100);
|
||||
millisLeft = millisLeft - 100;
|
||||
if (miner.isCurrentlyActiveAndOrHasQueue() && millisLeft <= 0) {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private GPSFixMoving createMockedFix() {
|
||||
GPSFixMoving fix = mock(GPSFixMoving.class);
|
||||
when(fix.getPosition()).thenReturn(new DegreePosition(54.431952, 10.186767));
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(2014, 4, 3, 13, 00);
|
||||
TimePoint fixTimePoint = new MillisecondsTimePoint(cal.getTime());
|
||||
when(fix.getTimePoint()).thenReturn(fixTimePoint);
|
||||
Bearing bearing = new DegreeBearingImpl(45);
|
||||
SpeedWithBearing speedWithBearing = new KnotSpeedWithBearingImpl(10.5, bearing);
|
||||
when(fix.getSpeed()).thenReturn(speedWithBearing);
|
||||
return fix;
|
||||
}
|
||||
|
||||
private TrackedRace createMockedTrackedRace(Competitor competitor, GPSFixMoving fix) {
|
||||
TrackedRace trackedRace = mock(TrackedRace.class);
|
||||
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> track = new DynamicGPSFixMovingTrackImpl<Competitor>(competitor,
|
||||
MILLISECONDS_OVER_WHICH_TO_AVERAGE_SPEED);
|
||||
track.add(fix);
|
||||
when(trackedRace.getTrack(competitor)).thenReturn(track);
|
||||
|
||||
RaceDefinition mockedRaceDefinition = createMockedRaceDefinition();
|
||||
when(trackedRace.getRace()).thenReturn(mockedRaceDefinition);
|
||||
|
||||
MarkPassing markpassing = createMockedStartMarkPassing();
|
||||
when(trackedRace.getMarkPassing(eq(competitor), any(Waypoint.class))).thenReturn(markpassing);
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(2014, 4, 3, 12, 00);
|
||||
TimePoint startOfRace = new MillisecondsTimePoint(cal.getTime());
|
||||
|
||||
cal.set(2014, 4, 3, 15, 00);
|
||||
TimePoint endOfRace = new MillisecondsTimePoint(cal.getTime());
|
||||
|
||||
when(trackedRace.getStartOfRace()).thenReturn(startOfRace);
|
||||
when(trackedRace.getEndOfRace()).thenReturn(endOfRace);
|
||||
|
||||
return trackedRace;
|
||||
}
|
||||
|
||||
private MarkPassing createMockedStartMarkPassing() {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(2014, 4, 3, 12, 15);
|
||||
TimePoint startOfRaceForCompetitor = new MillisecondsTimePoint(cal.getTime());
|
||||
|
||||
MarkPassing passing = mock(MarkPassing.class);
|
||||
when(passing.getTimePoint()).thenReturn(startOfRaceForCompetitor);
|
||||
return passing;
|
||||
}
|
||||
|
||||
private RaceDefinition createMockedRaceDefinition() {
|
||||
RaceDefinition raceDefinition = mock(RaceDefinition.class);
|
||||
Course mockedCourse = createMockedCourse();
|
||||
when(raceDefinition.getCourse()).thenReturn(mockedCourse);
|
||||
BoatClass mockedBoatClass = mock(BoatClass.class);
|
||||
when(mockedBoatClass.getManeuverDegreeAngleThreshold()).thenReturn(20.0);
|
||||
when(raceDefinition.getBoatClass()).thenReturn(mockedBoatClass);
|
||||
return raceDefinition;
|
||||
}
|
||||
|
||||
private Course createMockedCourse() {
|
||||
Course course = mock(Course.class);
|
||||
return course;
|
||||
}
|
||||
|
||||
}
|
||||
+19
-7
@@ -2,22 +2,26 @@ package com.sap.sailing.polars.mining;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.PolarSheetGenerationSettings;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.impl.WindSteppingWithMaxDistance;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sse.datamining.shared.annotations.Dimension;
|
||||
|
||||
public class GPSFixMovingWithPolarContext {
|
||||
public class GPSFixMovingWithPolarContext implements PolarClusterKey {
|
||||
|
||||
private final GPSFixMoving fix;
|
||||
private final TrackedRace race;
|
||||
private final Competitor competitor;
|
||||
private final PolarSheetGenerationSettings defaultPolarSheetGenerationSettings;
|
||||
|
||||
public GPSFixMovingWithPolarContext(GPSFixMoving fix, TrackedRace race, Competitor competitor) {
|
||||
public GPSFixMovingWithPolarContext(GPSFixMoving fix, TrackedRace race, Competitor competitor,
|
||||
PolarSheetGenerationSettings defaultPolarSheetGenerationSettings) {
|
||||
this.fix = fix;
|
||||
this.race = race;
|
||||
this.competitor = competitor;
|
||||
this.defaultPolarSheetGenerationSettings = defaultPolarSheetGenerationSettings;
|
||||
}
|
||||
|
||||
public GPSFixMoving getFix() {
|
||||
@@ -32,13 +36,21 @@ public class GPSFixMovingWithPolarContext {
|
||||
return competitor;
|
||||
}
|
||||
|
||||
@Dimension(messageKey = "roundedAngle")
|
||||
public int roundedAngleToTheWind() {
|
||||
@Override
|
||||
public RoundedAngleToTheWind getRoundedAngleToTheWind() {
|
||||
SpeedWithBearing boatSpeed = race.getTrack(competitor).getEstimatedSpeed(fix.getTimePoint());
|
||||
Wind wind = race.getWind(fix.getPosition(), fix.getTimePoint());
|
||||
Bearing bearing = boatSpeed.getBearing();
|
||||
int roundedAngle = (int) Math.round(bearing.getDifferenceTo(wind.getBearing()).getDegrees());
|
||||
return roundedAngle;
|
||||
int angle = (int) Math.round(bearing.getDifferenceTo(wind.getBearing()).getDegrees());
|
||||
return new RoundedAngleToTheWind(angle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindSpeedLevel getWindSpeedLevel() {
|
||||
Wind wind = race.getWind(fix.getPosition(), fix.getTimePoint());
|
||||
WindSteppingWithMaxDistance stepping = defaultPolarSheetGenerationSettings.getWindStepping();
|
||||
int level = stepping.getLevelIndexForValue(wind.getKnots());
|
||||
return new WindSpeedLevel(level, stepping);
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.sap.sailing.polars.mining;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sse.datamining.AdditionalResultDataBuilder;
|
||||
import com.sap.sse.datamining.components.Processor;
|
||||
import com.sap.sse.datamining.impl.components.GroupedDataEntry;
|
||||
import com.sap.sse.datamining.shared.GroupKey;
|
||||
|
||||
public class IncrementalRegressionProcessor implements Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>> {
|
||||
|
||||
private final Map<GroupKey, Set<GPSFixMovingWithPolarContext>> container = new HashMap<GroupKey, Set<GPSFixMovingWithPolarContext>>();
|
||||
|
||||
@Override
|
||||
public void onElement(GroupedDataEntry<GPSFixMovingWithPolarContext> element) {
|
||||
GroupKey key = element.getKey();
|
||||
if (!container.containsKey(key)) {
|
||||
container.put(key, new HashSet<GPSFixMovingWithPolarContext>());
|
||||
}
|
||||
Set<GPSFixMovingWithPolarContext> set = container.get(key);
|
||||
set.add(element.getDataEntry());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() throws InterruptedException {
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdditionalResultDataBuilder getAdditionalResultData(AdditionalResultDataBuilder additionalDataBuilder) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.sap.sailing.polars.mining;
|
||||
|
||||
import com.sap.sse.datamining.shared.annotations.Dimension;
|
||||
|
||||
public interface PolarClusterKey {
|
||||
|
||||
/**
|
||||
*
|
||||
* @return degrees boat to windDirection in DEG
|
||||
*/
|
||||
@Dimension(messageKey = "angleToWind")
|
||||
public abstract RoundedAngleToTheWind getRoundedAngleToTheWind();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return wind speed level
|
||||
*/
|
||||
@Dimension(messageKey = "windSpeed")
|
||||
public abstract WindSpeedLevel getWindSpeedLevel();
|
||||
|
||||
}
|
||||
@@ -8,6 +8,8 @@ import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.PolarSheetGenerationSettings;
|
||||
import com.sap.sailing.domain.common.impl.PolarSheetGenerationSettingsImpl;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
@@ -22,6 +24,7 @@ public class PolarDataMiner {
|
||||
|
||||
private static final int THREAD_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors(), 3);
|
||||
private static final ThreadPoolExecutor executor = createExecutor();
|
||||
private final PolarSheetGenerationSettings defaultPolarSheetGenerationSettings;
|
||||
|
||||
private static ThreadPoolExecutor createExecutor() {
|
||||
return new ThreadPoolExecutor(THREAD_POOL_SIZE, THREAD_POOL_SIZE, 60, TimeUnit.SECONDS,
|
||||
@@ -32,6 +35,7 @@ public class PolarDataMiner {
|
||||
private AbstractEnrichingProcessor<Triple<GPSFixMoving, TrackedRace, Competitor>, GPSFixMovingWithPolarContext> enrichingProcessor;
|
||||
|
||||
public PolarDataMiner() {
|
||||
defaultPolarSheetGenerationSettings = PolarSheetGenerationSettingsImpl.createStandardPolarSettings();
|
||||
try {
|
||||
setUpWorkflow();
|
||||
} catch (ClassCastException | NoSuchMethodException | SecurityException e) {
|
||||
@@ -44,23 +48,36 @@ public class PolarDataMiner {
|
||||
|
||||
private void setUpWorkflow() throws ClassCastException, NoSuchMethodException,
|
||||
SecurityException {
|
||||
Collection<Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>>> grouperResultReceivers = null;
|
||||
Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>> incrementalRegressionProcessor = new IncrementalRegressionProcessor();
|
||||
Collection<Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>>> grouperResultReceivers = Arrays
|
||||
.asList(incrementalRegressionProcessor);
|
||||
|
||||
Collection<Function<?>> dimensions = new ArrayList<>();
|
||||
Function<Integer> function = FunctionFactory.createMethodWrappingFunction(GPSFixMovingWithPolarContext.class
|
||||
.getMethod("roundedAngleToTheWind", new Class<?>[0]));
|
||||
dimensions.add(function);
|
||||
Function<RoundedAngleToTheWind> angleFunction = FunctionFactory
|
||||
.createMethodWrappingFunction(PolarClusterKey.class.getMethod("getRoundedAngleToTheWind",
|
||||
new Class<?>[0]));
|
||||
Function<WindSpeedLevel> windSpeedFunction = FunctionFactory.createMethodWrappingFunction(PolarClusterKey.class
|
||||
.getMethod("getWindSpeedLevel", new Class<?>[0]));
|
||||
|
||||
dimensions.add(angleFunction);
|
||||
dimensions.add(windSpeedFunction);
|
||||
|
||||
Processor<GPSFixMovingWithPolarContext> groupingProcessor = new ParallelMultiDimensionalGroupingProcessor<GPSFixMovingWithPolarContext>(
|
||||
executor, grouperResultReceivers, dimensions);
|
||||
|
||||
Collection<Processor<GPSFixMovingWithPolarContext>> filteringResultReceivers = Arrays.asList(groupingProcessor);
|
||||
Processor<GPSFixMovingWithPolarContext> filteringProcessor = new ParallelFilteringProcessor<GPSFixMovingWithPolarContext>(
|
||||
executor, filteringResultReceivers, new PolarFixFilterCriteria());
|
||||
|
||||
Collection<Processor<GPSFixMovingWithPolarContext>> enrichingResultReceivers = Arrays
|
||||
.asList(filteringProcessor);
|
||||
enrichingProcessor = new AbstractEnrichingProcessor<Triple<GPSFixMoving, TrackedRace, Competitor>, GPSFixMovingWithPolarContext>(executor, enrichingResultReceivers) {
|
||||
enrichingProcessor = new AbstractEnrichingProcessor<Triple<GPSFixMoving, TrackedRace, Competitor>, GPSFixMovingWithPolarContext>(
|
||||
executor, enrichingResultReceivers) {
|
||||
|
||||
@Override
|
||||
protected GPSFixMovingWithPolarContext enrich(Triple<GPSFixMoving, TrackedRace, Competitor> element) {
|
||||
return new GPSFixMovingWithPolarContext(element.getA(), element.getB(), element.getC());
|
||||
return new GPSFixMovingWithPolarContext(element.getA(), element.getB(), element.getC(),
|
||||
defaultPolarSheetGenerationSettings);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -70,4 +87,10 @@ public class PolarDataMiner {
|
||||
enrichingProcessor.onElement(new Triple<GPSFixMoving, TrackedRace, Competitor>(fix, trackedRace, competitor));
|
||||
}
|
||||
|
||||
public boolean isCurrentlyActiveAndOrHasQueue() {
|
||||
boolean isActive = executor.getActiveCount() > 0;
|
||||
boolean hasQueue = executor.getQueue().size() > 0;
|
||||
return isActive || hasQueue;
|
||||
}
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.sap.sailing.polars.mining;
|
||||
|
||||
public class RoundedAngleToTheWind {
|
||||
|
||||
private final int angle;
|
||||
|
||||
public RoundedAngleToTheWind(int angle) {
|
||||
this.angle = angle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + angle;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
RoundedAngleToTheWind other = (RoundedAngleToTheWind) obj;
|
||||
if (angle != other.angle)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.sap.sailing.polars.mining;
|
||||
|
||||
import com.sap.sailing.domain.common.WindStepping;
|
||||
|
||||
public class WindSpeedLevel {
|
||||
|
||||
private final int level;
|
||||
private final WindStepping stepping;
|
||||
|
||||
public WindSpeedLevel(int level, WindStepping stepping) {
|
||||
this.level = level;
|
||||
this.stepping = stepping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + level;
|
||||
result = prime * result + ((stepping == null) ? 0 : stepping.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
WindSpeedLevel other = (WindSpeedLevel) obj;
|
||||
if (level != other.level)
|
||||
return false;
|
||||
if (stepping == null) {
|
||||
if (other.stepping != null)
|
||||
return false;
|
||||
} else if (!stepping.equals(other.stepping))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+1
@@ -4,6 +4,7 @@ import com.sap.sse.datamining.shared.GroupKey;
|
||||
|
||||
|
||||
public class CompoundGroupKey extends AbstractGroupKey {
|
||||
|
||||
private static final long serialVersionUID = -7902450253393172550L;
|
||||
|
||||
private GroupKey mainKey;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.sap.sse.datamining.factories;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.sap.sse.datamining.functions.Function;
|
||||
import com.sap.sse.datamining.shared.GroupKey;
|
||||
import com.sap.sse.datamining.shared.impl.CompoundGroupKey;
|
||||
import com.sap.sse.datamining.shared.impl.GenericGroupKey;
|
||||
|
||||
public class GroupKeyFactory {
|
||||
|
||||
public static <DataType> GroupKey createCompoundKeyFor(DataType input, Iterator<Function<?>> dimensionsIterator) {
|
||||
Function<?> mainDimension = dimensionsIterator.next();
|
||||
GroupKey key = createGroupKeyFor(input, mainDimension);
|
||||
if (dimensionsIterator.hasNext()) {
|
||||
key = new CompoundGroupKey(key, createCompoundKeyFor(input, dimensionsIterator));
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
public static <DataType> GroupKey createGroupKeyFor(DataType input, Function<?> mainDimension) {
|
||||
Object keyValue = mainDimension.tryToInvoke(input);
|
||||
return new GenericGroupKey<Object>(keyValue);
|
||||
}
|
||||
|
||||
}
|
||||
+3
-19
@@ -1,16 +1,13 @@
|
||||
package com.sap.sse.datamining.impl.components;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import com.sap.sse.datamining.AdditionalResultDataBuilder;
|
||||
import com.sap.sse.datamining.components.Processor;
|
||||
import com.sap.sse.datamining.factories.GroupKeyFactory;
|
||||
import com.sap.sse.datamining.functions.Function;
|
||||
import com.sap.sse.datamining.shared.GroupKey;
|
||||
import com.sap.sse.datamining.shared.impl.CompoundGroupKey;
|
||||
import com.sap.sse.datamining.shared.impl.GenericGroupKey;
|
||||
|
||||
public class ParallelMultiDimensionalGroupingProcessor<DataType>
|
||||
extends AbstractSimpleParallelProcessor<DataType, GroupedDataEntry<DataType>> {
|
||||
@@ -47,25 +44,12 @@ public class ParallelMultiDimensionalGroupingProcessor<DataType>
|
||||
return new Callable<GroupedDataEntry<DataType>>() {
|
||||
@Override
|
||||
public GroupedDataEntry<DataType> call() throws Exception {
|
||||
return new GroupedDataEntry<DataType>(createCompoundKeyFor(element, dimensions.iterator()), element);
|
||||
return new GroupedDataEntry<DataType>(GroupKeyFactory.createCompoundKeyFor(element,
|
||||
dimensions.iterator()), element);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private GroupKey createCompoundKeyFor(DataType input, Iterator<Function<?>> dimensionsIterator) {
|
||||
Function<?> mainDimension = dimensionsIterator.next();
|
||||
GroupKey key = createGroupKeyFor(input, mainDimension);
|
||||
if (dimensionsIterator.hasNext()) {
|
||||
key = new CompoundGroupKey(key, createCompoundKeyFor(input, dimensionsIterator));
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
private GroupKey createGroupKeyFor(DataType input, Function<?> mainDimension) {
|
||||
Object keyValue = mainDimension.tryToInvoke(input);
|
||||
return new GenericGroupKey<Object>(keyValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setAdditionalData(AdditionalResultDataBuilder additionalDataBuilder) {
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user