diff options
| author | 2011-09-11 17:33:14 -0700 | |
|---|---|---|
| committer | 2011-09-12 16:13:20 -0700 | |
| commit | 69b0f63af2e3babc2e9f048c4682032a0c17d9d0 (patch) | |
| tree | bd8a475fbaa2ca320f0cafaea40ba16c54111074 | |
| parent | 1d50a2c0682926f783f9acab5c4bdeca1d3cb9cd (diff) | |
Data usage structure optimizations.
Driven by traceview hotspots found in Settings UI.
Change-Id: I614a049523c526b7fcd12fffdf53a3e4723623e4
5 files changed, 135 insertions, 50 deletions
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index d07d8990d716..d8ac31f277a0 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 b888d9a22316..e1db073c0713 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); diff --git a/services/tests/servicestests/res/raw/xt_qtaguid_extended b/services/tests/servicestests/res/raw/xt_qtaguid_extended index 5bef3dd75216..2f3b4ecd63bf 100644 --- a/services/tests/servicestests/res/raw/xt_qtaguid_extended +++ b/services/tests/servicestests/res/raw/xt_qtaguid_extended @@ -1,3 +1,3 @@ -acct_tag_hex uid_tag_int iface rx_bytes rx_packets tx_bytes tx_packets teleported_goats -0x0 1000 test0 1024 10 2048 20 2716057 -0x0000F00D00000000 1000 test0 512 5 512 5 3370318 +acct_tag_hex uid_tag_int iface rx_bytes rx_packets tx_bytes tx_packets teleported_goats idx +0x0 1000 test0 1024 10 2048 20 2716057 2 +0x0000F00D00000000 1000 test0 512 5 512 5 3370318 3 diff --git a/services/tests/servicestests/res/raw/xt_qtaguid_typical b/services/tests/servicestests/res/raw/xt_qtaguid_typical index 7c4f04e1fb3a..8df4b1b06d0b 100644 --- a/services/tests/servicestests/res/raw/xt_qtaguid_typical +++ b/services/tests/servicestests/res/raw/xt_qtaguid_typical @@ -1,32 +1,32 @@ idx iface acct_tag_hex uid_tag_int rx_bytes tx_bytes -1 wlan0 0x0 0 14615 4270 -2 wlan0 0x0 1000 5175 915 -3 wlan0 0x0 1021 3381 903 -4 wlan0 0x0 10004 333821 53558 -5 wlan0 0x0 10010 4888 37363 -6 wlan0 0x0 10013 52 104 -7 wlan0 0x74182ada00000000 10004 18725 1066 -8 rmnet0 0x0 0 301274 30244 -9 rmnet0 0x0 1000 304 441 -10 rmnet0 0x0 1013 2880 2272 -11 rmnet0 0x0 1021 31407 8430 -12 rmnet0 0x0 10003 32665 3814 -13 rmnet0 0x0 10004 2373141 420112 -14 rmnet0 0x0 10010 870370 1111727 -15 rmnet0 0x0 10013 240 240 -16 rmnet0 0x0 10016 16703 13512 -17 rmnet0 0x0 10017 3990 3269 -18 rmnet0 0x0 10018 474504 14516062 -19 rmnet0 0x0 10019 782804 71077 -20 rmnet0 0x0 10022 70671 49684 -21 rmnet0 0x0 10029 5785354 397159 -22 rmnet0 0x0 10033 2102 1686 -23 rmnet0 0x0 10034 15495464 227694 -24 rmnet0 0x0 10037 31184994 684122 -25 rmnet0 0x0 10051 298687 113485 -26 rmnet0 0x0 10056 29504 20669 -27 rmnet0 0x0 10069 683 596 -28 rmnet0 0x0 10072 34051 12453 -29 rmnet0 0x0 10077 7025393 213866 -30 rmnet0 0x0 10081 354 1178 -31 rmnet0 0x74182ada00000000 10037 28507378 437004 +2 wlan0 0x0 0 14615 4270 +3 wlan0 0x0 1000 5175 915 +4 wlan0 0x0 1021 3381 903 +5 wlan0 0x0 10004 333821 53558 +6 wlan0 0x0 10010 4888 37363 +7 wlan0 0x0 10013 52 104 +8 wlan0 0x74182ada00000000 10004 18725 1066 +9 rmnet0 0x0 0 301274 30244 +10 rmnet0 0x0 1000 304 441 +11 rmnet0 0x0 1013 2880 2272 +12 rmnet0 0x0 1021 31407 8430 +13 rmnet0 0x0 10003 32665 3814 +14 rmnet0 0x0 10004 2373141 420112 +15 rmnet0 0x0 10010 870370 1111727 +16 rmnet0 0x0 10013 240 240 +17 rmnet0 0x0 10016 16703 13512 +18 rmnet0 0x0 10017 3990 3269 +19 rmnet0 0x0 10018 474504 14516062 +20 rmnet0 0x0 10019 782804 71077 +21 rmnet0 0x0 10022 70671 49684 +22 rmnet0 0x0 10029 5785354 397159 +23 rmnet0 0x0 10033 2102 1686 +24 rmnet0 0x0 10034 15495464 227694 +25 rmnet0 0x0 10037 31184994 684122 +26 rmnet0 0x0 10051 298687 113485 +27 rmnet0 0x0 10056 29504 20669 +28 rmnet0 0x0 10069 683 596 +29 rmnet0 0x0 10072 34051 12453 +30 rmnet0 0x0 10077 7025393 213866 +31 rmnet0 0x0 10081 354 1178 +32 rmnet0 0x74182ada00000000 10037 28507378 437004 diff --git a/services/tests/servicestests/res/raw/xt_qtaguid_typical_with_set b/services/tests/servicestests/res/raw/xt_qtaguid_typical_with_set index 3678b101529c..f9f34ac556ed 100644 --- a/services/tests/servicestests/res/raw/xt_qtaguid_typical_with_set +++ b/services/tests/servicestests/res/raw/xt_qtaguid_typical_with_set @@ -1,13 +1,13 @@ idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_packets rx_tcp_bytes rx_udp_packets rx_udp_bytes rx_other_packets rx_other_bytes tx_tcp_packets tx_tcp_bytes tx_udp_packets tx_udp_bytes tx_other_packets tx_other_bytes
-1 rmnet0 0x0 0 0 14855 82 2804 47 2000 45 12799 35 56 2 676 13 2128 34 0 0
-1 rmnet0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-2 rmnet0 0x0 1000 0 278102 253 10487 182 277342 243 760 10 0 0 9727 172 760 10 0 0
-2 rmnet0 0x0 1000 1 26033 30 1401 26 25881 28 152 2 0 0 1249 24 152 2 0 0
-3 rmnet0 0x0 10012 0 40524 272 134138 293 40524 272 0 0 0 0 134138 293 0 0 0 0
-3 rmnet0 0x0 10012 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-4 rmnet0 0x0 10034 0 15791 59 9905 69 15791 59 0 0 0 0 9905 69 0 0 0 0
-4 rmnet0 0x0 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-5 rmnet0 0x0 10055 0 3602 29 7739 59 3602 29 0 0 0 0 7739 59 0 0 0 0
-5 rmnet0 0x0 10055 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-6 rmnet0 0x7fff000300000000 1000 0 483 4 1931 6 483 4 0 0 0 0 1931 6 0 0 0 0
-6 rmnet0 0x7fff000300000000 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+2 rmnet0 0x0 0 0 14855 82 2804 47 2000 45 12799 35 56 2 676 13 2128 34 0 0
+3 rmnet0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+4 rmnet0 0x0 1000 0 278102 253 10487 182 277342 243 760 10 0 0 9727 172 760 10 0 0
+5 rmnet0 0x0 1000 1 26033 30 1401 26 25881 28 152 2 0 0 1249 24 152 2 0 0
+6 rmnet0 0x0 10012 0 40524 272 134138 293 40524 272 0 0 0 0 134138 293 0 0 0 0
+7 rmnet0 0x0 10012 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+8 rmnet0 0x0 10034 0 15791 59 9905 69 15791 59 0 0 0 0 9905 69 0 0 0 0
+9 rmnet0 0x0 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+10 rmnet0 0x0 10055 0 3602 29 7739 59 3602 29 0 0 0 0 7739 59 0 0 0 0
+11 rmnet0 0x0 10055 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+12 rmnet0 0x7fff000300000000 1000 0 483 4 1931 6 483 4 0 0 0 0 1931 6 0 0 0 0
+13 rmnet0 0x7fff000300000000 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|