001: /*
002: * $RCSfile: HashKey.java,v $
003: *
004: * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006: *
007: * This code is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License version 2 only, as
009: * published by the Free Software Foundation. Sun designates this
010: * particular file as subject to the "Classpath" exception as provided
011: * by Sun in the LICENSE file that accompanied this code.
012: *
013: * This code is distributed in the hope that it will be useful, but WITHOUT
014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: * version 2 for more details (a copy is included in the LICENSE file that
017: * accompanied this code).
018: *
019: * You should have received a copy of the GNU General Public License version
020: * 2 along with this work; if not, write to the Free Software Foundation,
021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024: * CA 95054 USA or visit www.sun.com if you need additional information or
025: * have any questions.
026: *
027: * $Revision: 1.5 $
028: * $Date: 2008/02/28 20:17:23 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: class HashKey extends Object {
035:
036: /**
037: * The value is used for character storage.
038: */
039: char value[];
040:
041: /**
042: * The count is the number of characters in the buffer.
043: */
044: int count = 0;
045:
046: HashKey() {
047: this (16);
048: }
049:
050: HashKey(int length) {
051: value = new char[length];
052: }
053:
054: HashKey(HashKey hashkey) {
055: this .set(hashkey);
056: }
057:
058: HashKey(String str) {
059: this (str.length() + 16);
060: append(str);
061: }
062:
063: void set(HashKey hashkey) {
064: int i;
065:
066: if (this .count < hashkey.count) {
067: this .value = new char[hashkey.count];
068: }
069:
070: for (i = 0; i < hashkey.count; i++) {
071: this .value[i] = hashkey.value[i];
072: }
073: this .count = hashkey.count;
074: }
075:
076: void reset() {
077: count = 0;
078: }
079:
080: void ensureCapacity(int minimumCapacity) {
081: int maxCapacity = value.length;
082:
083: if (minimumCapacity > maxCapacity) {
084: int newCapacity = (maxCapacity + 1) * 2;
085: if (minimumCapacity > newCapacity) {
086: newCapacity = minimumCapacity;
087: }
088:
089: char newValue[] = new char[newCapacity];
090: System.arraycopy(value, 0, newValue, 0, count);
091: value = newValue;
092: }
093: }
094:
095: HashKey append(String str) {
096: int len = 0;
097:
098: if (str == null)
099: return this ;
100:
101: len = str.length();
102: ensureCapacity(count + len);
103: str.getChars(0, len, value, count);
104: count += len;
105: return this ;
106: }
107:
108: public int hashCode() {
109: int h = 0;
110: int off = 0;
111: char val[] = value;
112: int len = count;
113:
114: if (len < 16) {
115: for (int i = len; i > 0; i--) {
116: h = (h * 37) + val[off++];
117: }
118: } else {
119: // only sample some characters
120: int skip = len / 8;
121: for (int i = len; i > 0; i -= skip, off += skip) {
122: h = (h * 39) + val[off];
123: }
124: }
125: return h;
126: }
127:
128: public boolean equals(Object anObject) {
129: if ((anObject != null) && (anObject instanceof HashKey)) {
130: HashKey anotherHashKey = (HashKey) anObject;
131: int n = count;
132: if (n == anotherHashKey.count) {
133: char v1[] = value;
134: char v2[] = anotherHashKey.value;
135: ;
136: int i = 0;
137: int j = 0;
138: while (n-- != 0) {
139: if (v1[i++] != v2[j++]) {
140: return false;
141: }
142: }
143: return true;
144: }
145: }
146: return false;
147: }
148:
149: /* For internal use only. */
150: private int equals(HashKey hk) {
151: int index = 0;
152:
153: while ((index < count) && (index < hk.count)) {
154: if (value[index] < hk.value[index])
155: return -1;
156: else if (value[index] > hk.value[index])
157: return 1;
158: index++;
159: }
160:
161: if (count == hk.count)
162: // Found it!
163: return 0;
164: else if (count < hk.count)
165: return -1;
166: else
167: return 1;
168:
169: }
170:
171: /* For package use only. */
172: int equals(HashKey localToVworldKeys[], int start, int end) {
173: int mid;
174:
175: mid = start + ((end - start) / 2);
176: if (localToVworldKeys[mid] != null) {
177: int test = equals(localToVworldKeys[mid]);
178:
179: if ((test < 0) && (start != mid))
180: return equals(localToVworldKeys, start, mid);
181: else if ((test > 0) && (start != mid))
182: return equals(localToVworldKeys, mid, end);
183: else if (test == 0)
184: return mid;
185: else
186: return -1;
187: }
188: // A null haskey encountered.
189: return -2;
190: }
191:
192: /* For package use only. */
193: boolean equals(HashKey localToVworldKeys[], int[] index, int start,
194: int end) {
195:
196: int mid;
197:
198: mid = start + ((end - start) / 2);
199: if (localToVworldKeys[mid] != null) {
200: int test = equals(localToVworldKeys[mid]);
201:
202: if (start != mid) {
203: if (test < 0) {
204: return equals(localToVworldKeys, index, start, mid);
205: } else if (test > 0) {
206: return equals(localToVworldKeys, index, mid, end);
207: }
208: } else { // (start == mid)
209: if (test < 0) {
210: index[0] = mid;
211: return false;
212: } else if (test > 0) {
213: index[0] = mid + 1;
214: return false;
215: }
216: }
217:
218: // (test == 0)
219: index[0] = mid;
220: return true;
221:
222: }
223: // A null haskey encountered.
224: // But we still want to return the index where we encounter it.
225: index[0] = mid;
226: return false;
227: }
228:
229: public String toString() {
230: return new String(value, 0, count);
231: }
232:
233: String getLastNodeId() {
234: int i, j, temp;
235:
236: for (i = (count - 1); i > 0; i--)
237: if (value[i] == '+')
238: break;
239:
240: if (i > 0) {
241: value[i++] = '\0';
242: temp = count - i;
243: char v1[] = new char[temp];
244: for (j = 0; j < temp; j++, i++) {
245: v1[j] = value[i];
246: value[i] = '\0';
247: }
248: count = count - (temp + 1);
249: return new String(v1);
250: }
251:
252: return new String(value, 0, count);
253: }
254:
255: }
|