
soot.util.SmallNumberedMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of soot Show documentation
Show all versions of soot Show documentation
A Java Optimization Framework
package soot.util;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2002 Ondrej Lhotak
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.util.Iterator;
/**
* A java.util.Map-like map with Numberable objects as the keys.
*
* @author Ondrej Lhotak
*/
public final class SmallNumberedMap implements INumberedMap {
public SmallNumberedMap() {
//
}
@Override
public boolean put(Numberable key, T value) {
int pos = findPosition(key);
if (array[pos] == key) {
if (values[pos] == value) {
return false;
}
values[pos] = value;
return true;
}
size++;
if (size * 3 > array.length * 2) {
doubleSize();
pos = findPosition(key);
}
array[pos] = key;
values[pos] = value;
return true;
}
@Override
public T get(Numberable key) {
return (T) values[findPosition(key)];
}
@Override
public void remove(Numberable key) {
int pos = findPosition(key);
if (array[pos] == key) {
array[pos] = null;
values[pos] = null;
size--;
}
}
/** Returns the number of non-null values in this map. */
public int nonNullSize() {
int ret = 0;
for (Object element : values) {
if (element != null) {
ret++;
}
}
return ret;
}
@Override
public Iterator keyIterator() {
return new KeyIterator(this);
}
/** Returns an iterator over the non-null values. */
public Iterator iterator() {
return new ValueIterator(this);
}
abstract class SmallNumberedMapIterator implements Iterator {
SmallNumberedMap map;
int cur = 0;
SmallNumberedMapIterator(SmallNumberedMap map) {
this.map = map;
seekNext();
}
protected final void seekNext() {
try {
while (map.values[cur] == null) {
cur++;
}
} catch (ArrayIndexOutOfBoundsException e) {
cur = -1;
}
}
public final boolean hasNext() {
return cur != -1;
}
public abstract C next();
}
class KeyIterator extends SmallNumberedMapIterator {
KeyIterator(SmallNumberedMap map) {
super(map);
}
public final Numberable next() {
Numberable ret = array[cur];
cur++;
seekNext();
return ret;
}
@Override
public void remove() {
array[cur - 1] = null;
values[cur - 1] = null;
}
}
class ValueIterator extends SmallNumberedMapIterator {
ValueIterator(SmallNumberedMap map) {
super(map);
}
public final T next() {
Object ret = values[cur];
cur++;
seekNext();
return (T) ret;
}
@Override
public void remove() {
array[cur - 1] = null;
values[cur - 1] = null;
}
}
/* Private stuff. */
private final int findPosition(Numberable o) {
int number = o.getNumber();
if (number == 0) {
throw new RuntimeException("unnumbered");
}
number = number & (array.length - 1);
while (true) {
if (array[number] == o) {
return number;
}
if (array[number] == null) {
return number;
}
number = (number + 1) & (array.length - 1);
}
}
private final void doubleSize() {
Numberable[] oldArray = array;
Object[] oldValues = values;
int newLength = array.length * 2;
values = new Object[newLength];
array = new Numberable[newLength];
for (int i = 0; i < oldArray.length; i++) {
Numberable element = oldArray[i];
if (element != null) {
int pos = findPosition(element);
array[pos] = element;
values[pos] = oldValues[i];
}
}
}
private Numberable[] array = new Numberable[8];
private Object[] values = new Object[8];
private int size = 0;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy