/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.jikesrvm.classloader;
import java.util.WeakHashMap;
/**
* Lightweight implementation of a vector of Fields. This class is intended
* to be used by a single thread and is therefore not thread-safe.
*/
final class FieldVector {
//-----------//
// interface //
//-----------//
FieldVector() {
array = new RVMField[10];
}
void addElement(RVMField item) {
if (cnt == array.length) {
adjustLength(cnt << 1); // double size of array
}
array[cnt++] = item;
}
/**
* @return an array of fields, trimmed to size. The returned array
* is canonical: Adding the same set of fields in the same order
* to different newly-created vectors {@code v1} and {@code v2}
* will lead to the same array being returned for both {@code v1}
* and {@code v2} when this method is called.
*/
public RVMField[] finish() {
synchronized (RVMField.class) {
RVMField[] result = popularFVs.get(this);
if (result != null) {
array = result;
return result;
} else {
adjustLength(cnt);
popularFVs.put(this, array);
return array;
}
}
}
@Override
public int hashCode() {
int val = 0;
for (int i = cnt - 1; i >= 0; i--) {
val ^= array[i].hashCode();
}
return val;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof FieldVector) {
FieldVector that = (FieldVector)obj;
if (cnt != that.cnt) return false;
for (int i = cnt - 1; i >= 0; i--) {
if (array[i] != that.array[i]) return false;
}
return true;
} else {
return false;
}
}
//----------------//
// implementation //
//----------------//
private RVMField[] array;
private int cnt;
private static final RVMField[] empty = new RVMField[0];
private static final WeakHashMap<FieldVector, RVMField[]>
popularFVs = new WeakHashMap<FieldVector, RVMField[]>();
private void adjustLength(int newLength) {
if (newLength == 0) {
array = empty;
} else {
RVMField[] newElements = new RVMField[newLength];
int n = array.length;
if (n > newLength) {
n = newLength;
}
for (int i = 0; i < n; ++i) {
newElements[i] = array[i];
}
array = newElements;
}
}
}