1 /* 2 * Copyright (C) 2015 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 17 package android.support.v7.util; 18 19 import android.util.SparseArray; 20 21 import java.lang.reflect.Array; 22 23 /** 24 * A sparse collection of tiles sorted for efficient access. 25 */ 26 class TileList<T> { 27 28 final int mTileSize; 29 30 // Keyed by start position. 31 private final SparseArray<Tile<T>> mTiles = new SparseArray<Tile<T>>(10); 32 33 Tile<T> mLastAccessedTile; 34 TileList(int tileSize)35 public TileList(int tileSize) { 36 mTileSize = tileSize; 37 } 38 getItemAt(int pos)39 public T getItemAt(int pos) { 40 if (mLastAccessedTile == null || !mLastAccessedTile.containsPosition(pos)) { 41 final int startPosition = pos - (pos % mTileSize); 42 final int index = mTiles.indexOfKey(startPosition); 43 if (index < 0) { 44 return null; 45 } 46 mLastAccessedTile = mTiles.valueAt(index); 47 } 48 return mLastAccessedTile.getByPosition(pos); 49 } 50 size()51 public int size() { 52 return mTiles.size(); 53 } 54 clear()55 public void clear() { 56 mTiles.clear(); 57 } 58 getAtIndex(int index)59 public Tile<T> getAtIndex(int index) { 60 return mTiles.valueAt(index); 61 } 62 addOrReplace(Tile<T> newTile)63 public Tile<T> addOrReplace(Tile<T> newTile) { 64 final int index = mTiles.indexOfKey(newTile.mStartPosition); 65 if (index < 0) { 66 mTiles.put(newTile.mStartPosition, newTile); 67 return null; 68 } 69 Tile<T> oldTile = mTiles.valueAt(index); 70 mTiles.setValueAt(index, newTile); 71 if (mLastAccessedTile == oldTile) { 72 mLastAccessedTile = newTile; 73 } 74 return oldTile; 75 } 76 removeAtPos(int startPosition)77 public Tile<T> removeAtPos(int startPosition) { 78 Tile<T> tile = mTiles.get(startPosition); 79 if (mLastAccessedTile == tile) { 80 mLastAccessedTile = null; 81 } 82 mTiles.delete(startPosition); 83 return tile; 84 } 85 86 public static class Tile<T> { 87 public final T[] mItems; 88 public int mStartPosition; 89 public int mItemCount; 90 Tile<T> mNext; // Used only for pooling recycled tiles. 91 Tile(Class<T> klass, int size)92 public Tile(Class<T> klass, int size) { 93 //noinspection unchecked 94 mItems = (T[]) Array.newInstance(klass, size); 95 } 96 containsPosition(int pos)97 boolean containsPosition(int pos) { 98 return mStartPosition <= pos && pos < mStartPosition + mItemCount; 99 } 100 getByPosition(int pos)101 T getByPosition(int pos) { 102 return mItems[pos - mStartPosition]; 103 } 104 } 105 } 106