joinFilterMap: OpStateless U(Ut, M) → U(ID, V)
Ut onItem(Ut key, M value) {
if (location(value.id) = "window")
emit(value.id, (value.scalar, value.ts))
}
Ut onMarker(Marker m) { }
|
linearInterpolation: OpKeyedOrdered O(ID, V) → O(ID, V)
Precondition: items arrive in order of increasing timestamp
V initialState() { return nil }
V onItem(V state, ID key, V value) {
if (state == nil) then // first element
emit(key, value)
else // not the first element
Float x = state.scalar
Int dt = value.ts - state.ts
for i = 1 … dt do
Float y = x + i * (value.scalar - x) / dt
emit(key, (y, state.ts + i))
return value
}
V onMarker(V state, ID key, Marker m) { return state }
|
maxOfAvgPerID: OpKeyedUnordered U(ID, V) → U(ID, V)
AvgPair = { sum: Float, count: Nat }
AvgPair in(ID key, V value) { return (value.scalar, 1) }
AvgPair id() { return (0.0, 0) }
AvgPair combine(AvgPair x, AvgPair y) {
return (x.sum + y.sum, x.count + y.count)
}
Float initialState() { return -infinity }
Float updateState(Float oldState, AvgPair agg) {
return max(oldState, agg.sum / agg.count)
}
Ut onItem(Float lastState, ID key, V value) { }
Ut onMarker(Float newState, ID key, Marker m) {
emit(key, (newState, m.timestamp - 1))
}
|