1/*
2 * Copyright (C) 2013 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
17package com.android.camera.data;
18
19import android.net.Uri;
20
21import java.util.Collections;
22import java.util.Comparator;
23import java.util.HashMap;
24import java.util.LinkedList;
25
26/**
27 * Fast access data structure for an ordered LocalData list.
28 */
29public class LocalDataList {
30    /**
31     * We use this as a way to compare a Uri to LocalData instances inside a
32     * LinkedList. A linked list in indexOf does a other.equals(get(i)).
33     */
34    private static class UriWrapper {
35        private final Uri mUri;
36
37        public UriWrapper(Uri uri) {
38            mUri = uri;
39        }
40
41        @Override
42        public boolean equals(Object o) {
43            if (!(o instanceof LocalData)) {
44                return false;
45            }
46            return mUri.equals(((LocalData) o).getContentUri());
47        }
48    }
49
50    private LinkedList<LocalData> mList = new LinkedList<LocalData>();
51    private HashMap<Uri, LocalData> mUriMap = new HashMap<Uri, LocalData>();
52
53    public LocalData get(int index) {
54        return mList.get(index);
55    }
56
57    public LocalData remove(int index) {
58        LocalData removedItem = mList.remove(index);
59        mUriMap.remove(removedItem);
60        return removedItem;
61    }
62
63    public LocalData get(Uri uri) {
64        return mUriMap.get(uri);
65    }
66
67    public void set(int pos, LocalData data) {
68        mList.set(pos, data);
69        mUriMap.put(data.getContentUri(), data);
70    }
71
72    public void add(LocalData data) {
73        mList.add(data);
74        mUriMap.put(data.getContentUri(), data);
75    }
76
77    public void add(int pos, LocalData data) {
78        mList.add(pos, data);
79        mUriMap.put(data.getContentUri(), data);
80    }
81
82    public int size() {
83        return mList.size();
84    }
85
86    public void sort(Comparator<LocalData> comparator) {
87        Collections.sort(mList, comparator);
88    }
89
90    /**
91     * This implementation routes through to LinkedList.indexOf, so performs in
92     * O(n) but has a fast exit path for when the uri is not contained in the
93     * list, and immediately returns -1;
94     */
95    public int indexOf(Uri uri) {
96        if (!mUriMap.containsKey(uri)) {
97            return -1;
98        }
99        return mList.indexOf(new UriWrapper(uri));
100    }
101}
102