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

Commit 0e5ffcd2 authored by Charles Munger's avatar Charles Munger Committed by Android (Google) Code Review
Browse files

Merge "Always clear heap index when removing items" into main

parents 01c939e0 7aa6729b
Loading
Loading
Loading
Loading
+15 −12
Original line number Diff line number Diff line
@@ -91,11 +91,12 @@ public final class MessageHeap {
    }

    private void swap(int x, int y) {
        Message tmp = mHeap[x];
        mHeap[x] = mHeap[y];
        mHeap[y] = tmp;
        mHeap[x].heapIndex = x;
        mHeap[y].heapIndex = y;
        Message newX = mHeap[y];
        Message newY = mHeap[x];
        mHeap[x] = newX;
        mHeap[y] = newY;
        newX.heapIndex = x;
        newY.heapIndex = y;
    }

    private void siftDown(int i) {
@@ -205,6 +206,7 @@ public final class MessageHeap {
            mHeap[0] = mHeap[mNumElements];
            mHeap[0].heapIndex = 0;
            mHeap[mNumElements] = null;
            ret.heapIndex = -1;

            siftDown(0);

@@ -222,11 +224,12 @@ public final class MessageHeap {
        if (i >= mNumElements || mNumElements == 0 || i < 0) {
            throw new IllegalArgumentException("Index " + i + " out of bounds: "
                    + mNumElements);
        } else if (i == (mNumElements - 1)) {
            mHeap[i] = null;
        }
        mNumElements--;
        mHeap[i].heapIndex = -1;
        if (i == mNumElements) {
            mHeap[i] = null;
        } else {
            mNumElements--;
            mHeap[i] = mHeap[mNumElements];
            mHeap[i].heapIndex = i;
            mHeap[mNumElements] = null;
@@ -234,17 +237,17 @@ public final class MessageHeap {
                siftDown(i);
            }
        }
        /* Don't shink here, let the caller do this once it has removed all matching items. */
        /* Don't shrink here, let the caller do this once it has removed all matching items. */
    }

    public void removeMessage(@NonNull Message m) throws IllegalArgumentException {
        // We set this index to be out of range so that we don't attempt to remove this message from
        // the heap a second time (e.g. when it's processed on the MessageStack freelist).
        remove(m.heapIndex);
        m.heapIndex = -1;
    }

    public void removeAll() {
        for (int i = 0; i < mNumElements; i++) {
            mHeap[i].heapIndex = -1;
        }
        mHeap = new Message[INITIAL_SIZE];
        mNumElements = 0;
    }
+17 −22
Original line number Diff line number Diff line
@@ -228,7 +228,8 @@ public final class MessageStack {
        while (current != null) {
            Message nextFree = current.nextFree;
            current.nextFree = null;
            removeMessage(current, /* removeFromHeap= */ true);
            maybeRemoveFromHeap(current);
            removeFromStack(current);
            current = nextFree;
        }
    }
@@ -248,7 +249,7 @@ public final class MessageStack {
            if (!m.markRemoved()) {
                return null;
            }
            removeMessage(m, /* removeFromHeap= */ false);
            removeFromStack(m);
        }
        return m;
    }
@@ -264,24 +265,22 @@ public final class MessageStack {
        }
    }

    /**
     * Remove a message from the stack.
     *
     * removeFromHeap indicates if the message should be removed from the heap (if this message is
     * being drained from the freelist) or not (if this message was retrieved using
     * MessageHeap.pop()).
     */
    private void removeMessage(Message m, boolean removeFromHeap) {
        // An out of range heapIndex means that we've already removed this message from the heap
        // during the MessageHeap.peek() loop in peek().
        if (removeFromHeap && m.heapIndex >= 0) {
    private void maybeRemoveFromHeap(Message m) {
        // An out of range heapIndex means that we've already removed this message from the heap, or
        // it was never added to the heap in the first place.
        if (m.heapIndex >= 0) {
            if (m.isAsynchronous()) {
                mAsyncHeap.removeMessage(m);
            } else {
                mSyncHeap.removeMessage(m);
            }
        }
    }

    /**
     * Remove a message from the stack.
     */
    private void removeFromStack(Message m) {
        // mLooperProcessed must be updated to the next message that hasn't been removed.
        if (m == mLooperProcessed) {
            do {
@@ -328,21 +327,16 @@ public final class MessageStack {
     * removed messages.
     */
    public @Nullable Message peek(boolean async) {
        MessageHeap heap = async ? mAsyncHeap : mSyncHeap;
        while (true) {
            final Message m = async ? mAsyncHeap.peek() : mSyncHeap.peek();
            final Message m = heap.peek();
            if (m == null) {
                return null;
            }
            if (!m.isRemoved()) {
                return m;
            }
            if (m.heapIndex >= 0) {
                if (async) {
                    mAsyncHeap.removeMessage(m);
                } else {
                    mSyncHeap.removeMessage(m);
                }
            }
            heap.removeMessage(m);
        }
    }

@@ -352,7 +346,8 @@ public final class MessageStack {
     * This is suitable to use with the output of peek().
     */
    public void remove(Message m) {
        removeMessage(m, /* removeFromHeap= */ true);
        maybeRemoveFromHeap(m);
        removeFromStack(m);
    }

    Message peekLastMessageForTest() {