001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026: package com.sun.midp.rms;
027:
028: /**
029: * This class implements a mapping int --> int.
030: * (Analogs: vector, hash table, etc.) The implementation uses two arrays:
031: * one for keys and one for values.
032: * The methods are analogous to those of the java.util.Vector class.
033: */
034: class IntToIntMapper {
035: /**
036: * The array buffer into which the values to be returned are
037: * stored. The capacity of the mapper is the length of this array buffer.
038: */
039: protected int elementData[];
040:
041: /**
042: * The array buffer into which the values used as keys are
043: * stored. The capacity of the mapper is the length of this array buffer.
044: */
045: protected int elementKey[];
046:
047: /**
048: * The number of valid components in the mapper.
049: */
050: protected int elementCount;
051:
052: /**
053: * The amount by which the capacity is automatically
054: * incremented when its size becomes greater than its capacity. If
055: * the capacity increment is <code>0</code>, the capacity
056: * is doubled each time it needs to grow.
057: */
058: protected int capacityIncrement;
059:
060: /**
061: * The value returned if no value is associated with the key
062: * searched for.
063: */
064: public int defaultValue;
065:
066: /**
067: * Constructs an empty mapper with the specified initial capacity and
068: * capacity increment.
069: *
070: * @param initialCapacity the initial capacity of the mapper.
071: * @param defaultElement the value that gets returned for
072: * keys that are not there
073: * @param capacityIncrement the amount by which the capacity is
074: * increased when the mapper overflows.
075: * (0 means "to be doubled")
076: * @exception IllegalArgumentException if the specified initial capacity
077: * is negative
078: */
079: public IntToIntMapper(int initialCapacity, int defaultElement,
080: int capacityIncrement) {
081: super ();
082: if (initialCapacity < 0) {
083: throw new IllegalArgumentException();
084: }
085: this .elementData = new int[initialCapacity];
086: this .elementKey = new int[initialCapacity];
087: this .capacityIncrement = capacityIncrement;
088: this .defaultValue = defaultElement;
089: }
090:
091: /*
092: / * * this code used to be used in Vector.... not needed here for now
093: *
094: * Increases the capacity of this mapper, if necessary, to ensure
095: * that it can hold at least the number of components specified by
096: * the minimum capacity argument.
097: *
098: * @param minCapacity the desired minimum capacity.
099: */
100: /*
101: public synchronized void ensureCapacity(int minCapacity) {
102: if (minCapacity > elementData.length) {
103: ensureCapacityHelper(minCapacity);
104: }
105: }
106: */
107: /**
108: * This implements the unsynchronized semantics of ensureCapacity.
109: * Synchronized methods in this class can internally call this
110: * method for ensuring capacity without incurring the cost of an
111: * extra synchronization.
112: *
113: * This function increases the size of the mapper according to the
114: * value of capacityIncrement, and makes sure that the new size
115: * is not less than minCapacity.
116: *
117: * @param minCapacity the desired minimum capacity.
118: */
119: private void ensureCapacityHelper(int minCapacity) {
120: int oldCapacity = elementData.length;
121: int oldData[] = elementData;
122: int oldKey[] = elementKey;
123: int newCapacity = (capacityIncrement > 0) ? (oldCapacity + capacityIncrement)
124: : (oldCapacity * 2);
125: if (newCapacity < minCapacity) {
126: newCapacity = minCapacity;
127: }
128:
129: elementData = new int[newCapacity];
130: elementKey = new int[newCapacity];
131: System.arraycopy(oldData, 0, elementData, 0, elementCount);
132: System.arraycopy(oldKey, 0, elementKey, 0, elementCount);
133: }
134:
135: /**
136: * Returns the number of components in this mapper.
137: *
138: * @return the number of components in this mapper.
139: */
140: public int size() {
141: return elementCount;
142: }
143:
144: /**
145: * Tests if this mapper has no components.
146: *
147: * @return <code>true</code> if this mapper has no components;
148: * <code>false</code> otherwise.
149: */
150: public boolean isEmpty() {
151: return elementCount == 0;
152: }
153:
154: /**
155: * Returns the component at the specified key.
156: *
157: * @param key a key identifying an object in the mapper
158: * @return the component at the specified key, or the default value
159: * if an invalid key was given.
160: */
161: public synchronized int elementAt(int key) {
162: for (int i = 0; i < elementCount; i++) {
163: if (key == elementKey[i]) {
164: return elementData[i];
165: }
166: }
167: return defaultValue;
168: }
169:
170: /**
171: * Adds the specified component to the end of this mapper,
172: * increasing its size by one. The capacity of this mapper is
173: * increased if its size becomes greater than its capacity.
174: *
175: * @param obj the component to be added.
176: * @param key the key for that component.
177: */
178: private void addElement(int obj, int key) {
179: int newcount = elementCount + 1;
180: if (newcount > elementData.length) {
181: ensureCapacityHelper(newcount);
182: }
183: elementKey[elementCount] = key;
184: elementData[elementCount++] = obj;
185: }
186:
187: /**
188: * Sets the component at the specified <code>key</code> of this
189: * mapper to be the specified value. The previous component at that
190: * position is discarded.
191: *
192: * @param obj what the component is to be set to.
193: * @param key the key for that component.
194: */
195: public synchronized void setElementAt(int obj, int key) {
196: for (int i = 0; i < elementCount; i++)
197: if (key == elementKey[i]) {
198: elementData[i] = obj;
199: return;
200: }
201: addElement(obj, key);
202: }
203:
204: /**
205: * Deletes the component at the specified key. Nothing happens if
206: * no component has been associated with the key.
207: *
208: * @param key the key of the object to remove.
209: */
210: public synchronized void removeElementAt(int key) {
211: final int nowhere = -1;
212: int where = nowhere;
213: for (int i = 0; i < elementCount; i++) {
214: if (key == elementKey[i]) {
215: where = i;
216: break;
217: }
218: }
219: if (where == nowhere) {
220: return;
221: }
222:
223: // breaking the order :(
224: if (where < elementCount--) {
225: elementKey[where] = elementKey[elementCount];
226: elementData[where] = elementData[elementCount];
227: }
228: }
229: }
|