WALA/com.ibm.wala.util/src/com/ibm/wala/util/intset/TwoLevelIntVector.java

115 lines
2.9 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.io.Serializable;
import java.util.Vector;
import com.ibm.wala.util.math.Logs;
/**
* an int vector implementation which delegates to pages of int vectors.
*/
public class TwoLevelIntVector implements IntVector, Serializable {
private static final long serialVersionUID = -7383053435395846217L;
private static final int PAGE_SIZE = 4096;
private static final int LOG_PAGE_SIZE = Logs.log2(PAGE_SIZE);
int maxIndex = -1;
/**
* Array of IntVector: data.get(i) holds data[i*PAGE_SIZE] ... data[(i+1)*PAGESIZE - 1]
*/
final private Vector<SparseIntVector> data = new Vector<>();
private final int defaultValue;
TwoLevelIntVector(int defaultValue) {
this.defaultValue = defaultValue;
}
/*
* @see com.ibm.wala.util.intset.IntVector#get(int)
*/
@Override
public int get(int x) {
int page = getPageNumber(x);
if (page >= data.size()) {
return defaultValue;
}
IntVector v = data.get(page);
if (v == null) {
return defaultValue;
}
int localX = toLocalIndex(x, page);
return v.get(localX);
}
private static int toLocalIndex(int x, int page) {
return x - getFirstIndexOnPage(page);
}
private static int getFirstIndexOnPage(int page) {
return page << LOG_PAGE_SIZE;
}
private static int getPageNumber(int x) {
return x >> LOG_PAGE_SIZE;
}
/*
* TODO: this can be optimized
*
* @see com.ibm.wala.util.intset.IntVector#set(int, int)
*/
@Override
public void set(int x, int value) {
maxIndex = Math.max(maxIndex, x);
int page = getPageNumber(x);
IntVector v = findOrCreatePage(page);
int localX = toLocalIndex(x, page);
v.set(localX, value);
}
private IntVector findOrCreatePage(int page) {
if (page >= data.size()) {
SparseIntVector v = new SparseIntVector(defaultValue);
data.setSize(page + 1);
data.add(page, v);
return v;
} else {
SparseIntVector v = data.get(page);
if (v == null) {
v = new SparseIntVector(defaultValue);
data.set(page, v);
}
return v;
}
}
/*
* @see com.ibm.wala.util.debug.VerboseAction#performVerboseAction()
*/
public void performVerboseAction() {
System.err.println(("stats of " + getClass()));
System.err.println(("data: size = " + data.size()));
}
@Override
public int getMaxIndex() {
return maxIndex;
}
}