summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openecomp/sparky/analytics/AveragingRingBuffer.java
blob: 18f5dcfa33c3118886ca03926f92f2112a108c66 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
 * ============LICENSE_START===================================================
 * SPARKY (AAI UI service)
 * ============================================================================
 * Copyright © 2017 AT&T Intellectual Property.
 * Copyright © 2017 Amdocs
 * All rights reserved.
 * ============================================================================
 * 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.
 * ============LICENSE_END=====================================================
 *
 * ECOMP and OpenECOMP are trademarks
 * and service marks of AT&T Intellectual Property.
 */

package org.openecomp.sparky.analytics;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * TODO: Fill in description.
 * 
 * @author davea
 */
public class AveragingRingBuffer {

  private int numElements;

  private long[] data;

  private AtomicInteger index;

  private long average;

  private boolean initialAverageCalculated;

  /**
   * Instantiates a new averaging ring buffer.
   *
   * @param size the size
   */
  public AveragingRingBuffer(int size) {

    if (size == 0) {
      throw new IllegalArgumentException("Size must be greater than zero");
    }

    this.initialAverageCalculated = false;
    this.numElements = size;
    this.data = new long[this.numElements];
    this.index = new AtomicInteger(-1);
  }

  /**
   * Calculate average.
   *
   * @param maxArrayIndex the max array index
   */
  private void calculateAverage(int maxArrayIndex) {

    long sum = 0;

    for (int i = 0; i <= maxArrayIndex; i++) {
      sum += data[i];
    }

    average = (sum / (maxArrayIndex + 1));

  }

  public long getAvg() {

    if (!initialAverageCalculated) {
      /*
       * until the index rolls once we will calculate the average from the data that has been added
       * to the array, not including the zero elements
       */
      if (index.get() < 0) {
        calculateAverage(0);
      } else {
        calculateAverage(index.get());
      }

    }

    return average;
  }

  /**
   * Adds the sample.
   *
   * @param value the value
   */
  public synchronized void addSample(long value) {

    index.incrementAndGet();

    data[index.get()] = value;

    if (index.get() == (numElements - 1)) {
      calculateAverage(numElements - 1);

      if (!initialAverageCalculated) {
        initialAverageCalculated = true;
      }

      index.set(-1);
    }

  }

}