blob: 3cdb6ebc1cda6e403e9b03d63fb2ed8373a70428 [file] [log] [blame]
package org.apache.iotdb.tsfile.encoding.decoder;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import java.io.IOException;
import java.nio.ByteBuffer;
public class DoubleBUFFDecoder extends Decoder {
private boolean readMeta;
private long minValue;
private int countA, countB, n;
private byte buffer = 0;
private int bitsLeft = 0;
public DoubleBUFFDecoder() {
super(TSEncoding.BUFF);
reset();
}
@Override
public boolean hasNext(ByteBuffer in) throws IOException {
if (!readMeta) readMeta(in);
return n > 0;
}
@Override
public double readDouble(ByteBuffer in) {
if (!readMeta) readMeta(in);
long partA = readBits(in, countA);
double partB = 0, base = 1;
for (int i = 0; i < countB; i++) {
base /= 2;
if (readBit(in)) partB += base;
}
n--;
return minValue + partA + partB;
}
@Override
public void reset() {
readMeta = false;
buffer = 0;
bitsLeft = 0;
}
private void readMeta(ByteBuffer in) {
n = (int) readBits(in, Integer.SIZE);
if (n > 0) {
countA = (int) readBits(in, Integer.SIZE);
countB = (int) readBits(in, Integer.SIZE);
minValue = (int) readBits(in, Long.SIZE);
}
readMeta = true;
}
protected long readBits(ByteBuffer in, int len) {
long result = 0;
for (int i = 0; i < len; i++) {
result <<= 1;
if (readBit(in)) result |= 1;
}
return result;
}
/**
* Reads the next bit and returns a boolean representing it.
*
* @return true if the next bit is 1, otherwise 0.
*/
protected boolean readBit(ByteBuffer in) {
flipByte(in);
boolean bit = ((buffer >> (bitsLeft - 1)) & 1) == 1;
bitsLeft--;
return bit;
}
protected void flipByte(ByteBuffer in) {
if (bitsLeft == 0) {
buffer = in.get();
bitsLeft = Byte.SIZE;
}
}
}