1cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// Protocol Buffers - Google's data interchange format 2cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// Copyright 2014 Google Inc. All rights reserved. 3cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// http://code.google.com/p/protobuf/ 4cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// 5cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// Redistribution and use in source and binary forms, with or without 6cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// modification, are permitted provided that the following conditions are 7cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// met: 8cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// 9cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// * Redistributions of source code must retain the above copyright 10cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// notice, this list of conditions and the following disclaimer. 11cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// * Redistributions in binary form must reproduce the above 12cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// copyright notice, this list of conditions and the following disclaimer 13cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// in the documentation and/or other materials provided with the 14cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// distribution. 15cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// * Neither the name of Google Inc. nor the names of its 16cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// contributors may be used to endorse or promote products derived from 17cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// this software without specific prior written permission. 18cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// 19cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 31cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveirapackage com.google.protobuf.nano; 32cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 33cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 34cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira/** 35cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * A custom version of {@link android.util.SparseArray} with the minimal API 36cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * for storing {@link FieldData} objects. 37cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * 38cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * Based on {@link android.support.v4.util.SpareArrayCompat}. 39cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira */ 40cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveiraclass FieldArray { 41cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira private static final FieldData DELETED = new FieldData(); 42cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira private boolean mGarbage = false; 43cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 44cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira private int[] mFieldNumbers; 45cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira private FieldData[] mData; 46cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira private int mSize; 47cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 48cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira /** 49cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * Creates a new FieldArray containing no fields. 50cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira */ 51cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira public FieldArray() { 52cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira this(10); 53cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 54cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 55cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira /** 56cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * Creates a new FieldArray containing no mappings that will not 57cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * require any additional memory allocation to store the specified 58cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * number of mappings. 59cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira */ 60cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira public FieldArray(int initialCapacity) { 61cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira initialCapacity = idealIntArraySize(initialCapacity); 62cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mFieldNumbers = new int[initialCapacity]; 63cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mData = new FieldData[initialCapacity]; 64cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mSize = 0; 65cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 66cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 67cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira /** 68cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * Gets the FieldData mapped from the specified fieldNumber, or <code>null</code> 69cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * if no such mapping has been made. 70cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira */ 71cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira public FieldData get(int fieldNumber) { 72cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira int i = binarySearch(fieldNumber); 73cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 74cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (i < 0 || mData[i] == DELETED) { 75cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return null; 76cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } else { 77cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return mData[i]; 78cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 79cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 80cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 81cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira /** 82cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * Removes the data from the specified fieldNumber, if there was any. 83cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira */ 84cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira public void remove(int fieldNumber) { 85cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira int i = binarySearch(fieldNumber); 86cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 87cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (i >= 0 && mData[i] != DELETED) { 88cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mData[i] = DELETED; 89cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mGarbage = true; 90cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 91cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 92cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 93cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira private void gc() { 94cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira int n = mSize; 95cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira int o = 0; 96cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira int[] keys = mFieldNumbers; 97cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira FieldData[] values = mData; 98cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 99cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira for (int i = 0; i < n; i++) { 100cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira FieldData val = values[i]; 101cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 102cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (val != DELETED) { 103cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (i != o) { 104cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira keys[o] = keys[i]; 105cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira values[o] = val; 106cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira values[i] = null; 107cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 108cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 109cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira o++; 110cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 111cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 112cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 113cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mGarbage = false; 114cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mSize = o; 115cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 116cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 117cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira /** 118cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * Adds a mapping from the specified fieldNumber to the specified data, 119cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * replacing the previous mapping if there was one. 120cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira */ 121cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira public void put(int fieldNumber, FieldData data) { 122cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira int i = binarySearch(fieldNumber); 123cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 124cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (i >= 0) { 125cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mData[i] = data; 126cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } else { 127cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira i = ~i; 128cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 129cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (i < mSize && mData[i] == DELETED) { 130cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mFieldNumbers[i] = fieldNumber; 131cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mData[i] = data; 132cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return; 133cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 134cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 135cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (mGarbage && mSize >= mFieldNumbers.length) { 136cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira gc(); 137cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 138cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira // Search again because indices may have changed. 139cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira i = ~ binarySearch(fieldNumber); 140cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 141cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 142cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (mSize >= mFieldNumbers.length) { 143cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira int n = idealIntArraySize(mSize + 1); 144cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 145cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira int[] nkeys = new int[n]; 146cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira FieldData[] nvalues = new FieldData[n]; 147cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 148cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira System.arraycopy(mFieldNumbers, 0, nkeys, 0, mFieldNumbers.length); 149cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira System.arraycopy(mData, 0, nvalues, 0, mData.length); 150cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 151cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mFieldNumbers = nkeys; 152cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mData = nvalues; 153cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 154cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 155cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (mSize - i != 0) { 156cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira System.arraycopy(mFieldNumbers, i, mFieldNumbers, i + 1, mSize - i); 157cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira System.arraycopy(mData, i, mData, i + 1, mSize - i); 158cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 159cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 160cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mFieldNumbers[i] = fieldNumber; 161cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mData[i] = data; 162cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira mSize++; 163cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 164cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 165cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 166cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira /** 167cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * Returns the number of key-value mappings that this FieldArray 168cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * currently stores. 169cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira */ 170cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira public int size() { 171cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (mGarbage) { 172cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira gc(); 173cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 174cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 175cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return mSize; 176cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 177cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 178cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira public boolean isEmpty() { 179cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return size() == 0; 180cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 181cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 182cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira /** 183cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * Given an index in the range <code>0...size()-1</code>, returns 184cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * the value from the <code>index</code>th key-value mapping that this 185cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira * FieldArray stores. 186cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira */ 187cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira public FieldData dataAt(int index) { 188cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (mGarbage) { 189cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira gc(); 190cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 191cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 192cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return mData[index]; 193cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 194cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 195cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira @Override 196cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira public boolean equals(Object o) { 197cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (o == this) { 198cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return true; 199cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 200cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (!(o instanceof FieldArray)) { 201cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return false; 202cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 203cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 204cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira FieldArray other = (FieldArray) o; 205cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (size() != other.size()) { // size() will call gc() if necessary. 206cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return false; 207cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 208cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return arrayEquals(mFieldNumbers, other.mFieldNumbers, mSize) && 209cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira arrayEquals(mData, other.mData, mSize); 210cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 211cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 212cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira @Override 213cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira public int hashCode() { 214cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (mGarbage) { 215cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira gc(); 216cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 217cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira int result = 17; 218cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira for (int i = 0; i < mSize; i++) { 219cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira result = 31 * result + mFieldNumbers[i]; 220cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira result = 31 * result + mData[i].hashCode(); 221cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 222cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return result; 223cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 224cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 225cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira private int idealIntArraySize(int need) { 226cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return idealByteArraySize(need * 4) / 4; 227cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 228cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 229cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira private int idealByteArraySize(int need) { 230cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira for (int i = 4; i < 32; i++) 231cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (need <= (1 << i) - 12) 232cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return (1 << i) - 12; 233cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 234cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return need; 235cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 236cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 237cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira private int binarySearch(int value) { 238cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira int lo = 0; 239cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira int hi = mSize - 1; 240cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 241cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira while (lo <= hi) { 242cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira int mid = (lo + hi) >>> 1; 243cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira int midVal = mFieldNumbers[mid]; 244cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 245cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (midVal < value) { 246cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira lo = mid + 1; 247cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } else if (midVal > value) { 248cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira hi = mid - 1; 249cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } else { 250cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return mid; // value found 251cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 252cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 253cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return ~lo; // value not present 254cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 255cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 256cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira private boolean arrayEquals(int[] a, int[] b, int size) { 257cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira for (int i = 0; i < size; i++) { 258cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (a[i] != b[i]) { 259cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return false; 260cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 261cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 262cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return true; 263cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 264cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira 265cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira private boolean arrayEquals(FieldData[] a, FieldData[] b, int size) { 266cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira for (int i = 0; i < size; i++) { 267cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira if (!a[i].equals(b[i])) { 268cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return false; 269cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 270cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 271cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira return true; 272cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira } 273cf1b416ae1327a26dd53a691fc1b3e30eec8e6a6Juan Silveira} 274