/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util.containers;
import com.intellij.openapi.diagnostic.Logger;
/**
* @author Dmitry.Shtukenberg
*/
public final class VariableWidthIntArray implements Cloneable {
private static final Logger LOG = Logger.getInstance("#com.intellij.util.containers.VariableWidthIntArray");
private int[] intArray = null;
private short[] shortArray = null;
private byte[] byteArray = null;
private final int minValue;
private final int maxValue;
static final int INT = 1;
static final int SHORT = 2;
static final int BYTE = 3;
private final int arrayType;
public VariableWidthIntArray( int minValue, int maxValue, int initialCapacity ) {
this.minValue = minValue;
this.maxValue = maxValue;
if( minValue < Short.MIN_VALUE || maxValue > Short.MAX_VALUE ) {
intArray = new int[ bestSize(initialCapacity) ];
arrayType = INT;
}
else if( minValue < Byte.MIN_VALUE || maxValue > Byte.MAX_VALUE ) {
shortArray = new short[ bestSize(initialCapacity) ];
arrayType = SHORT;
}
else {
byteArray = new byte[ bestSize(initialCapacity) ];
arrayType = BYTE;
}
}
static int bestSize( int maxSize ) {
int newSize = (int)(((double)maxSize) * 5 / 4);
return newSize <= maxSize ? maxSize + 1 : newSize;
}
public void ensureArraySize( int index ) {
if( intArray != null && intArray.length <= index ) {
int[] tmp = new int[ bestSize(index) ];
System.arraycopy( intArray, 0, tmp, 0, intArray.length );
intArray = tmp;
}
else if( shortArray != null && shortArray.length <= index ) {
short[] tmp = new short[ bestSize(index) ];
System.arraycopy( shortArray, 0, tmp, 0, shortArray.length );
shortArray = tmp;
}
else if( byteArray.length <= index ) {
byte[] tmp = new byte[ bestSize(index) ];
System.arraycopy( byteArray, 0, tmp, 0, byteArray.length );
byteArray = tmp;
}
}
public int get( int index ) {
switch( arrayType ) {
case INT: return intArray[index];
case SHORT: return shortArray[index];
case BYTE: return byteArray[index];
}
LOG.error("No array allocated");
return 0;
}
public void put( int index, int value ) {
if( value < minValue || value > maxValue ) {
LOG.error("Value out of domain");
}
switch( arrayType ) {
case INT: intArray[index] = value; return;
case SHORT: shortArray[index] = (short)value; return;
case BYTE: byteArray[index] = (byte)value; return;
}
LOG.error("No array allocated");
}
public Object clone() throws CloneNotSupportedException {
VariableWidthIntArray arr = (VariableWidthIntArray)super.clone();
if( intArray != null ) { arr.intArray = intArray.clone(); }
if( shortArray != null ) { arr.shortArray = shortArray.clone(); }
if( byteArray != null ) { arr.byteArray = byteArray.clone(); }
return arr;
}
public void arraycopy(int[] src, int from, int to, int count) {
for( int i = 0; i < count; i++ )
put( i + to, src[i + from] );
}
public void move(int from, int to, int count) {
switch( arrayType ) {
case INT: System.arraycopy( intArray, from, intArray, to, count ); break;
case SHORT: System.arraycopy( shortArray, from, shortArray, to, count ); break;
case BYTE: System.arraycopy( byteArray, from, byteArray, to, count ); break;
default:
LOG.error("Invalid array type");
}
}
public boolean arrayequal( VariableWidthIntArray src, int srcfrom, int from, int count ) {
if( src.arrayType != arrayType ) return false;
for( int i = 0; i < count; i++ )
if( get(from+i) != src.get(srcfrom+i)) return false;
return true;
}
}