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

Commit 339bbc40 authored by Tim Murray's avatar Tim Murray
Browse files

WakeLogLog: remove expensive mSavedAcquisitions work

Optimize WakeLockLog to use a TreeMap instead of ArrayList and avoid
O(n) comparisons.

Test: atest WakeLockLogTest
Flag: EXEMPT bugfix
Bug: 441327741

Change-Id: I4a216fef80561165d33357323b9d4c7f678420d9
parent 3b4e340c
Loading
Loading
Loading
Loading
+34 −28
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.power;

import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.PowerManager;
@@ -29,14 +30,12 @@ import com.android.internal.os.BackgroundThread;

import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.TreeMap;

/**
 * Simple Log for wake lock events. Optimized to reduce memory usage.
@@ -194,16 +193,9 @@ final class WakeLockLog {
                int numEvents = 0;
                int numResets = 0;
                SparseArray<String[]> uidToPackagesCache = new SparseArray();

                for (int i = 0; i < mLog.mSavedAcquisitions.size(); i++) {
                for (LogEntry entry : mLog.mSavedAcquisitions.values()) {
                    numEvents++;
                    LogEntry entry = mLog.mSavedAcquisitions.get(i);

                    entry.updatePackageName(uidToPackagesCache, mContext.getPackageManager());

                    if (DEBUG) {
                        pw.print("Saved acquisition no. " + i);
                    }
                    entry.dump(pw, mDumpsysDateFormat);
                }

@@ -829,7 +821,7 @@ final class WakeLockLog {
         * Wake lock acquisition events should continue to be printed until their corresponding
         * release event is removed from the log.
         */
        private final List<LogEntry> mSavedAcquisitions;
        private final TreeMap<TagData, LogEntry> mSavedAcquisitions;

        TheLog(Injector injector, EntryByteTranslator translator, TagDatabase tagDatabase) {
            final int logSize = Math.max(injector.getLogSize(), LOG_SIZE_MIN);
@@ -846,7 +838,7 @@ final class WakeLockLog {
                }
            });

            mSavedAcquisitions = new ArrayList();
            mSavedAcquisitions = new TreeMap<TagData, LogEntry>();
        }

        /**
@@ -1065,17 +1057,15 @@ final class WakeLockLog {

            // Copy the contents of the start of the buffer to our temporary buffer.
            LogEntry entry = readEntryAt(mStart, mStartTime, null);

            if (entry.tag != null) {
                if (entry.type == TYPE_ACQUIRE) {
                // We'll continue to print the event until the corresponding release event is also
                // removed from the log.
                mSavedAcquisitions.add(entry);
                    // We'll continue to print the event until the corresponding release event is
                    // also removed from the log.
                    mSavedAcquisitions.put(entry.tag, entry);
                } else if (entry.type == TYPE_RELEASE) {
                    // We no longer need to print the corresponding acquire event.
                for (int i = 0; i < mSavedAcquisitions.size(); i++) {
                    if (Objects.equals(mSavedAcquisitions.get(i).tag, entry.tag)) {
                        mSavedAcquisitions.remove(i);
                        break;
                    }
                    LogEntry removed = mSavedAcquisitions.remove(entry.tag);
                }
            }
            if (DEBUG) {
@@ -1365,8 +1355,8 @@ final class WakeLockLog {
     * Contains both the wake lock tag data (tag + ownerUid) as well as index and last-used
     * time data as it relates to the tag-database.
     */
    static class TagData {
        public String tag;  // Wake lock tag
    static class TagData implements Comparable<TagData> {
        @Nullable public String tag;  // Wake lock tag
        public int ownerUid;  // Wake lock owner Uid
        public int index;  // Index of the tag in the tag-database
        public long lastUsedTime;  // Last time that this entry was used
@@ -1381,9 +1371,9 @@ final class WakeLockLog {
            if (this == o) {
                return true;
            }
            if (o instanceof TagData) {
            if (o != null && o instanceof TagData) {
                TagData other = (TagData) o;
                return TextUtils.equals(tag, other.tag) && ownerUid == other.ownerUid;
                return ownerUid == other.ownerUid && TextUtils.equals(tag, other.tag);
            }
            return false;
        }
@@ -1408,6 +1398,22 @@ final class WakeLockLog {
            bytes += 8;  // lastUsedTime
            return bytes;
        }

        @Override
        public int hashCode() {
            int result = ownerUid;
            result = 31 * result + tag.hashCode();
            return result;
        }

        @Override
        public int compareTo(TagData other) {
            if (other == null) {
                return -1;
            }
            return Long.compare(lastUsedTime, other.lastUsedTime);
        }

    }

    /**