diff options
| -rw-r--r-- | core/java/android/app/PropertyInvalidatedCache.java | 120 |
1 files changed, 99 insertions, 21 deletions
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java index add891d40d95..b49e571f74e1 100644 --- a/core/java/android/app/PropertyInvalidatedCache.java +++ b/core/java/android/app/PropertyInvalidatedCache.java @@ -374,10 +374,6 @@ public class PropertyInvalidatedCache<Query, Result> { private static final String TAG = "PropertyInvalidatedCache"; private static final boolean DEBUG = 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, @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 corkedInvalidates; synchronized (sCorkLock) { @@ -1386,9 +1444,15 @@ public class PropertyInvalidatedCache<Query, Result> { mCache.size(), mMaxEntries, mHighWaterMark, mMissOverflow)); pw.println(TextUtils.formatSimple(" Enabled: %s", mDisabled ? "false" : "true")); 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(); - if (!DETAILED || cacheEntries.size() == 0) { + if (cacheEntries.size() == 0) { return; } @@ -1399,17 +1463,34 @@ public class PropertyInvalidatedCache<Query, Result> { pw.println(TextUtils.formatSimple(" Key: %s\n Value: %s\n", key, value)); } + pw.flush(); + } + } + + /** + * 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())); + } } } /** - * Dumps contents of every cache in the process to the provided ParcelFileDescriptor. + * 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 */ public static void dumpCacheInfo(@NonNull ParcelFileDescriptor pfd, @NonNull String[] args) { - ArrayList<PropertyInvalidatedCache> activeCaches; - ArrayList<Map.Entry<String, Integer>> activeCorks; - try ( FileOutputStream fout = new FileOutputStream(pfd.getFileDescriptor()); PrintWriter pw = new FastPrintWriter(fout); @@ -1419,24 +1500,21 @@ public class PropertyInvalidatedCache<Query, Result> { 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) { activeCaches = getActiveCaches(); - 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())); - } + if (!detail) { + dumpCorkInfo(pw); } } for (int i = 0; i < activeCaches.size(); i++) { PropertyInvalidatedCache currentCache = activeCaches.get(i); - currentCache.dumpContents(pw); - pw.flush(); + currentCache.dumpContents(pw, detail, args); } } catch (IOException e) { Log.e(TAG, "Failed to dump PropertyInvalidatedCache instances"); |