Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a54c615b authored by Lee Shombert's avatar Lee Shombert Committed by Automerger Merge Worker
Browse files

Merge "Allow selective detailed dumps of caches" into tm-dev am: 13eb52a2

parents 3dc281d2 13eb52a2
Loading
Loading
Loading
Loading
+99 −21
Original line number Original line Diff line number Diff line
@@ -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();
        }
    }

    /**
     * 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
     * @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");