/* * Copyright (C) 2014 Google 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 interactivespaces.util.sampling; /** * A data sampler which does smoothing over a specified time window. * * <p> * Samples are kept for the length of a time window and averaged. For a * particular point, all values in the window are summed and then divided by the * size of the window. * * <p> * This class is not thread safe. * * @author Keith M. Hughes */ public class AveragingDataSampler implements DataSampler { /** * {@code true} if data is ready for processing. */ private boolean ready; /** * The size of the window over which data will be averaged. */ private final int sizeWindow; /** * Where the next samples will be stored. */ private int writePointer = 0; /** * The samples which have come in. This is a circular buffer. */ private final int[][] samples; /** * The sum of all samples in their current window. */ private final int[] summedSamples; /** * The average of the samples across the window. */ private final int[] averagedSamples; /** * Construct the sampler. * * @param numberSamples * the number of samples in a snapshot * @param sizeWindow * how many snapshots to hold in the averaging window */ public AveragingDataSampler(int numberSamples, int sizeWindow) { summedSamples = new int[numberSamples]; averagedSamples = new int[numberSamples]; this.sizeWindow = sizeWindow; samples = new int[sizeWindow][]; } @Override public void addSamples(int[] newSamples) { if (ready) { int[] sampleWriteArray = samples[writePointer]; for (int i = 0; i < summedSamples.length; i++) { summedSamples[i] += newSamples[i] - sampleWriteArray[i]; averagedSamples[i] = summedSamples[i] / sizeWindow; } samples[writePointer] = newSamples; writePointer = ++writePointer % sizeWindow; } else { for (int i = 0; i < summedSamples.length; i++) { summedSamples[i] += newSamples[i]; } samples[writePointer] = newSamples; writePointer = ++writePointer % sizeWindow; if (writePointer == 0) { ready = true; } } } @Override public boolean hasReadyData() { return ready; } @Override public int[] getProcessedData() { return averagedSamples; } }