14eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato/* 24eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Copyright (C) 2013 The Android Open Source Project 34eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 44eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 54eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * you may not use this file except in compliance with the License. 64eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * You may obtain a copy of the License at 74eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 84eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * http://www.apache.org/licenses/LICENSE-2.0 94eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 104eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Unless required by applicable law or agreed to in writing, software 114eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 124eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * See the License for the specific language governing permissions and 144eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * limitations under the License. 154eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 164eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 174eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratopackage com.android.internal.app.procstats; 184eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 194eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.os.Build; 204eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.os.Parcel; 214eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport android.util.Slog; 224eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport libcore.util.EmptyArray; 234eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 244eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport java.util.ArrayList; 254eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport java.util.Arrays; 264eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 274eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratoimport com.android.internal.util.GrowingArrayUtils; 284eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 294eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato/** 304eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Class that contains a set of tables mapping byte ids to long values. 31146dcc026500de5ef8152ef87372d548c71a1619Joe Onorato * 324eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * This class is used to store the ProcessStats data. This data happens to be 334eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * a set of very sparse tables, that is mostly append or overwrite, with infrequent 344eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * resets of the data. 354eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 364eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Data is stored as a list of large long[] arrays containing the actual values. There are a 374eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * set of Table objects that each contain a small array mapping the byte IDs to a position 384eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * in the larger arrays. 394eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 404eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * The data itself is either a single long value or a range of long values which are always 414eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * stored continguously in one of the long arrays. When the caller allocates a slot with 424eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * getOrAddKey, an int key is returned. That key can be re-retreived with getKey without 434eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * allocating the value. The data can then be set or retrieved with that key. 444eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 454eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onoratopublic class SparseMappingTable { 464eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private static final String TAG = "SparseMappingTable"; 474eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 484eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // How big each array is. 494eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public static final int ARRAY_SIZE = 4096; 504eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 514eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public static final int INVALID_KEY = 0xffffffff; 524eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 534eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Where the "type"/"state" part of the data appears in an offset integer. 544eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private static final int ID_SHIFT = 0; 554eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private static final int ID_MASK = 0xff; 564eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Where the "which array" part of the data appears in an offset integer. 574eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private static final int ARRAY_SHIFT = 8; 584eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private static final int ARRAY_MASK = 0xff; 594eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Where the "index into array" part of the data appears in an offset integer. 604eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private static final int INDEX_SHIFT = 16; 614eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private static final int INDEX_MASK = 0xffff; 62146dcc026500de5ef8152ef87372d548c71a1619Joe Onorato 634eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private int mSequence; 644eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private int mNextIndex; 654eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private final ArrayList<long[]> mLongs = new ArrayList<long[]>(); 66146dcc026500de5ef8152ef87372d548c71a1619Joe Onorato 674eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 684eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * A table of data as stored in a SparseMappingTable. 694eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 704eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public static class Table { 714eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private SparseMappingTable mParent; 7265adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato private int mSequence = 1; 734eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private int[] mTable; 744eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private int mSize; 754eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 764eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public Table(SparseMappingTable parent) { 774eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mParent = parent; 784eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mSequence = parent.mSequence; 794eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 804eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 814eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 824eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Pulls the data from 'copyFrom' and stores it in our own longs table. 834eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 844eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param copyFrom The Table to copy from 854eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param valueCount The number of values to copy for each key 864eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 874eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public void copyFrom(Table copyFrom, int valueCount) { 884eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mTable = null; 894eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mSize = 0; 904eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 914eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int N = copyFrom.getKeyCount(); 924eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato for (int i=0; i<N; i++) { 934eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int theirKey = copyFrom.getKeyAt(i); 944eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final long[] theirLongs = copyFrom.mParent.mLongs.get(getArrayFromKey(theirKey)); 954eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 964eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final byte id = SparseMappingTable.getIdFromKey(theirKey); 974eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 984eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int myKey = this.getOrAddKey((byte)id, valueCount); 994eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final long[] myLongs = mParent.mLongs.get(getArrayFromKey(myKey)); 1004eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 1014eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato System.arraycopy(theirLongs, getIndexFromKey(theirKey), 1024eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato myLongs, getIndexFromKey(myKey), valueCount); 1034eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 1044eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 1054eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 1064eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 1074eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Allocates data in the buffer, and stores that key in the mapping for this 1084eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * table. 1094eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 1104eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param id The id of the item (will be used in making the key) 1114eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param count The number of bytes to allocate. Must be less than 1124eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * SparseMappingTable.ARRAY_SIZE. 1134eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 1144eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @return The 'key' for this data value, which contains both the id itself 1154eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * and the location in the long arrays that the data is actually stored 1164eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * but should be considered opaque to the caller. 1174eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 1184eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public int getOrAddKey(byte id, int count) { 1194eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato assertConsistency(); 1204eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 1214eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int idx = binarySearch(id); 1224eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (idx >= 0) { 1234eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Found 1244eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return mTable[idx]; 1254eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } else { 1264eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Not found. Need to allocate it. 1274eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 1284eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Get an array with enough space to store 'count' values. 1294eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final ArrayList<long[]> list = mParent.mLongs; 1304eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato int whichArray = list.size()-1; 1314eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato long[] array = list.get(whichArray); 1324eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (mParent.mNextIndex + count > array.length) { 1334eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // if it won't fit then make a new array. 1344eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato array = new long[ARRAY_SIZE]; 1354eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato list.add(array); 1364eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato whichArray++; 1374eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mParent.mNextIndex = 0; 1384eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 1394eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 1404eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // The key is a combination of whichArray, which index in that array, and 1414eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // the table value itself, which will be used for lookup 1424eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int key = (whichArray << ARRAY_SHIFT) 1434eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato | (mParent.mNextIndex << INDEX_SHIFT) 1444eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato | (((int)id) << ID_SHIFT); 1454eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 1464eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mParent.mNextIndex += count; 1474eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 1484eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Store the key in the sparse lookup table for this Table object. 1494eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mTable = GrowingArrayUtils.insert(mTable != null ? mTable : EmptyArray.INT, 1504eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mSize, ~idx, key); 1514eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mSize++; 1524eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 1534eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return key; 1544eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 1554eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 1564eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 1574eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 1584eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Looks up a key in the table. 1594eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 1604eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @return The key from this table or INVALID_KEY if the id is not found. 1614eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 1624eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public int getKey(byte id) { 1634eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato assertConsistency(); 1644eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 1654eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int idx = binarySearch(id); 1664eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (idx >= 0) { 1674eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return mTable[idx]; 1684eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } else { 1694eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return INVALID_KEY; 1704eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 1714eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 1724eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 1734eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 1744eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Get the value for the given key and offset from that key. 1754eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 1764eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param key A key as obtained from getKey or getOrAddKey. 1774eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param value The value to set. 1784eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 1794eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public long getValue(int key) { 1804eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return getValue(key, 0); 1814eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 1824eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 1834eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 1844eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Get the value for the given key and offset from that key. 1854eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 1864eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param key A key as obtained from getKey or getOrAddKey. 1874eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param index The offset from that key. Must be less than the count 1884eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * provided to getOrAddKey when the space was allocated. 1894eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param value The value to set. 1904eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 1914eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @return the value, or 0 in case of an error 1924eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 1934eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public long getValue(int key, int index) { 1944eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato assertConsistency(); 1954eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 1964eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato try { 1974eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final long[] array = mParent.mLongs.get(getArrayFromKey(key)); 1984eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return array[getIndexFromKey(key) + index]; 1994eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } catch (IndexOutOfBoundsException ex) { 2004eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato logOrThrow("key=0x" + Integer.toHexString(key) 2014eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato + " index=" + index + " -- " + dumpInternalState(), ex); 2024eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return 0; 2034eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 2044eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 2054eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 2064eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 2074eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Set the value for the given id at offset 0 from that id. 2084eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * If the id is not found, return 0 instead. 2094eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 2104eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param id The id of the item. 2114eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 2124eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public long getValueForId(byte id) { 2134eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return getValueForId(id, 0); 2144eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 2154eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 2164eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 2174eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Set the value for the given id and index offset from that id. 2184eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * If the id is not found, return 0 instead. 2194eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 2204eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param id The id of the item. 2214eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param index The offset from that key. Must be less than the count 2224eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * provided to getOrAddKey when the space was allocated. 2234eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 2244eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public long getValueForId(byte id, int index) { 2254eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato assertConsistency(); 2264eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 2274eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int idx = binarySearch(id); 2284eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (idx >= 0) { 2294eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int key = mTable[idx]; 2304eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato try { 2314eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final long[] array = mParent.mLongs.get(getArrayFromKey(key)); 2324eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return array[getIndexFromKey(key) + index]; 2334eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } catch (IndexOutOfBoundsException ex) { 2344eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato logOrThrow("id=0x" + Integer.toHexString(id) + " idx=" + idx 2354eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato + " key=0x" + Integer.toHexString(key) + " index=" + index 2364eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato + " -- " + dumpInternalState(), ex); 2374eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return 0; 2384eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 2394eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } else { 2404eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return 0; 2414eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 2424eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 2434eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 2444eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 2454eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Return the raw storage long[] for the given key. 2464eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 2474eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public long[] getArrayForKey(int key) { 2484eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato assertConsistency(); 2494eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 2504eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return mParent.mLongs.get(getArrayFromKey(key)); 2514eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 2524eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 2534eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 2544eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Set the value for the given key and offset from that key. 2554eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 2564eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param key A key as obtained from getKey or getOrAddKey. 2574eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param value The value to set. 2584eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 2594eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public void setValue(int key, long value) { 2604eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato setValue(key, 0, value); 2614eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 2624eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 2634eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 2644eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Set the value for the given key and offset from that key. 2654eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 2664eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param key A key as obtained from getKey or getOrAddKey. 2674eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param index The offset from that key. Must be less than the count 2684eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * provided to getOrAddKey when the space was allocated. 2694eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @param value The value to set. 2704eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 2714eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public void setValue(int key, int index, long value) { 2724eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato assertConsistency(); 2734eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 2744eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (value < 0) { 2754eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato logOrThrow("can't store negative values" 2764eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato + " key=0x" + Integer.toHexString(key) 2774eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato + " index=" + index + " value=" + value 2784eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato + " -- " + dumpInternalState()); 2794eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return; 2804eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 2814eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 2824eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato try { 2834eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final long[] array = mParent.mLongs.get(getArrayFromKey(key)); 2844eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato array[getIndexFromKey(key) + index] = value; 2854eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } catch (IndexOutOfBoundsException ex) { 2864eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato logOrThrow("key=0x" + Integer.toHexString(key) 2874eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato + " index=" + index + " value=" + value 2884eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato + " -- " + dumpInternalState(), ex); 2894eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return; 2904eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 2914eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 2924eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 2934eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 2944eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Clear out the table, and reset the sequence numbers so future writes 2954eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * without allocations will assert. 2964eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 2974eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public void resetTable() { 2984eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Clear out our table. 2994eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mTable = null; 3004eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mSize = 0; 3014eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 3024eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Reset our sequence number. This will make all read/write calls 3034eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // start to fail, and then when we re-allocate it will be re-synced 3044eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // to that of mParent. 30565adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato mSequence = mParent.mSequence; 3064eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 3074eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 3084eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 3094eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Write the keys stored in the table to the parcel. The parent must 3104eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * be separately written. Does not save the actual data. 3114eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 3124eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public void writeToParcel(Parcel out) { 3134eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato out.writeInt(mSequence); 3144eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato out.writeInt(mSize); 3154eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato for (int i=0; i<mSize; i++) { 3164eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato out.writeInt(mTable[i]); 3174eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 3184eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 3194eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 3204eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 3214eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Read the keys from the parcel. The parent (with its long array) must 3224eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * have been previously initialized. 3234eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 3244eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public boolean readFromParcel(Parcel in) { 3254eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Read the state 3264eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mSequence = in.readInt(); 3274eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mSize = in.readInt(); 3284eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (mSize != 0) { 3294eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mTable = new int[mSize]; 3304eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato for (int i=0; i<mSize; i++) { 3314eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mTable[i] = in.readInt(); 3324eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 3334eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } else { 3344eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mTable = null; 3354eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 3364eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 3374eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Make sure we're all healthy 3384eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (validateKeys(true)) { 3394eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return true; 3404eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } else { 3414eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Clear it out 3424eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mSize = 0; 3434eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mTable = null; 3444eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return false; 3454eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 3464eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 3474eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 3484eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 3494eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Return the number of keys that have been added to this Table. 3504eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 3514eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public int getKeyCount() { 3524eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return mSize; 3534eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 3544eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 3554eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 3564eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Get the key at the given index in our table. 3574eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 3584eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public int getKeyAt(int i) { 3594eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return mTable[i]; 3604eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 3614eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 3624eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 3634eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Throw an exception if one of a variety of internal consistency checks fails. 3644eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 3654eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private void assertConsistency() { 36608274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato // Something with this checking isn't working and is triggering 36708274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato // more problems than it's helping to debug. 36808274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato // Original bug: b/27045736 36908274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato // New bug: b/27960286 37008274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato if (false) { 37108274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato // Assert that our sequence number matches mParent's. If it isn't that means 37265adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato // we have been reset and our. If our sequence is UNITIALIZED_SEQUENCE, then 37365adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato // it's possible that everything is working fine and we just haven't been 37465adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato // written to since the last resetTable(). 37508274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato if (mSequence != mParent.mSequence) { 37608274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato if (mSequence < mParent.mSequence) { 37765adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato logOrThrow("Sequence mismatch. SparseMappingTable.reset()" 37808274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato + " called but not Table.resetTable() -- " 37908274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato + dumpInternalState()); 38008274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato return; 38108274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato } else if (mSequence > mParent.mSequence) { 38208274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato logOrThrow("Sequence mismatch. Table.resetTable()" 38365adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato + " called but not SparseMappingTable.reset() -- " 38408274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato + dumpInternalState()); 38508274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato return; 38608274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato } 38708274740cd3bf34e91e243a1c5faa7d80ecb0fc6Joe Onorato } 3884eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 3894eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 3904eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 3914eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 3924eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Finds the 'id' inside the array of length size (physical size of the array 3934eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * is not used). 3944eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 3954eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * @return The index of the array, or the bitwise not (~index) of where it 3964eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * would go if you wanted to insert 'id' into the array. 3974eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 3984eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private int binarySearch(byte id) { 3994eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato int lo = 0; 4004eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato int hi = mSize - 1; 4014eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 4024eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato while (lo <= hi) { 4034eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato int mid = (lo + hi) >>> 1; 4044eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato byte midId = (byte)((mTable[mid] >> ID_SHIFT) & ID_MASK); 4054eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 4064eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (midId < id) { 4074eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato lo = mid + 1; 4084eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } else if (midId > id) { 4094eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato hi = mid - 1; 4104eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } else { 4114eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return mid; // id found 4124eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 4134eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 4144eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return ~lo; // id not present 4154eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 4164eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 4174eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 4184eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Check that all the keys are valid locations in the long arrays. 419146dcc026500de5ef8152ef87372d548c71a1619Joe Onorato * 4204eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * If any aren't, log it and return false. Else return true. 4214eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 4224eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private boolean validateKeys(boolean log) { 4234eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato ArrayList<long[]> longs = mParent.mLongs; 4244eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int longsSize = longs.size(); 4254eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 4264eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int N = mSize; 4274eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato for (int i=0; i<N; i++) { 4284eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int key = mTable[i]; 4294eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int arrayIndex = getArrayFromKey(key); 4304eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int index = getIndexFromKey(key); 4314eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (arrayIndex >= longsSize || index >= longs.get(arrayIndex).length) { 4324eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (log) { 4334eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato Slog.w(TAG, "Invalid stats at index " + i + " -- " + dumpInternalState()); 4344eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 4354eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return false; 4364eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 4374eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 4384eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 4394eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return true; 4404eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 4414eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 4424eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public String dumpInternalState() { 4434eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato StringBuilder sb = new StringBuilder(); 4444eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append("SparseMappingTable.Table{mSequence="); 4454eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(mSequence); 4464eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(" mParent.mSequence="); 4474eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(mParent.mSequence); 4484eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(" mParent.mLongs.size()="); 4494eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(mParent.mLongs.size()); 4504eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(" mSize="); 4514eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(mSize); 4524eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(" mTable="); 4534eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (mTable == null) { 4544eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append("null"); 4554eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } else { 4564eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int N = mTable.length; 4574eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append('['); 4584eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato for (int i=0; i<N; i++) { 4594eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int key = mTable[i]; 4604eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append("0x"); 4614eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(Integer.toHexString((key >> ID_SHIFT) & ID_MASK)); 4624eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append("/0x"); 4634eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(Integer.toHexString((key >> ARRAY_SHIFT) & ARRAY_MASK)); 4644eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append("/0x"); 4654eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(Integer.toHexString((key >> INDEX_SHIFT) & INDEX_MASK)); 4664eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (i != N-1) { 4674eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(", "); 4684eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 4694eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 4704eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(']'); 4714eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 4724eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(" clazz="); 4734eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append(getClass().getName()); 4744eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato sb.append('}'); 4754eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 4764eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return sb.toString(); 4774eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 4784eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 4794eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 48065adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato public SparseMappingTable() { 48165adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato mLongs.add(new long[ARRAY_SIZE]); 48265adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato } 48365adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato 4844eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 4854eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Wipe out all the data. 4864eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 4874eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public void reset() { 4884eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Clear out mLongs, and prime it with a new array of data 4894eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mLongs.clear(); 4904eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mLongs.add(new long[ARRAY_SIZE]); 4914eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mNextIndex = 0; 4924eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 4934eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // Increment out sequence counter, because all of the tables will 4944eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // now be out of sync with the data. 4954eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mSequence++; 4964eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 4974eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 4984eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 4994eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Write the data arrays to the parcel. 5004eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 5014eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public void writeToParcel(Parcel out) { 5024eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato out.writeInt(mSequence); 5034eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato out.writeInt(mNextIndex); 5044eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int N = mLongs.size(); 5054eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato out.writeInt(N); 5064eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato for (int i=0; i<N-1; i++) { 5074eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final long[] array = mLongs.get(i); 5084eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato out.writeInt(array.length); 5094eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato writeCompactedLongArray(out, array, array.length); 5104eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 5114eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato // save less for the last one. upon re-loading they'll just start a new array. 5124eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final long[] lastLongs = mLongs.get(N-1); 5134eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato out.writeInt(mNextIndex); 5144eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato writeCompactedLongArray(out, lastLongs, mNextIndex); 5154eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 5164eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 5174eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 5184eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Read the data arrays from the parcel. 5194eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 5204eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public void readFromParcel(Parcel in) { 5214eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mSequence = in.readInt(); 5224eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mNextIndex = in.readInt(); 5234eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 5244eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mLongs.clear(); 5254eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int N = in.readInt(); 5264eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato for (int i=0; i<N; i++) { 5274eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int size = in.readInt(); 5284eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final long[] array = new long[size]; 5294eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato readCompactedLongArray(in, array, size); 5304eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato mLongs.add(array); 5314eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 5324eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 5334eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 5344eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 53565adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato * Return a string for debugging. 53665adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato */ 53765adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato public String dumpInternalState(boolean includeData) { 53865adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato final StringBuilder sb = new StringBuilder(); 53965adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato sb.append("SparseMappingTable{"); 54065adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato sb.append("mSequence="); 54165adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato sb.append(mSequence); 54265adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato sb.append(" mNextIndex="); 54365adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato sb.append(mNextIndex); 54465adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato sb.append(" mLongs.size="); 54565adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato final int N = mLongs.size(); 54665adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato sb.append(N); 54765adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato sb.append("\n"); 54865adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato if (includeData) { 54965adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato for (int i=0; i<N; i++) { 55065adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato final long[] array = mLongs.get(i); 55165adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato for (int j=0; j<array.length; j++) { 55265adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato if (i == N-1 && j == mNextIndex) { 55365adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato break; 55465adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato } 55565adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato sb.append(String.format(" %4d %d 0x%016x %-19d\n", i, j, array[j], array[j])); 55665adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato } 55765adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato } 55865adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato } 55965adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato sb.append("}"); 56065adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato return sb.toString(); 56165adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato } 56265adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato 56365adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato /** 5644eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Write the long array to the parcel in a compacted form. Does not allow negative 5654eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * values in the array. 5664eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 5674eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private static void writeCompactedLongArray(Parcel out, long[] array, int num) { 5684eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato for (int i=0; i<num; i++) { 5694eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato long val = array[i]; 5704eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (val < 0) { 5714eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato Slog.w(TAG, "Time val negative: " + val); 5724eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato val = 0; 5734eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 5744eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (val <= Integer.MAX_VALUE) { 5754eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato out.writeInt((int)val); 5764eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } else { 5774eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato int top = ~((int)((val>>32)&0x7fffffff)); 57865adfeecd2acc4e63c00fc1f2073cc0b229f3467Joe Onorato int bottom = (int)(val&0x0ffffffffL); 5794eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato out.writeInt(top); 5804eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato out.writeInt(bottom); 5814eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 5824eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 5834eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 5844eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 5854eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 5864eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Read the compacted array into the long[]. 5874eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 5884eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private static void readCompactedLongArray(Parcel in, long[] array, int num) { 5894eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato final int alen = array.length; 5904eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (num > alen) { 5914eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato logOrThrow("bad array lengths: got " + num + " array is " + alen); 5924eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return; 5934eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 5944eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato int i; 5954eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato for (i=0; i<num; i++) { 5964eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato int val = in.readInt(); 5974eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (val >= 0) { 5984eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato array[i] = val; 5994eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } else { 6004eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato int bottom = in.readInt(); 6014eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato array[i] = (((long)~val)<<32) | bottom; 6024eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 6034eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 6044eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato while (i < alen) { 6054eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato array[i] = 0; 6064eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato i++; 6074eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 6084eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 609146dcc026500de5ef8152ef87372d548c71a1619Joe Onorato 6104eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 6114eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Extract the id from a key. 6124eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 6134eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public static byte getIdFromKey(int key) { 6144eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return (byte)((key >> ID_SHIFT) & ID_MASK); 6154eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 6164eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 6174eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 6184eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Gets the index of the array in the list of arrays. 6194eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 6204eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Not to be confused with getIndexFromKey. 6214eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 6224eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public static int getArrayFromKey(int key) { 6234eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return (key >> ARRAY_SHIFT) & ARRAY_MASK; 6244eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 6254eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 6264eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 6274eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Gets the index of a value in a long[]. 6284eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * 6294eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Not to be confused with getArrayFromKey. 6304eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 6314eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato public static int getIndexFromKey(int key) { 6324eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato return (key >> INDEX_SHIFT) & INDEX_MASK; 6334eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 6344eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 6354eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 6364eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Do a Slog.wtf or throw an exception (thereby crashing the system process if 6374eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * this is a debug build.) 6384eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 6394eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private static void logOrThrow(String message) { 640146dcc026500de5ef8152ef87372d548c71a1619Joe Onorato logOrThrow(message, new RuntimeException("Stack trace")); 6414eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 6424eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato 6434eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato /** 6444eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * Do a Slog.wtf or throw an exception (thereby crashing the system process if 6454eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato * this is an eng build.) 6464eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato */ 6474eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato private static void logOrThrow(String message, Throwable th) { 64804b70fc63a80e3df9b97a5197f1d7df022cbe92bJeff Sharkey Slog.e(TAG, message, th); 6494eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato if (Build.TYPE.equals("eng")) { 6504eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato throw new RuntimeException(message, th); 6514eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 6524eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato } 6534eb64fdbcf899a81d0a6a04dc3658d03d9df8247Joe Onorato} 654