com.kolibrifx.plovercrest.server.streams.folds.CombineLatestFoldSetup Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of plovercrest-server Show documentation
Show all versions of plovercrest-server Show documentation
Plovercrest server library.
The newest version!
/*
* Copyright (c) 2010-2017, KolibriFX AS. Licensed under the Apache License, version 2.0.
*/
package com.kolibrifx.plovercrest.server.streams.folds;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.kolibrifx.lancebill.folds.CombineLatestFold;
import com.kolibrifx.plovercrest.server.internal.folds.FoldCallback;
import com.kolibrifx.plovercrest.server.internal.folds.FoldReaderInputs;
import com.kolibrifx.plovercrest.server.internal.folds.FoldReaderSetup;
import com.kolibrifx.plovercrest.server.internal.folds.FoldWriter;
import com.kolibrifx.plovercrest.server.streams.Stream;
public class CombineLatestFoldSetup implements FoldSetup {
private final CombineLatestFold fold;
public CombineLatestFoldSetup(final CombineLatestFold fold) {
this.fold = fold;
}
@Override
public FoldReaderSetup setupReader(final long timestamp, final FoldWriter foldOutput,
final List> inputStreams) {
final List latestValues = new ArrayList<>();
final Map tableIndexes = new HashMap<>();
int i = 0;
for (final Stream> s : inputStreams) {
latestValues.add(null);
tableIndexes.put(s.getName(), i++);
}
final FoldCallback foldCallback = new FoldCallback() {
private long latestTimestamp = Long.MIN_VALUE;
@Override
public void onNext(final String tableName, final long timestamp, final U element) {
final int index = tableIndexes.get(tableName);
latestValues.set(index, element);
if (latestValues.contains(null)) {
// not all values are set yet, don't invoke fold
return;
}
latestTimestamp = Math.max(timestamp, latestTimestamp);
final T output = fold.apply(latestTimestamp, latestValues);
if (output != null) {
// note: assuming that the timestamp of the output is the same as the latest input. safe?
foldOutput.write(timestamp, output);
}
}
};
final FoldReaderInputs inputs = new FoldReaderInputs<>();
inputs.addInputs(inputStreams, timestamp);
return new FoldReaderSetup() {
@Override
public FoldCallback getFoldCallback() {
return foldCallback;
}
@Override
public FoldReaderInputs getInputs() {
return inputs;
}
};
}
@Override
public long getLastOutputTimestamp(final List> inputStreams,
final CombinatorStrategy combinatorStrategy) {
// The instanceof checks are not elegant, should use some nicer multiple dispatch pattern...
if (combinatorStrategy instanceof HistoricalCombinatorStrategy) {
// Return the minimum of all input last timestamps
long result = Long.MAX_VALUE;
for (final Stream> input : inputStreams) {
final long tmp = input.getLastTimestamp();
if (tmp == -1) {
// empty input
return -1;
}
result = Math.min(result, tmp);
}
return result;
} else if (combinatorStrategy instanceof LiveCombinatorStrategy) {
// Return the maximum of all input last timestamps
long result = Long.MIN_VALUE;
for (final Stream> input : inputStreams) {
final long tmp = input.getLastTimestamp();
if (tmp == -1) {
// empty input
return -1;
}
result = Math.max(result, tmp);
}
return result;
} else {
throw new IllegalStateException("Unknown combinator strategy " + combinatorStrategy);
}
}
}