1eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki/*
2eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki * Copyright (C) 2018 The Android Open Source Project
3eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki *
4eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki * Licensed under the Apache License, Version 2.0 (the "License");
5eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki * you may not use this file except in compliance with the License.
6eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki * You may obtain a copy of the License at
7eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki *
8eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki *      http://www.apache.org/licenses/LICENSE-2.0
9eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki *
10eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki * Unless required by applicable law or agreed to in writing, software
11eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki * distributed under the License is distributed on an "AS IS" BASIS,
12eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki * See the License for the specific language governing permissions and
14eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki * limitations under the License.
15eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki */
16eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onukipackage android.util;
17eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki
18eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki/**
19eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki * A sparse array of ArraySets, which is suitable to hold userid->packages association.
20eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki *
21eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki * @hide
22eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki */
23eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onukipublic class SparseSetArray<T> {
24eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    private final SparseArray<ArraySet<T>> mData = new SparseArray<>();
25eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki
26eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    public SparseSetArray() {
27eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    }
28eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki
29eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    /**
30eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki     * Add a value at index n.
31eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki     * @return FALSE when the value already existed at the given index, TRUE otherwise.
32eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki     */
33eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    public boolean add(int n, T value) {
34eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        ArraySet<T> set = mData.get(n);
35eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        if (set == null) {
36eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki            set = new ArraySet<>();
37eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki            mData.put(n, set);
38eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        }
39eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        if (set.contains(value)) {
40eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki            return true;
41eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        }
42eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        set.add(value);
43eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        return false;
44eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    }
45eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki
46eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    /**
47eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki     * @return whether a value exists at index n.
48eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki     */
49eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    public boolean contains(int n, T value) {
50eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        final ArraySet<T> set = mData.get(n);
51eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        if (set == null) {
52eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki            return false;
53eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        }
54eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        return set.contains(value);
55eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    }
56eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki
57eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    /**
58eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki     * Remove a value from index n.
59eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki     * @return TRUE when the value existed at the given index and removed, FALSE otherwise.
60eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki     */
61eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    public boolean remove(int n, T value) {
62eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        final ArraySet<T> set = mData.get(n);
63eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        if (set == null) {
64eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki            return false;
65eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        }
66eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        final boolean ret = set.remove(value);
67eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        if (set.size() == 0) {
68eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki            mData.remove(n);
69eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        }
70eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        return ret;
71eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    }
72eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki
73eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    /**
74eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki     * Remove all values from index n.
75eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki     */
76eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    public void remove(int n) {
77eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        mData.remove(n);
78eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    }
79eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    public int size() {
80eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        return mData.size();
81eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    }
82eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki
83eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    public int keyAt(int index) {
84eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        return mData.keyAt(index);
85eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    }
86eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki
87eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    public int sizeAt(int index) {
88eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        final ArraySet<T> set = mData.valueAt(index);
89eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        if (set == null) {
90eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki            return 0;
91eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        }
92eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        return set.size();
93eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    }
94eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki
95eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    public T valueAt(int intIndex, int valueIndex) {
96eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki        return mData.valueAt(intIndex).valueAt(valueIndex);
97eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki    }
98eb898f1b8a3a1c5ce32ec9780c6a3a302347a0b9Makoto Onuki}
99