1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/* 2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project 3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License"); 5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License. 6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at 7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * http://www.apache.org/licenses/LICENSE-2.0 9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software 11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS, 12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and 14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License. 15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.util; 18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.ByteBlock; 20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/** 22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * A list of labeled items, allowing easy lookup by label. 23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic class LabeledList extends FixedSizeList { 25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Sparse array indexed by label to FixedSizeList index. 28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * -1 = invalid label. 29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final IntList labelToIndex; 31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** @inheritDoc */ 33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public LabeledList(int size) { 34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul super(size); 35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul labelToIndex = new IntList(size); 37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs a new instance that is a copy of the old instance. 41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param old instance to copy 43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul protected LabeledList(LabeledList old) { 45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul super(old.size()); 46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul labelToIndex = old.labelToIndex.mutableCopy(); 47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int sz = old.size(); 49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < sz; i++) { 51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Object one = old.get0(i); 52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (one != null) { 53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul set0(i, one); 54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the maximum label (exclusive) of any block added to this instance. 60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= 0;} the maximum label 62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int getMaxLabel() { 64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int sz = labelToIndex.size(); 65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul // Gobble any deleted labels that may be at the end... 67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int i; 68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (i = sz - 1; (i >= 0) && (labelToIndex.get(i) < 0); i--) 69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul ; 70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int newSize = i+1; 72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul labelToIndex.shrink(newSize); 74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return newSize; 76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Removes a label from the label-to-index mapping 80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param oldLabel label to remove 81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul protected void removeLabel(int oldLabel) { 83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul labelToIndex.set(oldLabel, -1); 84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Adds a label and index to the label-to-index mapping 88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param label new label 89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param index index of block. 90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul protected void addLabelIndex(int label, int index) { 92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int origSz = labelToIndex.size(); 93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i <= (label - origSz); i++) { 95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul labelToIndex.add(-1); 96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul labelToIndex.set(label, index); 99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the index of the first item in the list with the given 103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * label, if any. 104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param label {@code >= 0;} the label to look for 106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= -1;} the index of the so-labelled item, or {@code -1} 107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * if none is found 108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int indexOfLabel(int label) { 110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (label >= labelToIndex.size()) { 111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return -1; 112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } else { 113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return labelToIndex.get(label); 114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** @inheritDoc */ 118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul @Override 119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public void shrinkToFit() { 120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul super.shrinkToFit(); 121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul rebuildLabelToIndex(); 123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Rebuilds the label-to-index mapping after a shrinkToFit(). 127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Note: assumes that the labels that are in the list are the same 128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * although the indicies may have changed. 129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul protected void rebuildLabelToIndex() { 131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int szItems = size(); 132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < szItems; i++) { 134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul LabeledItem li = (LabeledItem)get0(i); 135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (li != null) { 137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul labelToIndex.set(li.getLabel(), i); 138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Sets the element at the given index. 144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param n {@code >= 0, < size();} which element 146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param item {@code null-ok;} the value to store 147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul protected void set(int n, LabeledItem item) { 149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul LabeledItem old = (LabeledItem) getOrNull0(n); 150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 151917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul set0(n, item); 152917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 153917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (old != null) { 154917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul removeLabel(old.getLabel()); 155917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 156917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 157917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (item != null) { 158917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul addLabelIndex(item.getLabel(), n); 159917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 160917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 161917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul} 162