summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2015-03-04 17:14:10 -0800
committerGerrit Code Review <gerrit@cyanogenmod.org>2015-06-29 16:32:01 -0700
commit9ce29a7b47298c6d78cad32d0a9e73c5c61bc424 (patch)
tree5d30922511a2a133f56db8537f39d177588d46c8
parenta805aa2187e57e5b5b8deba72ca9787e68baa6d8 (diff)
downloadandroid_frameworks_base-9ce29a7b47298c6d78cad32d0a9e73c5c61bc424.tar.gz
android_frameworks_base-9ce29a7b47298c6d78cad32d0a9e73c5c61bc424.tar.bz2
android_frameworks_base-9ce29a7b47298c6d78cad32d0a9e73c5c61bc424.zip
Frameworks/base: Add removeAll for ArraySet
Add a simple ArraySet.removeAll(ArraySet) method. This avoids two allocations, a MapCollections helper and an Iterator object, over the removeAll(Collection) code. KeySetManagerService heavily calls removeAll during boot (about 9K times in AOSP). This reduces GC stress and optimizes the removal (about half the time the removed collection has only one element). The removal method in KeySetManagerService is also done under a lock, so that it gates parallelization efforts in PackageManagerService. Bug: 19498314 Change-Id: Ib0e483adfd09831cd66ab19a820ebf6544a2b66f (cherry picked from commit 165174e0d02b75db3acc6d2e510f8f4c4886d35f)
-rw-r--r--core/java/android/util/ArraySet.java20
1 files changed, 20 insertions, 0 deletions
diff --git a/core/java/android/util/ArraySet.java b/core/java/android/util/ArraySet.java
index 68f725e688b..7da3941914f 100644
--- a/core/java/android/util/ArraySet.java
+++ b/core/java/android/util/ArraySet.java
@@ -475,6 +475,26 @@ public final class ArraySet<E> implements Collection<E>, Set<E> {
}
/**
+ * Perform a {@link #remove(Object)} of all values in <var>array</var>
+ * @param array The array whose contents are to be removed.
+ */
+ public boolean removeAll(ArraySet<? extends E> array) {
+ // TODO: If array is sufficiently large, a marking approach might be beneficial. In a first
+ // pass, use the property that the sets are sorted by hash to make this linear passes
+ // (except for hash collisions, which means worst case still n*m), then do one
+ // collection pass into a new array. This avoids binary searches and excessive memcpy.
+ final int N = array.mSize;
+
+ // Note: ArraySet does not make thread-safety guarantees. So instead of OR-ing together all
+ // the single results, compare size before and after.
+ final int originalSize = mSize;
+ for (int i = 0; i < N; i++) {
+ remove(array.valueAt(i));
+ }
+ return originalSize != mSize;
+ }
+
+ /**
* Return the number of items in this array map.
*/
@Override