package com.tesora.dve.db.mysql.libmy;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import com.tesora.dve.exceptions.PEException;
public class MyNullBitmap {
public enum BitmapType {RESULT_ROW, EXECUTE_REQUEST}
private byte[] bitmap;
private int numFields;
private BitmapType bitmapType;
public MyNullBitmap(int numFields, BitmapType bitmapType) {
this.bitmapType = bitmapType;
this.numFields = numFields;
init();
}
public MyNullBitmap (byte[] bitmap, int numFields, BitmapType bitmapType) {
this.bitmap = bitmap;
this.bitmapType = bitmapType;
this.numFields = numFields;
}
private void init() {
int bitmapBytes = computeSize(numFields, bitmapType);
bitmap = new byte[bitmapBytes];
// init to zeroes
for (int i = 0; i < bitmap.length; i++) {
bitmap[i] = 0;
}
}
public byte[] getBitmap() {
return bitmap;
}
public static int computeSize(int numFields, BitmapType bitmapType2) {
return (numFields + 7 + getOffset(bitmapType2)) / 8;
}
public void setBit(int position) throws IllegalArgumentException {
if ( position > numFields )
throw new IllegalArgumentException("Cannot set value at position " + position + " for Null Bitmap containing only " + numFields + " elements");
int positionIndex = position - 1;
int offset = getOffset(bitmapType);
int inByte = ((positionIndex + offset) / 8);
int bitPos = (positionIndex + offset) % 8;
bitmap[inByte] |= 1 << bitPos;
}
public boolean getBit(int position) throws IllegalArgumentException {
if ( position > numFields )
throw new IllegalArgumentException("Cannot return value at position " + position + " from Null Bitmap containing only " + numFields + " elements");
int positionIndex = position - 1;
int offset = getOffset(bitmapType);
int inByte = ((positionIndex + offset) / 8);
int bitPos = (positionIndex + offset) % 8;
int mask = 1 << bitPos;
return (( bitmap[inByte] & mask ) == mask);
}
public byte[] getBitmapArray() {
return bitmap;
}
public int size() {
return numFields;
}
public int length() {
return bitmap.length;
}
private static int getOffset(BitmapType bitmapType2) {
int offset = 0;
switch (bitmapType2) {
case EXECUTE_REQUEST:
offset = 0;
break;
case RESULT_ROW:
offset = 2;
break;
default :
break;
}
return offset;
}
public MyNullBitmap flipType() throws PEException {
MyNullBitmap newBitmap =
new MyNullBitmap(size(),
(bitmapType == BitmapType.RESULT_ROW) ? BitmapType.EXECUTE_REQUEST : BitmapType.RESULT_ROW);
if (bitmapType == BitmapType.EXECUTE_REQUEST){
int oldByteIndex = 0;
for (int iNewBitmap = 0; iNewBitmap < newBitmap.length(); ++iNewBitmap) {
byte newByte = 0;
if (oldByteIndex < bitmap.length)
newByte |= (byte) (bitmap[oldByteIndex] << 2);
if (oldByteIndex > 0)
newByte |= (bitmap[oldByteIndex-1] >> 6 & 0x03);
++oldByteIndex;
newBitmap.bitmap[iNewBitmap] = newByte;
}
} else {
int oldByteIndex = 0;
for (int iNewBitmap = 0; iNewBitmap < newBitmap.length(); ++iNewBitmap) {
byte oldByte = bitmap[oldByteIndex++];
byte newByte = (byte) ((int)oldByte >> 2 & 0x3f);
if (oldByteIndex < bitmap.length)
newByte |= bitmap[oldByteIndex] << 6;
newBitmap.bitmap[iNewBitmap] = newByte;
}
}
return newBitmap;
}
}