Fix incorrect interpolation of active bucket for partial requests.
Just because the bucket is active (ie. overlaps with 'now') doesn't mean the request necessarily covers the entire bucket. For example a bucketDuration=5 with a bucket from curStart=1 to curEnd=6 with now=4 and requests: - from start=0 to end=3 --> overlap=[1,3] --> bucketSpan=2 - from start=2 to end=3 --> overlap=[2,3] --> bucketSpan=1 - from start=2 to end=5 --> overlap=[2,4] --> bucketSpan=2 - from start=2 to end=7 --> overlap=[2,4] --> bucketSpan=2 and the previously correctly handled cases: - from start=0 to end=5 --> overlap=[1,4] --> bucketSpan=3 - from start=0 to end=7 --> overlap=[1,4] --> bucketSpan=3 We fix this by bounding the end of buckets to now, this means that bucketDuration is no longer a constant, but it simplifies all the rest of the logic. Test: builds, atest Bug: 143338233 Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: I642b57f7b8486071ad7808fd9b901859923b6d25
This commit is contained in:
@@ -548,32 +548,32 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
final int startIndex = getIndexAfter(end);
|
final int startIndex = getIndexAfter(end);
|
||||||
for (int i = startIndex; i >= 0; i--) {
|
for (int i = startIndex; i >= 0; i--) {
|
||||||
final long curStart = bucketStart[i];
|
final long curStart = bucketStart[i];
|
||||||
final long curEnd = curStart + bucketDuration;
|
long curEnd = curStart + bucketDuration;
|
||||||
|
|
||||||
// bucket is older than request; we're finished
|
// bucket is older than request; we're finished
|
||||||
if (curEnd <= start) break;
|
if (curEnd <= start) break;
|
||||||
// bucket is newer than request; keep looking
|
// bucket is newer than request; keep looking
|
||||||
if (curStart >= end) continue;
|
if (curStart >= end) continue;
|
||||||
|
|
||||||
// include full value for active buckets, otherwise only fractional
|
// the active bucket is shorter then a normal completed bucket
|
||||||
final boolean activeBucket = curStart < now && curEnd > now;
|
if (curEnd > now) curEnd = now;
|
||||||
final long overlap;
|
// usually this is simply bucketDuration
|
||||||
if (activeBucket) {
|
final long bucketSpan = curEnd - curStart;
|
||||||
overlap = bucketDuration;
|
// prevent division by zero
|
||||||
} else {
|
if (bucketSpan <= 0) continue;
|
||||||
final long overlapEnd = curEnd < end ? curEnd : end;
|
|
||||||
final long overlapStart = curStart > start ? curStart : start;
|
final long overlapEnd = curEnd < end ? curEnd : end;
|
||||||
overlap = overlapEnd - overlapStart;
|
final long overlapStart = curStart > start ? curStart : start;
|
||||||
}
|
final long overlap = overlapEnd - overlapStart;
|
||||||
if (overlap <= 0) continue;
|
if (overlap <= 0) continue;
|
||||||
|
|
||||||
// integer math each time is faster than floating point
|
// integer math each time is faster than floating point
|
||||||
if (activeTime != null) entry.activeTime += activeTime[i] * overlap / bucketDuration;
|
if (activeTime != null) entry.activeTime += activeTime[i] * overlap / bucketSpan;
|
||||||
if (rxBytes != null) entry.rxBytes += rxBytes[i] * overlap / bucketDuration;
|
if (rxBytes != null) entry.rxBytes += rxBytes[i] * overlap / bucketSpan;
|
||||||
if (rxPackets != null) entry.rxPackets += rxPackets[i] * overlap / bucketDuration;
|
if (rxPackets != null) entry.rxPackets += rxPackets[i] * overlap / bucketSpan;
|
||||||
if (txBytes != null) entry.txBytes += txBytes[i] * overlap / bucketDuration;
|
if (txBytes != null) entry.txBytes += txBytes[i] * overlap / bucketSpan;
|
||||||
if (txPackets != null) entry.txPackets += txPackets[i] * overlap / bucketDuration;
|
if (txPackets != null) entry.txPackets += txPackets[i] * overlap / bucketSpan;
|
||||||
if (operations != null) entry.operations += operations[i] * overlap / bucketDuration;
|
if (operations != null) entry.operations += operations[i] * overlap / bucketSpan;
|
||||||
}
|
}
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user