• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.app.procstats;
18 
19 import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE;
20 import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT;
21 import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM;
22 import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM;
23 import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_AVERAGE;
24 import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MAXIMUM;
25 import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MINIMUM;
26 import static com.android.internal.app.procstats.ProcessStats.PSS_SAMPLE_COUNT;
27 import static com.android.internal.app.procstats.ProcessStats.PSS_USS_AVERAGE;
28 import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MAXIMUM;
29 import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MINIMUM;
30 
31 import android.service.procstats.ProcessStatsStateProto;
32 import android.util.proto.ProtoOutputStream;
33 import android.util.proto.ProtoUtils;
34 
35 /**
36  * Class to accumulate PSS data.
37  */
38 public class PssTable extends SparseMappingTable.Table {
39     /**
40      * Construct the PssTable with 'tableData' as backing store
41      * for the longs data.
42      */
PssTable(SparseMappingTable tableData)43     public PssTable(SparseMappingTable tableData) {
44         super(tableData);
45     }
46 
47     /**
48      * Merge the the values from the other table into this one.
49      */
mergeStats(PssTable that)50     public void mergeStats(PssTable that) {
51         final int N = that.getKeyCount();
52         for (int i=0; i<N; i++) {
53             final int thatKey = that.getKeyAt(i);
54             final int state = SparseMappingTable.getIdFromKey(thatKey);
55 
56             final int key = getOrAddKey((byte)state, PSS_COUNT);
57             final long[] stats = getArrayForKey(key);
58             final int statsIndex = SparseMappingTable.getIndexFromKey(key);
59 
60             final long[] thatStats = that.getArrayForKey(thatKey);
61             final int thatStatsIndex = SparseMappingTable.getIndexFromKey(thatKey);
62 
63             mergeStats(stats, statsIndex, thatStats, thatStatsIndex);
64         }
65     }
66 
67     /**
68      * Merge the supplied PSS data in.  The new min pss will be the minimum of the existing
69      * one and the new one, the average will now incorporate the new average, etc.
70      */
mergeStats(int state, int inCount, long minPss, long avgPss, long maxPss, long minUss, long avgUss, long maxUss, long minRss, long avgRss, long maxRss)71     public void mergeStats(int state, int inCount, long minPss, long avgPss, long maxPss,
72             long minUss, long avgUss, long maxUss, long minRss, long avgRss, long maxRss) {
73         final int key = getOrAddKey((byte)state, PSS_COUNT);
74         final long[] stats = getArrayForKey(key);
75         final int statsIndex = SparseMappingTable.getIndexFromKey(key);
76         mergeStats(stats, statsIndex, inCount, minPss, avgPss, maxPss, minUss, avgUss, maxUss,
77                 minRss, avgRss, maxRss);
78     }
79 
mergeStats(final long[] stats, final int statsIndex, final long[] thatStats, int thatStatsIndex)80     public static void mergeStats(final long[] stats, final int statsIndex,
81             final long[] thatStats, int thatStatsIndex) {
82         mergeStats(stats, statsIndex, (int)thatStats[thatStatsIndex + PSS_SAMPLE_COUNT],
83                 thatStats[thatStatsIndex + PSS_MINIMUM],
84                 thatStats[thatStatsIndex + PSS_AVERAGE],
85                 thatStats[thatStatsIndex + PSS_MAXIMUM],
86                 thatStats[thatStatsIndex + PSS_USS_MINIMUM],
87                 thatStats[thatStatsIndex + PSS_USS_AVERAGE],
88                 thatStats[thatStatsIndex + PSS_USS_MAXIMUM],
89                 thatStats[thatStatsIndex + PSS_RSS_MINIMUM],
90                 thatStats[thatStatsIndex + PSS_RSS_AVERAGE],
91                 thatStats[thatStatsIndex + PSS_RSS_MAXIMUM]);
92     }
93 
mergeStats(final long[] stats, final int statsIndex, final int inCount, final long minPss, final long avgPss, final long maxPss, final long minUss, final long avgUss, final long maxUss, final long minRss, final long avgRss, final long maxRss)94     public static void mergeStats(final long[] stats, final int statsIndex, final int inCount,
95             final long minPss, final long avgPss, final long maxPss,
96             final long minUss, final long avgUss, final long maxUss,
97             final long minRss, final long avgRss, final long maxRss) {
98         final long count = stats[statsIndex + PSS_SAMPLE_COUNT];
99         if (count == 0) {
100             stats[statsIndex + PSS_SAMPLE_COUNT] = inCount;
101             stats[statsIndex + PSS_MINIMUM] = minPss;
102             stats[statsIndex + PSS_AVERAGE] = avgPss;
103             stats[statsIndex + PSS_MAXIMUM] = maxPss;
104             stats[statsIndex + PSS_USS_MINIMUM] = minUss;
105             stats[statsIndex + PSS_USS_AVERAGE] = avgUss;
106             stats[statsIndex + PSS_USS_MAXIMUM] = maxUss;
107             stats[statsIndex + PSS_RSS_MINIMUM] = minRss;
108             stats[statsIndex + PSS_RSS_AVERAGE] = avgRss;
109             stats[statsIndex + PSS_RSS_MAXIMUM] = maxRss;
110         } else {
111             stats[statsIndex + PSS_SAMPLE_COUNT] = count + inCount;
112 
113             if (stats[statsIndex + PSS_MINIMUM] > minPss) {
114                 stats[statsIndex + PSS_MINIMUM] = minPss;
115             }
116 
117             stats[statsIndex + PSS_AVERAGE] = (long)(((stats[statsIndex + PSS_AVERAGE]
118                     * (double)count) + (avgPss * (double)inCount)) / (count + inCount));
119 
120             if (stats[statsIndex + PSS_MAXIMUM] < maxPss) {
121                 stats[statsIndex + PSS_MAXIMUM] = maxPss;
122             }
123 
124             if (stats[statsIndex + PSS_USS_MINIMUM] > minUss) {
125                 stats[statsIndex + PSS_USS_MINIMUM] = minUss;
126             }
127 
128             stats[statsIndex + PSS_USS_AVERAGE] = (long)(((stats[statsIndex + PSS_USS_AVERAGE]
129                     * (double)count) + (avgUss * (double)inCount)) / (count + inCount));
130 
131             if (stats[statsIndex + PSS_USS_MAXIMUM] < maxUss) {
132                 stats[statsIndex + PSS_USS_MAXIMUM] = maxUss;
133             }
134 
135             if (stats[statsIndex + PSS_RSS_MINIMUM] > minRss) {
136             }
137 
138             stats[statsIndex + PSS_RSS_AVERAGE] = (long)(((stats[statsIndex + PSS_RSS_AVERAGE]
139                     * (double)count) + (avgRss * (double)inCount)) / (count + inCount));
140 
141             if (stats[statsIndex + PSS_RSS_MAXIMUM] < maxRss) {
142                 stats[statsIndex + PSS_RSS_MAXIMUM] = maxRss;
143             }
144         }
145     }
146 
writeStatsToProtoForKey(ProtoOutputStream proto, int key)147     public void writeStatsToProtoForKey(ProtoOutputStream proto, int key) {
148         final long[] stats = getArrayForKey(key);
149         final int statsIndex = SparseMappingTable.getIndexFromKey(key);
150         writeStatsToProto(proto, stats, statsIndex);
151     }
152 
writeStatsToProto(ProtoOutputStream proto, final long[] stats, final int statsIndex)153     public static void writeStatsToProto(ProtoOutputStream proto, final long[] stats,
154             final int statsIndex) {
155         proto.write(ProcessStatsStateProto.SAMPLE_SIZE, stats[statsIndex + PSS_SAMPLE_COUNT]);
156         ProtoUtils.toAggStatsProto(proto, ProcessStatsStateProto.PSS,
157                 stats[statsIndex + PSS_MINIMUM],
158                 stats[statsIndex + PSS_AVERAGE],
159                 stats[statsIndex + PSS_MAXIMUM]);
160         ProtoUtils.toAggStatsProto(proto, ProcessStatsStateProto.USS,
161                 stats[statsIndex + PSS_USS_MINIMUM],
162                 stats[statsIndex + PSS_USS_AVERAGE],
163                 stats[statsIndex + PSS_USS_MAXIMUM]);
164         ProtoUtils.toAggStatsProto(proto, ProcessStatsStateProto.RSS,
165                 stats[statsIndex + PSS_RSS_MINIMUM],
166                 stats[statsIndex + PSS_RSS_AVERAGE],
167                 stats[statsIndex + PSS_RSS_MAXIMUM]);
168     }
169 
getRssMeanAndMax(int key)170     long[] getRssMeanAndMax(int key) {
171         final long[] stats = getArrayForKey(key);
172         final int statsIndex = SparseMappingTable.getIndexFromKey(key);
173         return new long[]{stats[statsIndex + PSS_RSS_AVERAGE], stats[statsIndex + PSS_RSS_MAXIMUM]};
174     }
175 }
176