15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <cmath>
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "cc/base/rolling_time_delta_history.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace cc {
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)RollingTimeDeltaHistory::RollingTimeDeltaHistory(size_t max_size)
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : max_size_(max_size) {}
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)RollingTimeDeltaHistory::~RollingTimeDeltaHistory() {}
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void RollingTimeDeltaHistory::InsertSample(base::TimeDelta time) {
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (max_size_ == 0)
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (sample_set_.size() == max_size_) {
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    sample_set_.erase(chronological_sample_deque_.front());
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    chronological_sample_deque_.pop_front();
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TimeDeltaMultiset::iterator it = sample_set_.insert(time);
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  chronological_sample_deque_.push_back(it);
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void RollingTimeDeltaHistory::Clear() {
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  chronological_sample_deque_.clear();
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sample_set_.clear();
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)base::TimeDelta RollingTimeDeltaHistory::Percentile(double percent) const {
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (sample_set_.size() == 0)
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return base::TimeDelta();
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  double fraction = percent / 100.0;
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (fraction <= 0.0)
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return *(sample_set_.begin());
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (fraction >= 1.0)
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return *(sample_set_.rbegin());
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t num_smaller_samples =
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      static_cast<size_t>(std::ceil(fraction * sample_set_.size())) - 1;
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (num_smaller_samples > sample_set_.size() / 2) {
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    size_t num_larger_samples = sample_set_.size() - num_smaller_samples - 1;
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    TimeDeltaMultiset::const_reverse_iterator it = sample_set_.rbegin();
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for (size_t i = 0; i < num_larger_samples; i++)
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      it++;
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return *it;
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TimeDeltaMultiset::const_iterator it = sample_set_.begin();
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0; i < num_smaller_samples; i++)
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    it++;
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return *it;
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace cc
64