persistable sclass BlockOptimizedIntMatrix extends AbstractMatrix {
// Each block is square with side length being a power of two
// (i.e. blockSize = 1 << blockShift)
int blockShift, blockSize;
int bw, bh; // number of block cols/block rows
int[][] fullBlocks; // if entry != null, it's a detailed block
int[] simpleBlocks; // if fullBlocks entry is null, find block value here
*(int *w, int *h, int *blockShift) {
blockSize = 1 << blockShift;
bw = rshift_ceil(w, blockSize);
bh = rshift_ceil(h, blockSize);
simpleBlocks = new int[bw*bh];
fullBlocks = new int[bw*bh][];
}
public Int get(int x, int y) {
int bx = x >> blockSize, by = y >> blockSize;
int iBlock = by*bw+bx;
int[] block = fullBlocks[iBlock];
if (block != null)
ret block[x & (blockSize-1) | ((y & blockSize-1) << blockShift)];
ret simpleBlocks[iBlock];
}
public void set(int x, int y, Int a) {
int bx = x >> blockSize, by = y >> blockSize;
int iBlock = by*bw+bx;
int[] block = fullBlocks[iBlock];
if (block == null) {
int val = simpleBlocks[iBlock];
if (val == a) ret; // no change
// convert to full block
block = new int[1 << (blockShift*2)];
fullBlocks[iBlock] = block;
fillArray(block, val);
simpleBlocks[iBlock] = 0; // set irrelevant array entry to 0 for beauty reasons
}
block[x & (blockSize-1) | ((y & blockSize-1) << blockShift)] = a;
}
}