/*
* Copyright (C) 2015 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 android.support.v7.util;
import android.util.SparseArray;
import java.lang.reflect.Array;
/**
* A sparse collection of tiles sorted for efficient access.
*/
class TileList<T> {
final int mTileSize;
// Keyed by start position.
private final SparseArray<Tile<T>> mTiles = new SparseArray<Tile<T>>(10);
Tile<T> mLastAccessedTile;
public TileList(int tileSize) {
mTileSize = tileSize;
}
public T getItemAt(int pos) {
if (mLastAccessedTile == null || !mLastAccessedTile.containsPosition(pos)) {
final int startPosition = pos - (pos % mTileSize);
final int index = mTiles.indexOfKey(startPosition);
if (index < 0) {
return null;
}
mLastAccessedTile = mTiles.valueAt(index);
}
return mLastAccessedTile.getByPosition(pos);
}
public int size() {
return mTiles.size();
}
public void clear() {
mTiles.clear();
}
public Tile<T> getAtIndex(int index) {
return mTiles.valueAt(index);
}
public Tile<T> addOrReplace(Tile<T> newTile) {
final int index = mTiles.indexOfKey(newTile.mStartPosition);
if (index < 0) {
mTiles.put(newTile.mStartPosition, newTile);
return null;
}
Tile<T> oldTile = mTiles.valueAt(index);
mTiles.setValueAt(index, newTile);
if (mLastAccessedTile == oldTile) {
mLastAccessedTile = newTile;
}
return oldTile;
}
public Tile<T> removeAtPos(int startPosition) {
Tile<T> tile = mTiles.get(startPosition);
if (mLastAccessedTile == tile) {
mLastAccessedTile = null;
}
mTiles.delete(startPosition);
return tile;
}
public static class Tile<T> {
public final T[] mItems;
public int mStartPosition;
public int mItemCount;
Tile<T> mNext; // Used only for pooling recycled tiles.
public Tile(Class<T> klass, int size) {
//noinspection unchecked
mItems = (T[]) Array.newInstance(klass, size);
}
boolean containsPosition(int pos) {
return mStartPosition <= pos && pos < mStartPosition + mItemCount;
}
T getByPosition(int pos) {
return mItems[pos - mStartPosition];
}
}
}