OSDN Git Service

Data usage structure optimizations.
authorJeff Sharkey <jsharkey@android.com>
Mon, 12 Sep 2011 00:33:14 +0000 (17:33 -0700)
committerJeff Sharkey <jsharkey@android.com>
Mon, 12 Sep 2011 23:13:20 +0000 (16:13 -0700)
Driven by traceview hotspots found in Settings UI.

Change-Id: I614a049523c526b7fcd12fffdf53a3e4723623e4

core/java/android/net/NetworkStatsHistory.java
core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
services/tests/servicestests/res/raw/xt_qtaguid_extended
services/tests/servicestests/res/raw/xt_qtaguid_typical
services/tests/servicestests/res/raw/xt_qtaguid_typical_with_set

index d07d899..d8ac31f 100644 (file)
@@ -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
index b888d9a..e1db073 100644 (file)
@@ -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);
index 5bef3dd..2f3b4ec 100644 (file)
@@ -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
index 7c4f04e..8df4b1b 100644 (file)
@@ -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
index 3678b10..f9f34ac 100644 (file)
@@ -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\r
-1 rmnet0 0x0 0 0 14855 82 2804 47 2000 45 12799 35 56 2 676 13 2128 34 0 0\r
-1 rmnet0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\r
-2 rmnet0 0x0 1000 0 278102 253 10487 182 277342 243 760 10 0 0 9727 172 760 10 0 0\r
-2 rmnet0 0x0 1000 1 26033 30 1401 26 25881 28 152 2 0 0 1249 24 152 2 0 0\r
-3 rmnet0 0x0 10012 0 40524 272 134138 293 40524 272 0 0 0 0 134138 293 0 0 0 0\r
-3 rmnet0 0x0 10012 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\r
-4 rmnet0 0x0 10034 0 15791 59 9905 69 15791 59 0 0 0 0 9905 69 0 0 0 0\r
-4 rmnet0 0x0 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\r
-5 rmnet0 0x0 10055 0 3602 29 7739 59 3602 29 0 0 0 0 7739 59 0 0 0 0\r
-5 rmnet0 0x0 10055 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\r
-6 rmnet0 0x7fff000300000000 1000 0 483 4 1931 6 483 4 0 0 0 0 1931 6 0 0 0 0\r
-6 rmnet0 0x7fff000300000000 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\r
+2 rmnet0 0x0 0 0 14855 82 2804 47 2000 45 12799 35 56 2 676 13 2128 34 0 0\r
+3 rmnet0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\r
+4 rmnet0 0x0 1000 0 278102 253 10487 182 277342 243 760 10 0 0 9727 172 760 10 0 0\r
+5 rmnet0 0x0 1000 1 26033 30 1401 26 25881 28 152 2 0 0 1249 24 152 2 0 0\r
+6 rmnet0 0x0 10012 0 40524 272 134138 293 40524 272 0 0 0 0 134138 293 0 0 0 0\r
+7 rmnet0 0x0 10012 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\r
+8 rmnet0 0x0 10034 0 15791 59 9905 69 15791 59 0 0 0 0 9905 69 0 0 0 0\r
+9 rmnet0 0x0 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\r
+10 rmnet0 0x0 10055 0 3602 29 7739 59 3602 29 0 0 0 0 7739 59 0 0 0 0\r
+11 rmnet0 0x0 10055 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\r
+12 rmnet0 0x7fff000300000000 1000 0 483 4 1931 6 483 4 0 0 0 0 1931 6 0 0 0 0\r
+13 rmnet0 0x7fff000300000000 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\r