187 lines
4.7 KiB
Java
187 lines
4.7 KiB
Java
/*******************************************************************************
|
|
* Copyright (c) 2002 - 2006 IBM Corporation.
|
|
* All rights reserved. This program and the accompanying materials
|
|
* are made available under the terms of the Eclipse Public License v1.0
|
|
* which accompanies this distribution, and is available at
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
*
|
|
* Contributors:
|
|
* IBM Corporation - initial API and implementation
|
|
*******************************************************************************/
|
|
package com.ibm.wala.util.intset;
|
|
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
|
|
import com.ibm.wala.util.collections.HashMapFactory;
|
|
|
|
/**
|
|
* A bit set mapping based on an object array. This is not terribly efficient, but is useful for prototyping.
|
|
*/
|
|
public class MutableMapping<T> implements OrdinalSetMapping<T> {
|
|
|
|
private static final int INITIAL_CAPACITY = 20;
|
|
|
|
private final static int MAX_SIZE = Integer.MAX_VALUE / 4;
|
|
|
|
public static <T> MutableMapping<T> make() {
|
|
return new MutableMapping<T>();
|
|
}
|
|
|
|
private Object[] array;
|
|
|
|
private int nextIndex = 0;
|
|
|
|
/**
|
|
* A mapping from object to Integer.
|
|
*/
|
|
final HashMap<T, Integer> map = HashMapFactory.make();
|
|
|
|
/**
|
|
* @throws IllegalArgumentException if array is null
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public MutableMapping(final Object[] array) {
|
|
if (array == null) {
|
|
throw new IllegalArgumentException("array is null");
|
|
}
|
|
this.array = new Object[2 * array.length];
|
|
for (int i = 0; i < array.length; i++) {
|
|
this.array[i] = array[i];
|
|
map.put((T) array[i], Integer.valueOf(i));
|
|
}
|
|
nextIndex = array.length;
|
|
}
|
|
|
|
protected MutableMapping() {
|
|
array = new Object[INITIAL_CAPACITY];
|
|
nextIndex = 0;
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
public T getMappedObject(int n) {
|
|
try {
|
|
return (T) array[n];
|
|
} catch (ArrayIndexOutOfBoundsException e) {
|
|
throw new IllegalArgumentException("n out of range " + n);
|
|
}
|
|
}
|
|
|
|
public int getMappedIndex(T o) {
|
|
Integer I = map.get(o);
|
|
if (I == null) {
|
|
return -1;
|
|
} else {
|
|
return I.intValue();
|
|
}
|
|
|
|
}
|
|
|
|
public boolean hasMappedIndex(T o) {
|
|
return map.get(o) != null;
|
|
}
|
|
|
|
/**
|
|
* Add an object to the set of mapped objects.
|
|
*
|
|
* @return the integer to which the object is mapped.
|
|
*/
|
|
public int add(T o) {
|
|
Integer I = map.get(o);
|
|
if (I != null) {
|
|
return I.intValue();
|
|
}
|
|
map.put(o, new Integer(nextIndex));
|
|
if (nextIndex >= array.length) {
|
|
Object[] old = array;
|
|
array = new Object[2 * array.length];
|
|
System.arraycopy(old, 0, array, 0, old.length);
|
|
}
|
|
int result = nextIndex++;
|
|
array[result] = o;
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
StringBuffer result = new StringBuffer();
|
|
for (int i = 0; i < nextIndex; i++) {
|
|
result.append(i).append(" ").append(array[i]).append("\n");
|
|
}
|
|
return result.toString();
|
|
}
|
|
|
|
/*
|
|
* @see com.ibm.wala.util.intset.OrdinalSetMapping#iterator()
|
|
*/
|
|
public Iterator<T> iterator() {
|
|
return map.keySet().iterator();
|
|
}
|
|
|
|
/*
|
|
* @see com.ibm.wala.util.intset.OrdinalSetMapping#makeSingleton(int)
|
|
*/
|
|
public OrdinalSet<T> makeSingleton(int i) {
|
|
return new OrdinalSet<T>(SparseIntSet.singleton(i), this);
|
|
}
|
|
|
|
/**
|
|
* @param n
|
|
*/
|
|
public void deleteMappedObject(T n) {
|
|
int index = getMappedIndex(n);
|
|
if (index != -1) {
|
|
array[index] = null;
|
|
map.remove(n);
|
|
}
|
|
}
|
|
|
|
public Collection<T> getObjects() {
|
|
return Collections.unmodifiableCollection(map.keySet());
|
|
}
|
|
|
|
/**
|
|
* Replace a in this mapping with b.
|
|
*/
|
|
public void replace(T a, T b) throws IllegalArgumentException {
|
|
int i = getMappedIndex(a);
|
|
if (i == -1) {
|
|
throw new IllegalArgumentException("first element does not exist in map");
|
|
}
|
|
map.remove(a);
|
|
map.put(b, new Integer(i));
|
|
array[i] = b;
|
|
}
|
|
|
|
/**
|
|
* Add an object to the set of mapped objects at index i.
|
|
*/
|
|
public void put(int i, T o) {
|
|
|
|
if (i < 0 || i > MAX_SIZE) {
|
|
throw new IllegalArgumentException("invalid i: " + i);
|
|
}
|
|
Integer I = Integer.valueOf(i);
|
|
map.put(o, I);
|
|
if (i >= array.length) {
|
|
Object[] old = array;
|
|
array = new Object[2 * i];
|
|
System.arraycopy(old, 0, array, 0, old.length);
|
|
}
|
|
array[i] = o;
|
|
nextIndex = Math.max(nextIndex, i + 1);
|
|
|
|
}
|
|
|
|
public int getMaximumIndex() {
|
|
return nextIndex - 1;
|
|
}
|
|
|
|
public int getSize() {
|
|
return map.size();
|
|
}
|
|
|
|
}
|