FileDocCategorySizeDatePackage
PackedIntVector.javaAPI DocAndroid 1.5 API11523Wed May 06 22:41:56 BST 2009android.text

PackedIntVector

public class PackedIntVector extends Object
PackedIntVector stores a two-dimensional array of integers, optimized for inserting and deleting rows and for offsetting the values in segments of a given column.

Fields Summary
private final int
mColumns
private int
mRows
private int
mRowGapStart
private int
mRowGapLength
private int[]
mValues
private int[]
mValueGap
Constructors Summary
public PackedIntVector(int columns)
Creates a new PackedIntVector with the specified width and a height of 0.

param
columns the width of the PackedIntVector.

        mColumns = columns;
        mRows = 0;

        mRowGapStart = 0;
        mRowGapLength = mRows;

        mValues = null;
        mValueGap = new int[2 * columns];
    
Methods Summary
public voidadjustValuesBelow(int startRow, int column, int delta)
Increments all values in the specified column whose row >= the specified row by the specified delta.

param
startRow the row at which to begin incrementing. This may be == size(), which case there is no effect.
param
column the index of the column to set.
throws
IndexOutOfBoundsException if the row is out of range (startRow < 0 || startRow > size()) or the column is out of range (column < 0 || column >= width()).

        if (((startRow | column) < 0) || (startRow > size()) ||
                (column >= width())) {
            throw new IndexOutOfBoundsException(startRow + ", " + column);
        }

        if (startRow >= mRowGapStart) {
            startRow += mRowGapLength;
        }

        moveValueGapTo(column, startRow);
        mValueGap[column + mColumns] += delta;
    
public voiddeleteAt(int row, int count)
Deletes the specified number of rows starting with the specified row.

param
row the index of the first row to be deleted.
param
count the number of rows to delete.
throws
IndexOutOfBoundsException if any of the rows to be deleted are out of range (row < 0 || count < 0 || row + count > size()).

        if (((row | count) < 0) || (row + count > size())) {
            throw new IndexOutOfBoundsException(row + ", " + count);
        }

        moveRowGapTo(row + count);

        mRowGapStart -= count;
        mRowGapLength += count;

        // TODO: Reclaim memory when the new height is much smaller
        // than the allocated size.
    
public intgetValue(int row, int column)
Returns the value at the specified row and column.

param
row the index of the row to return.
param
column the index of the column to return.
return
the value stored at the specified position.
throws
IndexOutOfBoundsException if the row is out of range (row < 0 || row >= size()) or the column is out of range (column < 0 || column >= width()).

        final int columns = mColumns;

        if (((row | column) < 0) || (row >= size()) || (column >= columns)) {
            throw new IndexOutOfBoundsException(row + ", " + column);
        }

        if (row >= mRowGapStart) {
            row += mRowGapLength;
        }

        int value = mValues[row * columns + column];

        int[] valuegap = mValueGap;
        if (row >= valuegap[column]) {
            value += valuegap[column + columns];
        }

        return value;
    
private final voidgrowBuffer()
Grows the value and gap arrays to be large enough to store at least one more than the current number of rows.

        final int columns = mColumns;
        int newsize = size() + 1;
        newsize = ArrayUtils.idealIntArraySize(newsize * columns) / columns;
        int[] newvalues = new int[newsize * columns];

        final int[] valuegap = mValueGap;
        final int rowgapstart = mRowGapStart;

        int after = mRows - (rowgapstart + mRowGapLength);

        if (mValues != null) {
            System.arraycopy(mValues, 0, newvalues, 0, columns * rowgapstart);
            System.arraycopy(mValues, (mRows - after) * columns,
                             newvalues, (newsize - after) * columns,
                             after * columns);
        }

        for (int i = 0; i < columns; i++) {
            if (valuegap[i] >= rowgapstart) {
                valuegap[i] += newsize - mRows;

                if (valuegap[i] < rowgapstart) {
                    valuegap[i] = rowgapstart;
                }
            }
        }

        mRowGapLength += newsize - mRows;
        mRows = newsize;
        mValues = newvalues;
    
public voidinsertAt(int row, int[] values)
Inserts a new row of values at the specified row offset.

param
row the row above which to insert the new row. This may be == size(), which case the new row is added at the end.
param
values the new values to be added. If this is null, a row of zeroes is added.
throws
IndexOutOfBoundsException if the row is out of range (row < 0 || row > size()) or if the length of the values array is too small (values.length < width()).

        if ((row < 0) || (row > size())) {
            throw new IndexOutOfBoundsException("row " + row);
        }

        if ((values != null) && (values.length < width())) {
            throw new IndexOutOfBoundsException("value count " + values.length);
        }

        moveRowGapTo(row);

        if (mRowGapLength == 0) {
            growBuffer();
        }

        mRowGapStart++;
        mRowGapLength--;

        if (values == null) {
            for (int i = mColumns - 1; i >= 0; i--) {
                setValueInternal(row, i, 0);
            }
        } else {
            for (int i = mColumns - 1; i >= 0; i--) {
                setValueInternal(row, i, values[i]);
            }
        }
    
private final voidmoveRowGapTo(int where)
Moves the gap in the row indices to begin at the specified row.

        if (where == mRowGapStart) {
            return;
        } else if (where > mRowGapStart) {
            int moving = where + mRowGapLength - (mRowGapStart + mRowGapLength);
            final int columns = mColumns;
            final int[] valuegap = mValueGap;
            final int[] values = mValues;
            final int gapend = mRowGapStart + mRowGapLength;

            for (int i = gapend; i < gapend + moving; i++) {
                int destrow = i - gapend + mRowGapStart;

                for (int j = 0; j < columns; j++) {
                    int val = values[i * columns+ j];

                    if (i >= valuegap[j]) {
                        val += valuegap[j + columns];
                    }

                    if (destrow >= valuegap[j]) {
                        val -= valuegap[j + columns];
                    }

                    values[destrow * columns + j] = val;
                }
            }
        } else /* where < mRowGapStart */ {
            int moving = mRowGapStart - where;
            final int columns = mColumns;
            final int[] valuegap = mValueGap;
            final int[] values = mValues;
            final int gapend = mRowGapStart + mRowGapLength;

            for (int i = where + moving - 1; i >= where; i--) {
                int destrow = i - where + gapend - moving;

                for (int j = 0; j < columns; j++) {
                    int val = values[i * columns+ j];

                    if (i >= valuegap[j]) {
                        val += valuegap[j + columns];
                    }

                    if (destrow >= valuegap[j]) {
                        val -= valuegap[j + columns];
                    }

                    values[destrow * columns + j] = val;
                }
            }
        }

        mRowGapStart = where;
    
private final voidmoveValueGapTo(int column, int where)
Moves the gap in the values of the specified column to begin at the specified row.

        final int[] valuegap = mValueGap;
        final int[] values = mValues;
        final int columns = mColumns;

        if (where == valuegap[column]) {
            return;
        } else if (where > valuegap[column]) {
            for (int i = valuegap[column]; i < where; i++) {
                values[i * columns + column] += valuegap[column + columns];
            }
        } else /* where < valuegap[column] */ {
            for (int i = where; i < valuegap[column]; i++) {
                values[i * columns + column] -= valuegap[column + columns];
            }
        }

        valuegap[column] = where;
    
public voidsetValue(int row, int column, int value)
Sets the value at the specified row and column.

param
row the index of the row to set.
param
column the index of the column to set.
throws
IndexOutOfBoundsException if the row is out of range (row < 0 || row >= size()) or the column is out of range (column < 0 || column >= width()).

        if (((row | column) < 0) || (row >= size()) || (column >= mColumns)) {
            throw new IndexOutOfBoundsException(row + ", " + column);
        }

        if (row >= mRowGapStart) {
            row += mRowGapLength;
        }

        int[] valuegap = mValueGap;
        if (row >= valuegap[column]) {
            value -= valuegap[column + mColumns];
        }

        mValues[row * mColumns + column] = value;
    
private voidsetValueInternal(int row, int column, int value)
Sets the value at the specified row and column. Private internal version: does not check args.

param
row the index of the row to set.
param
column the index of the column to set.

        if (row >= mRowGapStart) {
            row += mRowGapLength;
        }

        int[] valuegap = mValueGap;
        if (row >= valuegap[column]) {
            value -= valuegap[column + mColumns];
        }

        mValues[row * mColumns + column] = value;
    
public intsize()
Returns the number of rows in the PackedIntVector. This number will change as rows are inserted and deleted.

return
the number of rows.

        return mRows - mRowGapLength;
    
public intwidth()
Returns the width of the PackedIntVector. This number is set at construction and will not change.

return
the number of columns.

        return mColumns;