Merge "Allow selective detailed dumps of caches" into tm-dev
This commit is contained in:
@@ -374,10 +374,6 @@ public class PropertyInvalidatedCache<Query, Result> {
|
|||||||
private static final String TAG = "PropertyInvalidatedCache";
|
private static final String TAG = "PropertyInvalidatedCache";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
private static final boolean VERIFY = false;
|
private static final boolean VERIFY = false;
|
||||||
// If this is true, dumpsys will dump the cache entries along with cache statistics.
|
|
||||||
// Most of the time this causes dumpsys to fail because the output stream is too
|
|
||||||
// large. Only set it to true in development images.
|
|
||||||
private static final boolean DETAILED = false;
|
|
||||||
|
|
||||||
// Per-Cache performance counters. As some cache instances are declared static,
|
// Per-Cache performance counters. As some cache instances are declared static,
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
@@ -1358,7 +1354,69 @@ public class PropertyInvalidatedCache<Query, Result> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dumpContents(PrintWriter pw) {
|
/**
|
||||||
|
* Switches that can be used to control the detail emitted by a cache dump. The
|
||||||
|
* "CONTAINS" switches match if the cache (property) name contains the switch
|
||||||
|
* argument. The "LIKE" switches match if the cache (property) name matches the
|
||||||
|
* switch argument as a regex. The regular expression must match the entire name,
|
||||||
|
* which generally means it may need leading/trailing "." expressions.
|
||||||
|
*/
|
||||||
|
final static String NAME_CONTAINS = "-name-has=";
|
||||||
|
final static String NAME_LIKE = "-name-like=";
|
||||||
|
final static String PROPERTY_CONTAINS = "-property-has=";
|
||||||
|
final static String PROPERTY_LIKE = "-property-like=";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if any argument is a detailed specification switch.
|
||||||
|
*/
|
||||||
|
private static boolean anyDetailed(String[] args) {
|
||||||
|
for (String a : args) {
|
||||||
|
if (a.startsWith(NAME_CONTAINS) || a.startsWith(NAME_LIKE)
|
||||||
|
|| a.startsWith(PROPERTY_CONTAINS) || a.startsWith(PROPERTY_LIKE)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper method to determine if a string matches a switch.
|
||||||
|
*/
|
||||||
|
private static boolean chooses(String arg, String key, String reference, boolean contains) {
|
||||||
|
if (arg.startsWith(key)) {
|
||||||
|
final String value = arg.substring(key.length());
|
||||||
|
if (contains) {
|
||||||
|
return reference.contains(value);
|
||||||
|
} else {
|
||||||
|
return reference.matches(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if this cache should be dumped in detail. This method is not called
|
||||||
|
* unless it has already been determined that there is at least one match requested.
|
||||||
|
*/
|
||||||
|
private boolean showDetailed(String[] args) {
|
||||||
|
for (String a : args) {
|
||||||
|
if (chooses(a, NAME_CONTAINS, cacheName(), true)
|
||||||
|
|| chooses(a, NAME_LIKE, cacheName(), false)
|
||||||
|
|| chooses(a, PROPERTY_CONTAINS, mPropertyName, true)
|
||||||
|
|| chooses(a, PROPERTY_LIKE, mPropertyName, false)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dumpContents(PrintWriter pw, boolean detailed, String[] args) {
|
||||||
|
// If the user has requested specific caches and this is not one of them, return
|
||||||
|
// immediately.
|
||||||
|
if (detailed && !showDetailed(args)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
long invalidateCount;
|
long invalidateCount;
|
||||||
long corkedInvalidates;
|
long corkedInvalidates;
|
||||||
synchronized (sCorkLock) {
|
synchronized (sCorkLock) {
|
||||||
@@ -1386,9 +1444,15 @@ public class PropertyInvalidatedCache<Query, Result> {
|
|||||||
mCache.size(), mMaxEntries, mHighWaterMark, mMissOverflow));
|
mCache.size(), mMaxEntries, mHighWaterMark, mMissOverflow));
|
||||||
pw.println(TextUtils.formatSimple(" Enabled: %s", mDisabled ? "false" : "true"));
|
pw.println(TextUtils.formatSimple(" Enabled: %s", mDisabled ? "false" : "true"));
|
||||||
pw.println("");
|
pw.println("");
|
||||||
|
pw.flush();
|
||||||
|
|
||||||
|
// No specific cache was requested. This is the default, and no details
|
||||||
|
// should be dumped.
|
||||||
|
if (!detailed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Set<Map.Entry<Query, Result>> cacheEntries = mCache.entrySet();
|
Set<Map.Entry<Query, Result>> cacheEntries = mCache.entrySet();
|
||||||
if (!DETAILED || cacheEntries.size() == 0) {
|
if (cacheEntries.size() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1399,17 +1463,34 @@ public class PropertyInvalidatedCache<Query, Result> {
|
|||||||
|
|
||||||
pw.println(TextUtils.formatSimple(" Key: %s\n Value: %s\n", key, value));
|
pw.println(TextUtils.formatSimple(" Key: %s\n Value: %s\n", key, value));
|
||||||
}
|
}
|
||||||
|
pw.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dumps contents of every cache in the process to the provided ParcelFileDescriptor.
|
* Dump the corking status.
|
||||||
|
*/
|
||||||
|
@GuardedBy("sCorkLock")
|
||||||
|
private static void dumpCorkInfo(PrintWriter pw) {
|
||||||
|
ArrayList<Map.Entry<String, Integer>> activeCorks = getActiveCorks();
|
||||||
|
if (activeCorks.size() > 0) {
|
||||||
|
pw.println(" Corking Status:");
|
||||||
|
for (int i = 0; i < activeCorks.size(); i++) {
|
||||||
|
Map.Entry<String, Integer> entry = activeCorks.get(i);
|
||||||
|
pw.println(TextUtils.formatSimple(" Property Name: %s Count: %d",
|
||||||
|
entry.getKey(), entry.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Without arguments, this dumps statistics from every cache in the process to the
|
||||||
|
* provided ParcelFileDescriptor. Optional switches allow the caller to choose
|
||||||
|
* specific caches (selection is by cache name or property name); if these switches
|
||||||
|
* are used then the output includes both cache statistics and cache entries.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static void dumpCacheInfo(@NonNull ParcelFileDescriptor pfd, @NonNull String[] args) {
|
public static void dumpCacheInfo(@NonNull ParcelFileDescriptor pfd, @NonNull String[] args) {
|
||||||
ArrayList<PropertyInvalidatedCache> activeCaches;
|
|
||||||
ArrayList<Map.Entry<String, Integer>> activeCorks;
|
|
||||||
|
|
||||||
try (
|
try (
|
||||||
FileOutputStream fout = new FileOutputStream(pfd.getFileDescriptor());
|
FileOutputStream fout = new FileOutputStream(pfd.getFileDescriptor());
|
||||||
PrintWriter pw = new FastPrintWriter(fout);
|
PrintWriter pw = new FastPrintWriter(fout);
|
||||||
@@ -1419,24 +1500,21 @@ public class PropertyInvalidatedCache<Query, Result> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See if detailed is requested for any cache. If there is a specific detailed request,
|
||||||
|
// then only that cache is reported.
|
||||||
|
boolean detail = anyDetailed(args);
|
||||||
|
|
||||||
|
ArrayList<PropertyInvalidatedCache> activeCaches;
|
||||||
synchronized (sCorkLock) {
|
synchronized (sCorkLock) {
|
||||||
activeCaches = getActiveCaches();
|
activeCaches = getActiveCaches();
|
||||||
activeCorks = getActiveCorks();
|
if (!detail) {
|
||||||
|
dumpCorkInfo(pw);
|
||||||
if (activeCorks.size() > 0) {
|
|
||||||
pw.println(" Corking Status:");
|
|
||||||
for (int i = 0; i < activeCorks.size(); i++) {
|
|
||||||
Map.Entry<String, Integer> entry = activeCorks.get(i);
|
|
||||||
pw.println(TextUtils.formatSimple(" Property Name: %s Count: %d",
|
|
||||||
entry.getKey(), entry.getValue()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < activeCaches.size(); i++) {
|
for (int i = 0; i < activeCaches.size(); i++) {
|
||||||
PropertyInvalidatedCache currentCache = activeCaches.get(i);
|
PropertyInvalidatedCache currentCache = activeCaches.get(i);
|
||||||
currentCache.dumpContents(pw);
|
currentCache.dumpContents(pw, detail, args);
|
||||||
pw.flush();
|
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(TAG, "Failed to dump PropertyInvalidatedCache instances");
|
Log.e(TAG, "Failed to dump PropertyInvalidatedCache instances");
|
||||||
|
|||||||
Reference in New Issue
Block a user