1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.util;
17 
18 import android.annotation.NonNull;
19 
20 /**
21  * A sparse array of ArraySets, which is suitable to hold userid->packages association.
22  *
23  * @hide
24  */
25 public class SparseSetArray<T> {
26     private final SparseArray<ArraySet<T>> mData;
27 
SparseSetArray()28     public SparseSetArray() {
29         mData = new SparseArray<>();
30     }
31 
32     /**
33      * Copy constructor
34      */
SparseSetArray(@onNull SparseSetArray<T> src)35     public SparseSetArray(@NonNull SparseSetArray<T> src) {
36         final int arraySize = src.size();
37         mData = new SparseArray<>(arraySize);
38         for (int i = 0; i < arraySize; i++) {
39             final int key = src.keyAt(i);
40             final ArraySet<T> set = src.get(key);
41             addAll(key, set);
42         }
43     }
44 
45     /**
46      * Add a value for key n.
47      * @return FALSE when the value already existed for the given key, TRUE otherwise.
48      */
add(int n, T value)49     public boolean add(int n, T value) {
50         ArraySet<T> set = mData.get(n);
51         if (set == null) {
52             set = new ArraySet<>();
53             mData.put(n, set);
54         }
55         if (set.contains(value)) {
56             return false;
57         }
58         set.add(value);
59         return true;
60     }
61 
62     /**
63      * Add a set of values for key n.
64      */
addAll(int n, ArraySet<T> values)65     public void addAll(int n, ArraySet<T> values) {
66         ArraySet<T> set = mData.get(n);
67         if (set == null) {
68             set = new ArraySet<>(values);
69             mData.put(n, set);
70             return;
71         }
72         set.addAll(values);
73     }
74 
75     /**
76      * Removes all mappings from this SparseSetArray.
77      */
clear()78     public void clear() {
79         mData.clear();
80     }
81 
82     /**
83      * @return whether the value exists for the key n.
84      */
contains(int n, T value)85     public boolean contains(int n, T value) {
86         final ArraySet<T> set = mData.get(n);
87         if (set == null) {
88             return false;
89         }
90         return set.contains(value);
91     }
92 
93     /**
94      * @return the set of items of key n
95      */
get(int n)96     public ArraySet<T> get(int n) {
97         return mData.get(n);
98     }
99 
100     /**
101      * Remove a value for key n.
102      * @return TRUE when the value existed for the given key and removed, FALSE otherwise.
103      */
remove(int n, T value)104     public boolean remove(int n, T value) {
105         final ArraySet<T> set = mData.get(n);
106         if (set == null) {
107             return false;
108         }
109         final boolean ret = set.remove(value);
110         if (set.size() == 0) {
111             mData.remove(n);
112         }
113         return ret;
114     }
115 
116     /**
117      * Remove all values for key n.
118      */
remove(int n)119     public void remove(int n) {
120         mData.remove(n);
121     }
122 
size()123     public int size() {
124         return mData.size();
125     }
126 
keyAt(int index)127     public int keyAt(int index) {
128         return mData.keyAt(index);
129     }
130 
sizeAt(int index)131     public int sizeAt(int index) {
132         final ArraySet<T> set = mData.valueAt(index);
133         if (set == null) {
134             return 0;
135         }
136         return set.size();
137     }
138 
valueAt(int intIndex, int valueIndex)139     public T valueAt(int intIndex, int valueIndex) {
140         return mData.valueAt(intIndex).valueAt(valueIndex);
141     }
142 
143     /** @return The set of values for key at position {@code intIndex}. */
valuesAt(int intIndex)144     public ArraySet<T> valuesAt(int intIndex) {
145         return mData.valueAt(intIndex);
146     }
147 }
148