1c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren/* 2c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * Copyright (C) 2016 The Android Open Source Project 3c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * 4c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * Licensed under the Apache License, Version 2.0 (the "License"); 5c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * you may not use this file except in compliance with the License. 6c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * You may obtain a copy of the License at 7c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * 8c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * http://www.apache.org/licenses/LICENSE-2.0 9c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * 10c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * Unless required by applicable law or agreed to in writing, software 11c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * distributed under the License is distributed on an "AS IS" BASIS, 12c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * See the License for the specific language governing permissions and 14c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * limitations under the License 15c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren */ 16c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren 17c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wrenpackage com.android.server.notification; 18c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren 19c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren 20c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren/** 21c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * Exponentially weighted moving average estimator for event rate. 22c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * 23c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren * {@hide} 24c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren */ 25c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wrenpublic class RateEstimator { 26c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren private static final double RATE_ALPHA = 0.8; 27c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren private static final double MINIMUM_DT = 0.0005; 28fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak private Long mLastEventTime; 29888b7a8faf7d6c2aa4272bebeb875eac9a2ff21cChris Wren private double mInterarrivalTime; 30c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren 31888b7a8faf7d6c2aa4272bebeb875eac9a2ff21cChris Wren public RateEstimator() { 32888b7a8faf7d6c2aa4272bebeb875eac9a2ff21cChris Wren // assume something generous if we have no information 33888b7a8faf7d6c2aa4272bebeb875eac9a2ff21cChris Wren mInterarrivalTime = 1000.0; 34888b7a8faf7d6c2aa4272bebeb875eac9a2ff21cChris Wren } 35c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren 36fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak /** Update the estimate to account for an event that just happened. */ 37c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren public float update(long now) { 38fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak float rate; 39fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak if (mLastEventTime == null) { 40fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak // No last event time, rate is zero. 41fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak rate = 0f; 42fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak } else { 43fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak // Calculate the new inter-arrival time based on last event time. 44888b7a8faf7d6c2aa4272bebeb875eac9a2ff21cChris Wren mInterarrivalTime = getInterarrivalEstimate(now); 45fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak rate = (float) (1.0 / mInterarrivalTime); 46fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak } 47c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren mLastEventTime = now; 48fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak return rate; 49c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren } 50c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren 51c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren /** @return the estimated rate if there were a new event right now. */ 52c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren public float getRate(long now) { 53fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak if (mLastEventTime == null) { 54fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak return 0f; 55fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak } 56c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren return (float) (1.0 / getInterarrivalEstimate(now)); 57c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren } 58c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren 59c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren /** @return the average inter-arrival time if there were a new event right now. */ 60c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren private double getInterarrivalEstimate(long now) { 61c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren double dt = ((double) (now - mLastEventTime)) / 1000.0; 62c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren dt = Math.max(dt, MINIMUM_DT); 63fd303327083fdf309b9d8a15343f9eb70c014b11Tony Mak // a*iat_old + (1-a)*(t_now-t_last) 64c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren return (RATE_ALPHA * mInterarrivalTime + (1.0 - RATE_ALPHA) * dt); 65c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren } 66c8673a88fed53715d2295a535535c7ce7acbe7b6Chris Wren} 67