135 lines
5.2 KiB
Java
135 lines
5.2 KiB
Java
![]() |
/*
|
||
|
* Copyright (C) 2018 The Android Open Source Project
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
package com.android.internal.util;
|
||
|
|
||
|
import android.os.SystemClock;
|
||
|
import android.util.SparseBooleanArray;
|
||
|
import android.util.SparseLongArray;
|
||
|
|
||
|
import java.io.PrintWriter;
|
||
|
|
||
|
public class ProviderAccessStats {
|
||
|
private final Object mLock = new Object();
|
||
|
|
||
|
private final long mStartUptime = SystemClock.uptimeMillis();
|
||
|
|
||
|
private final SparseBooleanArray mAllCallingUids = new SparseBooleanArray();
|
||
|
private final SparseLongArray mQueryStats = new SparseLongArray(16);
|
||
|
private final SparseLongArray mBatchStats = new SparseLongArray(0);
|
||
|
private final SparseLongArray mInsertStats = new SparseLongArray(0);
|
||
|
private final SparseLongArray mUpdateStats = new SparseLongArray(0);
|
||
|
private final SparseLongArray mDeleteStats = new SparseLongArray(0);
|
||
|
private final SparseLongArray mInsertInBatchStats = new SparseLongArray(0);
|
||
|
private final SparseLongArray mUpdateInBatchStats = new SparseLongArray(0);
|
||
|
private final SparseLongArray mDeleteInBatchStats = new SparseLongArray(0);
|
||
|
|
||
|
private final SparseLongArray mOperationDurationMillis = new SparseLongArray(16);
|
||
|
|
||
|
private static class PerThreadData {
|
||
|
public int nestCount;
|
||
|
public long startUptimeMillis;
|
||
|
}
|
||
|
|
||
|
private final ThreadLocal<PerThreadData> mThreadLocal =
|
||
|
ThreadLocal.withInitial(() -> new PerThreadData());
|
||
|
|
||
|
private void incrementStats(int callingUid, SparseLongArray stats) {
|
||
|
synchronized (mLock) {
|
||
|
stats.put(callingUid, stats.get(callingUid) + 1);
|
||
|
mAllCallingUids.put(callingUid, true);
|
||
|
}
|
||
|
|
||
|
final PerThreadData data = mThreadLocal.get();
|
||
|
data.nestCount++;
|
||
|
if (data.nestCount == 1) {
|
||
|
data.startUptimeMillis = SystemClock.uptimeMillis();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void incrementStats(int callingUid, boolean inBatch,
|
||
|
SparseLongArray statsNonBatch, SparseLongArray statsInBatch) {
|
||
|
incrementStats(callingUid, inBatch ? statsInBatch : statsNonBatch);
|
||
|
}
|
||
|
|
||
|
public final void incrementInsertStats(int callingUid, boolean inBatch) {
|
||
|
incrementStats(callingUid, inBatch, mInsertStats, mInsertInBatchStats);
|
||
|
}
|
||
|
|
||
|
public final void incrementUpdateStats(int callingUid, boolean inBatch) {
|
||
|
incrementStats(callingUid, inBatch, mUpdateStats, mUpdateInBatchStats);
|
||
|
}
|
||
|
|
||
|
public final void incrementDeleteStats(int callingUid, boolean inBatch) {
|
||
|
incrementStats(callingUid, inBatch, mDeleteStats, mDeleteInBatchStats);
|
||
|
}
|
||
|
|
||
|
public final void incrementQueryStats(int callingUid) {
|
||
|
incrementStats(callingUid, mQueryStats);
|
||
|
}
|
||
|
|
||
|
public final void incrementBatchStats(int callingUid) {
|
||
|
incrementStats(callingUid, mBatchStats);
|
||
|
}
|
||
|
|
||
|
public void finishOperation(int callingUid) {
|
||
|
final PerThreadData data = mThreadLocal.get();
|
||
|
data.nestCount--;
|
||
|
if (data.nestCount == 0) {
|
||
|
// Because we only have millisecond granularity, let's always attribute at least 1ms
|
||
|
// for each operation.
|
||
|
final long duration = Math.max(1, SystemClock.uptimeMillis() - data.startUptimeMillis);
|
||
|
|
||
|
synchronized (mLock) {
|
||
|
mOperationDurationMillis.put(callingUid,
|
||
|
mOperationDurationMillis.get(callingUid) + duration);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void dump(PrintWriter pw, String prefix) {
|
||
|
synchronized (mLock) {
|
||
|
pw.print(" Process uptime: ");
|
||
|
pw.print((SystemClock.uptimeMillis() - mStartUptime) / (60 * 1000));
|
||
|
pw.println(" minutes");
|
||
|
pw.println();
|
||
|
|
||
|
pw.print(prefix);
|
||
|
pw.println("Client activities:");
|
||
|
pw.print(prefix);
|
||
|
pw.println(" UID Query Insert Update Delete Batch Insert Update Delete"
|
||
|
+ " Sec");
|
||
|
for (int i = 0; i < mAllCallingUids.size(); i++) {
|
||
|
final int uid = mAllCallingUids.keyAt(i);
|
||
|
pw.print(prefix);
|
||
|
pw.println(String.format(
|
||
|
" %-9d %6d %6d %6d %6d %6d %6d %6d %6d %12.3f",
|
||
|
uid,
|
||
|
mQueryStats.get(uid),
|
||
|
mInsertStats.get(uid),
|
||
|
mUpdateStats.get(uid),
|
||
|
mDeleteStats.get(uid),
|
||
|
mBatchStats.get(uid),
|
||
|
mInsertInBatchStats.get(uid),
|
||
|
mUpdateInBatchStats.get(uid),
|
||
|
mDeleteInBatchStats.get(uid),
|
||
|
(mOperationDurationMillis.get(uid) / 1000.0)
|
||
|
));
|
||
|
}
|
||
|
pw.println();
|
||
|
}
|
||
|
}
|
||
|
}
|