001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Eclipse Public License (EPL);
005 * You may not use this file except in compliance with the License. You
006 * may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 * See the COPYRIGHT.txt file distributed with this work for information
011 * regarding copyright ownership.
012 */
013 package org.jikesrvm.classloader;
014
015 import java.util.WeakHashMap;
016
017 /**
018 * Lightweight implementation of a vector of Fields.
019 */
020 final class TypeReferenceVector {
021 //-----------//
022 // interface //
023 //-----------//
024
025 public TypeReferenceVector() {
026 array = new TypeReference[10];
027 }
028
029 // Add item.
030 //
031 void addElement(TypeReference item) {
032 if (cnt == array.length) {
033 adjustLength(cnt << 1); // double size of array
034 }
035 array[cnt++] = item;
036 }
037
038 // Add item if it is not already in the Vector.
039 //
040 public void addUniqueElement(TypeReference item) {
041 for (int i = 0; i < cnt; i++) {
042 if (array[i] == item) return;
043 }
044 addElement(item);
045 }
046
047 // Get item.
048 //
049 TypeReference elementAt(int index) {
050 return array[index];
051 }
052
053 // Set item.
054 //
055 void setElementAt(TypeReference item, int index) {
056 array[index] = item;
057 }
058
059 // Get number of items added so far.
060 //
061 public int size() {
062 return cnt;
063 }
064
065 // Get array, trimmed to size.
066 //
067 public TypeReference[] finish() {
068 TypeReference[] result = popularTRVs.get(this);
069 if (result != null) {
070 array = result;
071 return result;
072 } else {
073 adjustLength(cnt);
074 popularTRVs.put(this, array);
075 return array;
076 }
077 }
078
079 public int hashCode() {
080 int val=0;
081 for(int i=0; i<cnt; i++) {
082 val ^= array[i].hashCode();
083 }
084 return val;
085 }
086
087 public boolean equals(Object obj) {
088 if (obj instanceof TypeReferenceVector) {
089 TypeReferenceVector that = (TypeReferenceVector)obj;
090 if (cnt != that.cnt) return false;
091 for(int i=0; i<cnt; i++) {
092 if (array[i] != that.array[i]) return false;
093 }
094 return true;
095 } else {
096 return false;
097 }
098 }
099
100 //----------------//
101 // implementation //
102 //----------------//
103
104 private TypeReference[] array;
105 private int cnt;
106
107 private static final TypeReference[] empty = new TypeReference[0];
108 private static final WeakHashMap<TypeReferenceVector,TypeReference[]>
109 popularTRVs = new WeakHashMap<TypeReferenceVector,TypeReference[]>();
110
111 private void adjustLength(int newLength) {
112 if (newLength == 0) {
113 array = empty;
114 } else {
115 TypeReference[] newElements = new TypeReference[newLength];
116 int n = array.length;
117 if (n > newLength) {
118 n = newLength;
119 }
120
121 for (int i = 0; i < n; ++i) {
122 newElements[i] = array[i];
123 }
124
125 array = newElements;
126 }
127 }
128 }