/* * Copyright © 2014 Cask Data, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package co.cask.cdap.api.dataset.lib.cube; import co.cask.cdap.api.annotation.Beta; /** * Returns interpolators of different types. */ @Beta public final class Interpolators { public static final long DEFAULT_MAX_ALLOWED_GAP = 60; /** * Return 0 if the time between data points is above a give limit, or if the point to interpolate * is too far before the first point, or too far after the last point. */ public abstract static class BaseInterpolator implements Interpolator { private long maxAllowedGap; BaseInterpolator(long maxAllowedGap) { this.maxAllowedGap = maxAllowedGap; } @Override public long interpolate(TimeValue start, TimeValue end, long ts) { if (start == null) { throw new NullPointerException("start cannot be null"); } if (end == null) { throw new NullPointerException("end cannot be null"); } if (ts > end.getTimestamp() || ts < start.getTimestamp()) { throw new IllegalArgumentException("ts must be within given start and end"); } // if its been too many seconds between datapoints, return a 0 for everything in between. if ((end.getTimestamp() - start.getTimestamp()) > maxAllowedGap) { return 0; } return limitedInterpolate(start, end, ts); } @Override public long getMaxAllowedGap() { return maxAllowedGap; } protected abstract long limitedInterpolate(TimeValue start, TimeValue end, long ts); } /** * Timestamps between 2 data points will take on the value of the previous point. * If the timestamp is before the start, return a 0. If the timestamp is after the end, * return the end value. */ public static final class Step extends BaseInterpolator { public Step() { super(DEFAULT_MAX_ALLOWED_GAP); } public Step(long maxAllowedGap) { super(maxAllowedGap); } @Override protected long limitedInterpolate(TimeValue start, TimeValue end, long ts) { return (ts < end.getTimestamp()) ? start.getValue() : end.getValue(); } } /** * timestamps between 2 data points will increase or decrease "linearly". If the timestamp * is before the start or after the end, return a 0. */ public static final class Linear extends BaseInterpolator { public Linear() { super(DEFAULT_MAX_ALLOWED_GAP); } public Linear(long maxAllowedGap) { super(maxAllowedGap); } @Override protected long limitedInterpolate(TimeValue start, TimeValue end, long ts) { long deltaX = ts - start.getTimestamp(); long totalX = end.getTimestamp() - start.getTimestamp(); long totalY = end.getValue() - start.getValue(); long deltaY = (int) (totalY * deltaX / totalX); return start.getValue() + deltaY; } } }