/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.camera.data; import android.net.Uri; import com.android.camera.debug.Log; import com.android.camera.debug.Log.Tag; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedList; import java.util.List; /** * Fast access data structure for an ordered LocalData list. */ public class FilmstripItemList { /** * We use this as a way to compare a Uri to LocalData instances inside a * LinkedList. A linked list in indexOf does a other.equals(get(i)). */ private static class UriWrapper { private final Uri mUri; public UriWrapper(Uri uri) { mUri = uri; } @Override public boolean equals(Object o) { if (!(o instanceof FilmstripItem)) { return false; } return mUri.equals(((FilmstripItem) o).getData().getUri()); } } private static final Tag TAG = new Tag("LocalDataList"); private final LinkedList mList = new LinkedList(); private final HashMap mUriMap = new HashMap(); public FilmstripItem get(int index) { return mList.get(index); } /** * Removes the item at the given index. * * @param index the item to delete * @return If the item was found and deleted, it is returned. If the item * was not found, null is returned. */ public synchronized FilmstripItem remove(int index) { try { FilmstripItem removedItem = mList.remove(index); mUriMap.remove(removedItem); return removedItem; } catch (IndexOutOfBoundsException ex) { Log.w(TAG, "Could not remove item. Not found: " + index, ex); return null; } } public FilmstripItem get(Uri uri) { return mUriMap.get(uri); } public void set(int pos, FilmstripItem data) { mList.set(pos, data); mUriMap.put(data.getData().getUri(), data); } public void add(FilmstripItem data) { mList.add(data); mUriMap.put(data.getData().getUri(), data); } public void add(int pos, FilmstripItem data) { mList.add(pos, data); mUriMap.put(data.getData().getUri(), data); } public void addAll(List filmstripItemList) { for (FilmstripItem filmstripItem : filmstripItemList) { add(filmstripItem); } } public int size() { return mList.size(); } public void sort(Comparator comparator) { Collections.sort(mList, comparator); } /** * This implementation routes through to LinkedList.indexOf, so performs in * O(n) but has a fast exit path for when the uri is not contained in the * list, and immediately returns -1; */ public int indexOf(Uri uri) { if (!mUriMap.containsKey(uri)) { return -1; } return mList.indexOf(new UriWrapper(uri)); } }