115 lines
2.9 KiB
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;
|
|
}
|
|
|
|
}
|