diff options
author | Jeff Sharkey <jsharkey@android.com> | 2011-09-11 17:33:14 -0700 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2011-09-12 16:13:20 -0700 |
commit | 69b0f63af2e3babc2e9f048c4682032a0c17d9d0 (patch) | |
tree | bd8a475fbaa2ca320f0cafaea40ba16c54111074 /core | |
parent | 1d50a2c0682926f783f9acab5c4bdeca1d3cb9cd (diff) | |
download | frameworks_base-69b0f63af2e3babc2e9f048c4682032a0c17d9d0.zip frameworks_base-69b0f63af2e3babc2e9f048c4682032a0c17d9d0.tar.gz frameworks_base-69b0f63af2e3babc2e9f048c4682032a0c17d9d0.tar.bz2 |
Data usage structure optimizations.
Driven by traceview hotspots found in Settings UI.
Change-Id: I614a049523c526b7fcd12fffdf53a3e4723623e4
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/net/NetworkStatsHistory.java | 45 | ||||
-rw-r--r-- | core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java | 48 |
2 files changed, 89 insertions, 4 deletions
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index d07d899..d8ac31f 100644 --- a/core/java/android/net/NetworkStatsHistory.java +++ b/core/java/android/net/NetworkStatsHistory.java @@ -29,6 +29,7 @@ import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray; import android.os.Parcel; import android.os.Parcelable; +import android.util.MathUtils; import java.io.CharArrayWriter; import java.io.DataInputStream; @@ -207,6 +208,34 @@ public class NetworkStatsHistory implements Parcelable { } /** + * Return index of bucket that contains or is immediately before the + * requested time. + */ + public int getIndexBefore(long time) { + int index = Arrays.binarySearch(bucketStart, 0, bucketCount, time); + if (index < 0) { + index = (~index) - 1; + } else { + index -= 1; + } + return MathUtils.constrain(index, 0, bucketCount - 1); + } + + /** + * Return index of bucket that contains or is immediately after the + * requested time. + */ + public int getIndexAfter(long time) { + int index = Arrays.binarySearch(bucketStart, 0, bucketCount, time); + if (index < 0) { + index = ~index; + } else { + index += 1; + } + return MathUtils.constrain(index, 0, bucketCount - 1); + } + + /** * Return specific stats entry. */ public Entry getValues(int i, Entry recycle) { @@ -247,7 +276,8 @@ public class NetworkStatsHistory implements Parcelable { // distribute data usage into buckets long duration = end - start; - for (int i = bucketCount - 1; i >= 0; i--) { + final int startIndex = getIndexAfter(end); + for (int i = startIndex; i >= 0; i--) { final long curStart = bucketStart[i]; final long curEnd = curStart + bucketDuration; @@ -406,7 +436,8 @@ public class NetworkStatsHistory implements Parcelable { entry.txPackets = txPackets != null ? 0 : UNKNOWN; entry.operations = operations != null ? 0 : UNKNOWN; - for (int i = bucketCount - 1; i >= 0; i--) { + final int startIndex = getIndexAfter(end); + for (int i = startIndex; i >= 0; i--) { final long curStart = bucketStart[i]; final long curEnd = curStart + bucketDuration; @@ -417,8 +448,14 @@ public class NetworkStatsHistory implements Parcelable { // include full value for active buckets, otherwise only fractional final boolean activeBucket = curStart < now && curEnd > now; - final long overlap = activeBucket ? bucketDuration - : Math.min(curEnd, end) - Math.max(curStart, start); + final long overlap; + if (activeBucket) { + overlap = bucketDuration; + } else { + final long overlapEnd = curEnd < end ? curEnd : end; + final long overlapStart = curStart > start ? curStart : start; + overlap = overlapEnd - overlapStart; + } if (overlap <= 0) continue; // integer math each time is faster than floating point diff --git a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java index b888d9a..e1db073 100644 --- a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java +++ b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java @@ -407,6 +407,54 @@ public class NetworkStatsHistoryTest extends AndroidTestCase { assertEquals(Long.MAX_VALUE - 40, performVarLong(Long.MAX_VALUE - 40)); } + public void testIndexBeforeAfter() throws Exception { + final long BUCKET_SIZE = HOUR_IN_MILLIS; + stats = new NetworkStatsHistory(BUCKET_SIZE); + + final long FIRST_START = TEST_START; + final long FIRST_END = FIRST_START + (2 * HOUR_IN_MILLIS); + final long SECOND_START = TEST_START + WEEK_IN_MILLIS; + final long SECOND_END = SECOND_START + HOUR_IN_MILLIS; + final long THIRD_START = TEST_START + (2 * WEEK_IN_MILLIS); + final long THIRD_END = THIRD_START + (2 * HOUR_IN_MILLIS); + + stats.recordData(FIRST_START, FIRST_END, + new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); + stats.recordData(SECOND_START, SECOND_END, + new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); + stats.recordData(THIRD_START, THIRD_END, + new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); + + // should have buckets: 2+1+2 + assertEquals(5, stats.size()); + + assertIndexBeforeAfter(stats, 0, 0, Long.MIN_VALUE); + assertIndexBeforeAfter(stats, 0, 1, FIRST_START); + assertIndexBeforeAfter(stats, 0, 1, FIRST_START + MINUTE_IN_MILLIS); + assertIndexBeforeAfter(stats, 0, 2, FIRST_START + HOUR_IN_MILLIS); + assertIndexBeforeAfter(stats, 1, 2, FIRST_START + HOUR_IN_MILLIS + MINUTE_IN_MILLIS); + assertIndexBeforeAfter(stats, 1, 2, FIRST_END - MINUTE_IN_MILLIS); + assertIndexBeforeAfter(stats, 1, 2, FIRST_END); + assertIndexBeforeAfter(stats, 1, 2, FIRST_END + MINUTE_IN_MILLIS); + assertIndexBeforeAfter(stats, 1, 2, SECOND_START - MINUTE_IN_MILLIS); + assertIndexBeforeAfter(stats, 1, 3, SECOND_START); + assertIndexBeforeAfter(stats, 2, 3, SECOND_END); + assertIndexBeforeAfter(stats, 2, 3, SECOND_END + MINUTE_IN_MILLIS); + assertIndexBeforeAfter(stats, 2, 3, THIRD_START - MINUTE_IN_MILLIS); + assertIndexBeforeAfter(stats, 2, 4, THIRD_START); + assertIndexBeforeAfter(stats, 3, 4, THIRD_START + MINUTE_IN_MILLIS); + assertIndexBeforeAfter(stats, 3, 4, THIRD_START + HOUR_IN_MILLIS); + assertIndexBeforeAfter(stats, 4, 4, THIRD_END); + assertIndexBeforeAfter(stats, 4, 4, THIRD_END + MINUTE_IN_MILLIS); + assertIndexBeforeAfter(stats, 4, 4, Long.MAX_VALUE); + } + + private static void assertIndexBeforeAfter( + NetworkStatsHistory stats, int before, int after, long time) { + assertEquals("unexpected before", before, stats.getIndexBefore(time)); + assertEquals("unexpected after", after, stats.getIndexAfter(time)); + } + private static long performVarLong(long before) throws Exception { final ByteArrayOutputStream out = new ByteArrayOutputStream(); writeVarLong(new DataOutputStream(out), before); |