This is an automated email from the ASF dual-hosted git repository.
hxd pushed a commit to branch research/encoding-exp
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/research/encoding-exp by this
push:
new f4aacbb Add encoding algorithms: RLBE, RAKE and SPRINTZ (#5011)
f4aacbb is described below
commit f4aacbbbe29af107448e005eea5ebabe1281e9ab
Author: huangyuxiang03 <[email protected]>
AuthorDate: Fri Feb 4 12:17:57 2022 +0800
Add encoding algorithms: RLBE, RAKE and SPRINTZ (#5011)
---
.../org/apache/iotdb/db/qp/sql/IoTDBSqlLexer.g4 | 13 +-
.../iotdb/flink/tsfile/util/TSFileConfigUtil.java | 1 +
.../org/apache/iotdb/db/utils/SchemaUtils.java | 6 +
.../iotdb/tsfile/common/conf/TSFileConfig.java | 10 +
.../iotdb/tsfile/encoding/decoder/Decoder.java | 39 +++
.../tsfile/encoding/decoder/DoubleRAKEDecoder.java | 40 +++
.../tsfile/encoding/decoder/DoubleRLBEDecoder.java | 197 +++++++++++++++
.../encoding/decoder/DoubleSprintzDecoder.java | 139 +++++++++++
.../tsfile/encoding/decoder/FloatRAKEDecoder.java | 40 +++
.../tsfile/encoding/decoder/FloatRLBEDecoder.java | 197 +++++++++++++++
.../encoding/decoder/FloatSprintzDecoder.java | 140 +++++++++++
.../tsfile/encoding/decoder/IntRAKEDecoder.java | 42 ++++
.../tsfile/encoding/decoder/IntRLBEDecoder.java | 196 +++++++++++++++
.../tsfile/encoding/decoder/IntSprintzDecoder.java | 129 ++++++++++
.../tsfile/encoding/decoder/LongRAKEDecoder.java | 42 ++++
.../tsfile/encoding/decoder/LongRLBEDecoder.java | 196 +++++++++++++++
.../encoding/decoder/LongSprintzDecoder.java | 127 ++++++++++
.../iotdb/tsfile/encoding/decoder/RAKEDecoder.java | 205 ++++++++++++++++
.../tsfile/encoding/decoder/SprintzDecoder.java | 54 ++++
.../tsfile/encoding/encoder/DoubleRAKEEncoder.java | 42 ++++
.../iotdb/tsfile/encoding/encoder/DoubleRLBE.java | 272 ++++++++++++++++++++
.../encoding/encoder/DoubleSprintzEncoder.java | 160 ++++++++++++
.../tsfile/encoding/encoder/FloatRAKEEncoder.java | 42 ++++
.../iotdb/tsfile/encoding/encoder/FloatRLBE.java | 273 +++++++++++++++++++++
.../encoding/encoder/FloatSprintzEncoder.java | 159 ++++++++++++
.../tsfile/encoding/encoder/IntRAKEEncoder.java | 42 ++++
.../iotdb/tsfile/encoding/encoder/IntRLBE.java | 257 +++++++++++++++++++
.../tsfile/encoding/encoder/IntSprintzEncoder.java | 158 ++++++++++++
.../tsfile/encoding/encoder/LongRAKEEncoder.java | 42 ++++
.../iotdb/tsfile/encoding/encoder/LongRLBE.java | 257 +++++++++++++++++++
.../encoding/encoder/LongSprintzEncoder.java | 159 ++++++++++++
.../iotdb/tsfile/encoding/encoder/RAKEEncoder.java | 166 +++++++++++++
.../apache/iotdb/tsfile/encoding/encoder/RLBE.java | 61 +++++
.../tsfile/encoding/encoder/SprintzEncoder.java | 72 ++++++
.../tsfile/encoding/encoder/TSEncodingBuilder.java | 76 ++++++
.../apache/iotdb/tsfile/encoding/fire/Fire.java | 56 +++++
.../apache/iotdb/tsfile/encoding/fire/IntFire.java | 52 ++++
.../iotdb/tsfile/encoding/fire/LongFire.java | 48 ++++
.../tsfile/file/metadata/enums/TSEncoding.java | 11 +-
.../tsfile/utils/ReadWriteForEncodingUtils.java | 18 ++
40 files changed, 4234 insertions(+), 2 deletions(-)
diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlLexer.g4
b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlLexer.g4
index 024cf78..32c0b68 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlLexer.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlLexer.g4
@@ -633,7 +633,7 @@ TEXT
// Encoding Type Keywords
ENCODING_VALUE
- : DICTIONARY | DIFF | GORILLA | PLAIN | REGULAR | RLE | TS_2DIFF
+ : DICTIONARY | DIFF | GORILLA | PLAIN | REGULAR | RLE | TS_2DIFF | RLBE |
RAKE | SPRINTZ
;
DICTIONARY
@@ -664,6 +664,17 @@ TS_2DIFF
: T S '_' '2' D I F F
;
+RLBE
+ : R L B E
+ ;
+
+RAKE
+ : R A K E
+ ;
+
+SPRINTZ
+ : S P R I N T Z
+ ;
// Compressor Type Keywords
diff --git
a/flink-tsfile-connector/src/main/java/org/apache/iotdb/flink/tsfile/util/TSFileConfigUtil.java
b/flink-tsfile-connector/src/main/java/org/apache/iotdb/flink/tsfile/util/TSFileConfigUtil.java
index 44862a3..336ca19 100644
---
a/flink-tsfile-connector/src/main/java/org/apache/iotdb/flink/tsfile/util/TSFileConfigUtil.java
+++
b/flink-tsfile-connector/src/main/java/org/apache/iotdb/flink/tsfile/util/TSFileConfigUtil.java
@@ -60,5 +60,6 @@ public class TSFileConfigUtil {
globalConfig.setTSFileStorageFs(config.getTSFileStorageFs());
globalConfig.setUseKerberos(config.isUseKerberos());
globalConfig.setValueEncoder(config.getValueEncoder());
+ globalConfig.setSprintzPredictScheme(config.getSprintzPredictScheme());
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
b/server/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
index 4fe4f64..c953e2d 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
@@ -68,6 +68,9 @@ public class SchemaUtils {
intSet.add(TSEncoding.RLE);
intSet.add(TSEncoding.TS_2DIFF);
intSet.add(TSEncoding.GORILLA);
+ intSet.add(TSEncoding.SPRINTZ);
+ intSet.add(TSEncoding.RLBE);
+ intSet.add(TSEncoding.RAKE);
schemaChecker.put(TSDataType.INT32, intSet);
schemaChecker.put(TSDataType.INT64, intSet);
@@ -77,6 +80,9 @@ public class SchemaUtils {
floatSet.add(TSEncoding.TS_2DIFF);
floatSet.add(TSEncoding.GORILLA_V1);
floatSet.add(TSEncoding.GORILLA);
+ floatSet.add(TSEncoding.RAKE);
+ floatSet.add(TSEncoding.RLBE);
+ floatSet.add(TSEncoding.SPRINTZ);
schemaChecker.put(TSDataType.FLOAT, floatSet);
schemaChecker.put(TSDataType.DOUBLE, floatSet);
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/common/conf/TSFileConfig.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/common/conf/TSFileConfig.java
index d13f817..3365d9d 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/common/conf/TSFileConfig.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/common/conf/TSFileConfig.java
@@ -99,6 +99,8 @@ public class TSFileConfig implements Serializable {
private int rleBitWidth = 8;
/** Default block size of two-diff. delta encoding is 128 */
private int deltaBlockSize = 128;
+ /** Default predict method for Sprintz encoding scheme * */
+ private String sprintzPredictScheme = "delta";
/** Default frequency type is SINGLE_FREQ. */
private String freqType = "SINGLE_FREQ";
/** Default PLA max error is 100. */
@@ -244,6 +246,14 @@ public class TSFileConfig implements Serializable {
this.deltaBlockSize = deltaBlockSize;
}
+ public String getSprintzPredictScheme() {
+ return sprintzPredictScheme;
+ }
+
+ public void setSprintzPredictScheme(String scheme) {
+ this.sprintzPredictScheme = scheme;
+ }
+
public String getFreqType() {
return freqType;
}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/Decoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/Decoder.java
index 37c5ebe..e14c1bb 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/Decoder.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/Decoder.java
@@ -112,6 +112,45 @@ public abstract class Decoder {
}
case DICTIONARY:
return new DictionaryDecoder();
+ case SPRINTZ:
+ switch (dataType) {
+ case INT32:
+ return new IntSprintzDecoder();
+ case INT64:
+ return new LongSprintzDecoder();
+ case FLOAT:
+ return new FloatSprintzDecoder();
+ case DOUBLE:
+ return new DoubleSprintzDecoder();
+ default:
+ throw new TsFileDecodingException(String.format(ERROR_MSG,
encoding, dataType));
+ }
+ case RLBE:
+ switch (dataType) {
+ case INT32:
+ return new IntRLBEDecoder();
+ case INT64:
+ return new LongRLBEDecoder();
+ case FLOAT:
+ return new FloatRLBEDecoder();
+ case DOUBLE:
+ return new DoubleRLBEDecoder();
+ default:
+ throw new TsFileDecodingException(String.format(ERROR_MSG,
encoding, dataType));
+ }
+ case RAKE:
+ switch (dataType) {
+ case INT32:
+ return new IntRAKEDecoder();
+ case INT64:
+ return new LongRAKEDecoder();
+ case FLOAT:
+ return new FloatRAKEDecoder();
+ case DOUBLE:
+ return new DoubleRAKEDecoder();
+ default:
+ throw new TsFileDecodingException(String.format(ERROR_MSG,
encoding, dataType));
+ }
default:
throw new TsFileDecodingException(String.format(ERROR_MSG, encoding,
dataType));
}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DoubleRAKEDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DoubleRAKEDecoder.java
new file mode 100644
index 0000000..3194b18
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DoubleRAKEDecoder.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import java.nio.ByteBuffer;
+
+public class DoubleRAKEDecoder extends RAKEDecoder {
+ @Override
+ public double readDouble(ByteBuffer buffer) {
+ parseBuffer(buffer, 64);
+ String subNumBuffer = numBuffer.substring(0, 64);
+ this.numBuffer = "";
+ if (subNumBuffer.charAt(0) == '0')
+ return Double.longBitsToDouble(Long.parseUnsignedLong(subNumBuffer, 2));
+ else {
+ String tmpSubNumBuffer = "0";
+ for (int i = 1; i < subNumBuffer.length(); i++) {
+ tmpSubNumBuffer += subNumBuffer.charAt(i);
+ }
+ return -Double.longBitsToDouble(Long.parseUnsignedLong(tmpSubNumBuffer,
2));
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DoubleRLBEDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DoubleRLBEDecoder.java
new file mode 100644
index 0000000..5068457
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DoubleRLBEDecoder.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+
+import java.nio.ByteBuffer;
+
+public class DoubleRLBEDecoder extends Decoder {
+ /** constructor of DoubleRLBEDecoder */
+ public DoubleRLBEDecoder() {
+ super(TSEncoding.RLBE);
+ numberLeftInBuffer = 0;
+ byteBuffer = 0;
+ }
+
+ /** how many numbers expected to decode in following block */
+ private int blocksize;
+
+ /** origin values are stored in data */
+ private double[] data;
+
+ /** whether the first value is decoded */
+ private int writeindex = -1;
+
+ /** the pointer of current last value */
+ private int readindex = -1;
+
+ /** fibonacci values are stored in fibonacci */
+ private long[] fibonacci;
+
+ /** read bits from input stream to byteBuffer and get bit from byteBuffer */
+ private byte byteBuffer;
+
+ /** valid bits in byteBuffer */
+ private int numberLeftInBuffer;
+
+ /**
+ * read the header of a block, determine the size of block and malloc space
values
+ *
+ * @param buffer inputstream buffer
+ */
+ private void readhead(ByteBuffer buffer) {
+ for (int i = 0; i <= writeindex; i++) {
+ data[i] = 0;
+ }
+ writeindex = -1;
+ readindex = -1;
+ clearBuffer(buffer);
+ readblocksize(buffer);
+ data = new double[blocksize * 2 + 1];
+ fibonacci = new long[blocksize * 2 + 1];
+ for (int i = 0; i < blocksize * 2; i++) {
+ data[i] = 0;
+ fibonacci[i] = 0;
+ }
+ fibonacci[0] = 1;
+ fibonacci[1] = 1;
+ }
+
+ /**
+ * read a block from inputstream buffer
+ *
+ * @param buffer inputstream buffer
+ */
+ private void readT(ByteBuffer buffer) {
+ // read the header of the block
+ readhead(buffer);
+ while (writeindex < blocksize - 1) {
+ int seglength = 0, runlength = 0;
+ // read first 7 bits: length of each binary words.
+ for (int j = 6; j >= 0; j--) {
+ seglength |= (readbit(buffer) << j);
+ }
+
+ // generate repeat time of rle on delta
+ int now = readbit(buffer);
+ int next = readbit(buffer);
+
+ int j = 1;
+ while (true) {
+ if (j > 1) fibonacci[j] = fibonacci[j - 1] + fibonacci[j - 2];
+ if (now == 1) runlength += fibonacci[j];
+ // when now and next are both 1, the 1 of next is the symbol of ending
of fibonacci code
+ if (now == 1 && next == 1) break;
+ j++;
+ now = next;
+ next = readbit(buffer);
+ }
+ // read the delta value one by one
+ for (int i = 1; i <= runlength; i++) {
+
+ long readlongtemp = 0;
+ for (int k = seglength - 1; k >= 0; k--) {
+ readlongtemp += ((long) readbit(buffer) << k);
+ }
+ if (seglength == 64) readlongtemp -= ((long) 1 << 63);
+ double readdoubletemp = Double.longBitsToDouble(readlongtemp);
+ if (writeindex == -1) {
+ data[++writeindex] = readdoubletemp;
+ } else {
+ ++writeindex;
+ data[writeindex] = data[writeindex - 1] + readdoubletemp;
+ }
+ }
+ }
+ }
+
+ @Override
+ public double readDouble(ByteBuffer buffer) {
+ if (readindex < writeindex) {
+ return data[++readindex];
+ } else {
+ readT(buffer);
+ return data[++readindex];
+ }
+ }
+
+ @Override
+ public boolean hasNext(ByteBuffer buffer) {
+ return (buffer.remaining() > 0 || readindex < writeindex);
+ }
+
+ @Override
+ public void reset() {
+ // do nothing
+ }
+
+ /**
+ * get a bit from byteBuffer, when there is no bit in byteBuffer, get new 8
bits from inputstream
+ * buffer
+ *
+ * @param buffer inputstream buffer
+ * @return the top bit of byteBuffer
+ */
+ private int readbit(ByteBuffer buffer) {
+ if (numberLeftInBuffer == 0) {
+ loadBuffer(buffer);
+ numberLeftInBuffer = 8;
+ }
+ int top = ((byteBuffer >> 7) & 1);
+ byteBuffer <<= 1;
+ numberLeftInBuffer--;
+ return top;
+ }
+
+ /**
+ * get 8 bits from inputstream buffer to byteBuffer
+ *
+ * @param buffer inputstream buffer
+ */
+ private void loadBuffer(ByteBuffer buffer) {
+ byteBuffer = buffer.get();
+ }
+
+ /**
+ * clear all remaining bits in byteBuffer
+ *
+ * @param buffer inputstream buffer
+ */
+ private void clearBuffer(ByteBuffer buffer) {
+ while (numberLeftInBuffer > 0) {
+ readbit(buffer);
+ }
+ }
+
+ /**
+ * read the first integer of the block: blocksize
+ *
+ * @param buffer inputstream buffer
+ */
+ private void readblocksize(ByteBuffer buffer) {
+ blocksize = 0;
+ for (int i = 31; i >= 0; i--) {
+ if (readbit(buffer) == 1) {
+ blocksize |= (1 << i);
+ }
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DoubleSprintzDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DoubleSprintzDecoder.java
new file mode 100644
index 0000000..6419deb
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DoubleSprintzDecoder.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
+import org.apache.iotdb.tsfile.encoding.bitpacking.LongPacker;
+import org.apache.iotdb.tsfile.encoding.fire.LongFire;
+import org.apache.iotdb.tsfile.utils.ReadWriteForEncodingUtils;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+public class DoubleSprintzDecoder extends SprintzDecoder {
+ LongPacker packer;
+ LongFire firePred;
+ private double preValue;
+ private final double[] currentBuffer;
+ private final long[] convertBuffer;
+ private double currentValue;
+ private final String predictScheme =
+ TSFileDescriptor.getInstance().getConfig().getSprintzPredictScheme();
+
+ public DoubleSprintzDecoder() {
+ super();
+ currentBuffer = new double[Block_size + 1];
+ convertBuffer = new long[Block_size];
+ firePred = new LongFire(3);
+ reset();
+ }
+
+ @Override
+ public boolean hasNext(ByteBuffer buffer) throws IOException {
+ // int minLenth = Long.BYTES + 1;
+ return (isBlockReaded && currentCount < Block_size) || buffer.remaining()
> 0;
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ preValue = 0;
+ currentValue = 0;
+ currentCount = 0;
+ Arrays.fill(currentBuffer, 0);
+ Arrays.fill(convertBuffer, 0);
+ }
+
+ @Override
+ protected void decodeBlock(ByteBuffer in) throws IOException {
+ bitWidth =
ReadWriteForEncodingUtils.readIntLittleEndianPaddedOnBitWidth(in, 1);
+ if ((bitWidth & (1 << 7)) != 0) {
+ decodeSize = bitWidth & ~(1 << 7);
+ DoublePrecisionDecoderV2 decoder = new DoublePrecisionDecoderV2();
+ for (int i = 0; i < decodeSize; i++) {
+ currentBuffer[i] = decoder.readDouble(in);
+ }
+ } else {
+ decodeSize = Block_size + 1;
+ preValue = in.getDouble();
+ currentBuffer[0] = preValue;
+ long[] tmpBuffer = new long[8];
+ packer = new LongPacker(bitWidth);
+ byte[] packcle = new byte[bitWidth];
+ for (int i = 0; i < bitWidth; i++) {
+ packcle[i] = in.get();
+ }
+ packer.unpack8Values(packcle, 0, tmpBuffer);
+ for (int i = 0; i < 8; i++) convertBuffer[i] = tmpBuffer[i];
+ recalculate();
+ }
+ isBlockReaded = true;
+ }
+
+ @Override
+ protected void recalculate() {
+ for (int i = 0; i < Block_size; i++) {
+ if (convertBuffer[i] % 2 == 0) convertBuffer[i] = -convertBuffer[i] / 2;
+ else convertBuffer[i] = (convertBuffer[i] + 1) / 2;
+ }
+ if (predictScheme.equals("delta")) {
+ convertBuffer[0] = convertBuffer[0] + Double.doubleToLongBits(preValue);
+ currentBuffer[1] = Double.longBitsToDouble(convertBuffer[0]);
+ for (int i = 1; i < Block_size; i++) {
+ convertBuffer[i] += convertBuffer[i - 1];
+ currentBuffer[i + 1] = Double.longBitsToDouble(convertBuffer[i]);
+ }
+ } else if (predictScheme.equals("fire")) {
+ firePred.reset();
+ long p = firePred.predict(Double.doubleToLongBits(preValue));
+ long e = convertBuffer[0];
+ convertBuffer[0] += p;
+ currentBuffer[1] = Double.longBitsToDouble(convertBuffer[0]);
+ firePred.train(Double.doubleToLongBits(preValue), convertBuffer[0], e);
+ for (int i = 1; i < Block_size; i++) {
+ long pred = firePred.predict(convertBuffer[i - 1]);
+ long err = convertBuffer[i];
+ convertBuffer[i] += pred;
+ currentBuffer[i + 1] = Double.longBitsToDouble(convertBuffer[i]);
+ firePred.train(convertBuffer[i - 1], convertBuffer[i], err);
+ }
+ } else {
+ throw new UnsupportedOperationException("Sprintz predictive method {} is
not supported.");
+ }
+ }
+
+ @Override
+ public double readDouble(ByteBuffer buffer) {
+ if (!isBlockReaded) {
+ try {
+ decodeBlock(buffer);
+ } catch (IOException e) {
+ logger.error("Error occured when readInt with Sprintz Decoder.", e);
+ }
+ }
+ currentValue = currentBuffer[currentCount++];
+ if (currentCount == decodeSize) {
+ isBlockReaded = false;
+ currentCount = 0;
+ }
+ return currentValue;
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/FloatRAKEDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/FloatRAKEDecoder.java
new file mode 100644
index 0000000..95acd37
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/FloatRAKEDecoder.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import java.nio.ByteBuffer;
+
+public class FloatRAKEDecoder extends RAKEDecoder {
+ @Override
+ public float readFloat(ByteBuffer buffer) {
+ parseBuffer(buffer, 32);
+ String subNumBuffer = numBuffer.substring(0, 32);
+ this.numBuffer = "";
+ if (subNumBuffer.charAt(0) == '0')
+ return Float.intBitsToFloat(Integer.parseUnsignedInt(subNumBuffer, 2));
+ else {
+ String tmpSubNumBuffer = "0";
+ for (int i = 1; i < subNumBuffer.length(); i++) {
+ tmpSubNumBuffer += subNumBuffer.charAt(i);
+ }
+ return -Float.intBitsToFloat(Integer.parseUnsignedInt(tmpSubNumBuffer,
2));
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/FloatRLBEDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/FloatRLBEDecoder.java
new file mode 100644
index 0000000..5726897
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/FloatRLBEDecoder.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+
+import java.nio.ByteBuffer;
+
+public class FloatRLBEDecoder extends Decoder {
+ /** constructor of FloatRLBEDecoder */
+ public FloatRLBEDecoder() {
+ super(TSEncoding.RLBE);
+ numberLeftInBuffer = 0;
+ byteBuffer = 0;
+ }
+
+ /** how many numbers expected to decode in following block */
+ private int blocksize;
+
+ /** origin values are stored in data */
+ private float[] data;
+
+ /** whether the first value is decoded */
+ private int writeindex = -1;
+
+ /** the pointer of current last value */
+ private int readindex = -1;
+
+ /** fibonacci values are stored in fibonacci */
+ private int[] fibonacci;
+
+ /** read bits from input stream to byteBuffer and get bit from byteBuffer */
+ private byte byteBuffer;
+
+ /** valid bits in byteBuffer */
+ private int numberLeftInBuffer;
+
+ /**
+ * read the header of a block, determine the size of block and malloc space
values
+ *
+ * @param buffer inputstream buffer
+ */
+ private void readhead(ByteBuffer buffer) {
+ for (int i = 0; i <= writeindex; i++) {
+ data[i] = 0;
+ }
+ writeindex = -1;
+ readindex = -1;
+ clearBuffer(buffer);
+ readblocksize(buffer);
+ data = new float[blocksize * 2 + 1];
+ fibonacci = new int[blocksize * 2 + 1];
+ for (int i = 0; i < blocksize * 2; i++) {
+ data[i] = 0;
+ fibonacci[i] = 0;
+ }
+ fibonacci[0] = 1;
+ fibonacci[1] = 1;
+ }
+
+ /**
+ * read a block from inputstream buffer
+ *
+ * @param buffer inputstream buffer
+ */
+ private void readT(ByteBuffer buffer) {
+ // read the header of the block
+ readhead(buffer);
+ while (writeindex < blocksize - 1) {
+ int seglength = 0, runlength = 0;
+ // read first 6 bits: length of each binary words.
+ for (int j = 5; j >= 0; j--) {
+ seglength |= (readbit(buffer) << j);
+ }
+
+ // generate repeat time of rle on delta
+ int now = readbit(buffer);
+ int next = readbit(buffer);
+
+ int j = 1;
+ while (true) {
+ if (j > 1) fibonacci[j] = fibonacci[j - 1] + fibonacci[j - 2];
+ if (now == 1) runlength += fibonacci[j];
+ // when now and next are both 1, the 1 of next is the symbol of ending
of fibonacci code
+ if (now == 1 && next == 1) break;
+ j++;
+ now = next;
+ next = readbit(buffer);
+ }
+ // read the delta value one by one
+ for (int i = 1; i <= runlength; i++) {
+
+ int readinttemp = 0;
+ for (int k = seglength - 1; k >= 0; k--) {
+ readinttemp += (readbit(buffer) << k);
+ }
+ if (seglength == 32) readinttemp -= (1 << 31);
+ float readfloattemp = Float.intBitsToFloat(readinttemp);
+ if (writeindex == -1) {
+ data[++writeindex] = readfloattemp;
+ } else {
+ ++writeindex;
+ data[writeindex] = data[writeindex - 1] + readfloattemp;
+ }
+ }
+ }
+ }
+
+ @Override
+ public float readFloat(ByteBuffer buffer) {
+ if (readindex < writeindex) {
+ return data[++readindex];
+ } else {
+ readT(buffer);
+ return data[++readindex];
+ }
+ }
+
+ @Override
+ public boolean hasNext(ByteBuffer buffer) {
+ return (buffer.remaining() > 0 || readindex < writeindex);
+ }
+
+ @Override
+ public void reset() {
+ // do nothing
+ }
+
+ /**
+ * get a bit from byteBuffer, when there is no bit in byteBuffer, get new 8
bits from inputstream
+ * buffer
+ *
+ * @param buffer inputstream buffer
+ * @return the top bit of byteBuffer
+ */
+ private int readbit(ByteBuffer buffer) {
+ if (numberLeftInBuffer == 0) {
+ loadBuffer(buffer);
+ numberLeftInBuffer = 8;
+ }
+ int top = ((byteBuffer >> 7) & 1);
+ byteBuffer <<= 1;
+ numberLeftInBuffer--;
+ return top;
+ }
+
+ /**
+ * get 8 bits from inputstream buffer to byteBuffer
+ *
+ * @param buffer inputstream buffer
+ */
+ private void loadBuffer(ByteBuffer buffer) {
+ byteBuffer = buffer.get();
+ }
+
+ /**
+ * clear all remaining bits in byteBuffer
+ *
+ * @param buffer inputstream buffer
+ */
+ private void clearBuffer(ByteBuffer buffer) {
+ while (numberLeftInBuffer > 0) {
+ readbit(buffer);
+ }
+ }
+
+ /**
+ * read the first integer of the block: blocksize
+ *
+ * @param buffer inputstream buffer
+ */
+ private void readblocksize(ByteBuffer buffer) {
+ blocksize = 0;
+ for (int i = 31; i >= 0; i--) {
+ if (readbit(buffer) == 1) {
+ blocksize |= (1 << i);
+ }
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/FloatSprintzDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/FloatSprintzDecoder.java
new file mode 100644
index 0000000..40f523e
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/FloatSprintzDecoder.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
+import org.apache.iotdb.tsfile.encoding.bitpacking.IntPacker;
+import org.apache.iotdb.tsfile.encoding.fire.IntFire;
+import org.apache.iotdb.tsfile.utils.ReadWriteForEncodingUtils;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+public class FloatSprintzDecoder extends SprintzDecoder {
+
+ IntPacker packer;
+ IntFire firePred;
+ private float preValue;
+ private final float[] currentBuffer;
+ private final int[] convertBuffer;
+ private float currentValue;
+ private final String predictScheme =
+ TSFileDescriptor.getInstance().getConfig().getSprintzPredictScheme();
+
+ public FloatSprintzDecoder() {
+ super();
+ currentBuffer = new float[Block_size + 1];
+ convertBuffer = new int[Block_size];
+ firePred = new IntFire(2);
+ reset();
+ }
+
+ @Override
+ public boolean hasNext(ByteBuffer buffer) throws IOException {
+ int minLenth = Float.BYTES + 1;
+ return (isBlockReaded && currentCount < Block_size) || buffer.remaining()
>= minLenth;
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ currentValue = 0;
+ preValue = 0;
+ currentCount = 0;
+ Arrays.fill(currentBuffer, 0);
+ Arrays.fill(convertBuffer, 0);
+ }
+
+ @Override
+ protected void decodeBlock(ByteBuffer in) throws IOException {
+ bitWidth =
ReadWriteForEncodingUtils.readIntLittleEndianPaddedOnBitWidth(in, 1);
+ if ((bitWidth & (1 << 7)) != 0) {
+ decodeSize = bitWidth & ~(1 << 7);
+ SinglePrecisionDecoderV2 decoder = new SinglePrecisionDecoderV2();
+ for (int i = 0; i < decodeSize; i++) {
+ currentBuffer[i] = decoder.readFloat(in);
+ }
+ } else {
+ decodeSize = Block_size + 1;
+ preValue = in.getFloat();
+ currentBuffer[0] = preValue;
+ int[] tmpBuffer = new int[8];
+ packer = new IntPacker(bitWidth);
+ byte[] packcle = new byte[bitWidth];
+ for (int i = 0; i < bitWidth; i++) {
+ packcle[i] = in.get();
+ }
+ packer.unpack8Values(packcle, 0, tmpBuffer);
+ for (int i = 0; i < 8; i++) convertBuffer[i] = tmpBuffer[i];
+ recalculate();
+ }
+ isBlockReaded = true;
+ }
+
+ @Override
+ protected void recalculate() {
+ for (int i = 0; i < Block_size; i++) {
+ if (convertBuffer[i] % 2 == 0) convertBuffer[i] = -convertBuffer[i] / 2;
+ else convertBuffer[i] = (convertBuffer[i] + 1) / 2;
+ }
+ if (predictScheme.equals("delta")) {
+ convertBuffer[0] = convertBuffer[0] + Float.floatToIntBits(preValue);
+ currentBuffer[1] = Float.intBitsToFloat(convertBuffer[0]);
+ for (int i = 1; i < Block_size; i++) {
+ convertBuffer[i] += convertBuffer[i - 1];
+ currentBuffer[i + 1] = Float.intBitsToFloat(convertBuffer[i]);
+ }
+ } else if (predictScheme.equals("fire")) {
+ firePred.reset();
+ int p = firePred.predict(Float.floatToIntBits(preValue));
+ int e = convertBuffer[0];
+ convertBuffer[0] += p;
+ currentBuffer[1] = Float.intBitsToFloat(convertBuffer[0]);
+ firePred.train(Float.floatToIntBits(preValue), convertBuffer[0], e);
+ for (int i = 1; i < Block_size; i++) {
+ int pred = firePred.predict(convertBuffer[i - 1]);
+ int err = convertBuffer[i];
+ convertBuffer[i] += pred;
+ currentBuffer[i + 1] = Float.intBitsToFloat(convertBuffer[i]);
+ firePred.train(convertBuffer[i - 1], convertBuffer[i], err);
+ }
+ } else {
+ throw new UnsupportedOperationException("Sprintz predictive method {} is
not supported.");
+ }
+ }
+
+ @Override
+ public float readFloat(ByteBuffer buffer) {
+ if (!isBlockReaded) {
+ try {
+ decodeBlock(buffer);
+ } catch (IOException e) {
+ logger.error("Error occured when readInt with Sprintz Decoder.", e);
+ }
+ }
+ currentValue = currentBuffer[currentCount++];
+ if (currentCount == decodeSize) {
+ isBlockReaded = false;
+ currentCount = 0;
+ }
+ return currentValue;
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/IntRAKEDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/IntRAKEDecoder.java
new file mode 100644
index 0000000..6abc08b
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/IntRAKEDecoder.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import java.nio.ByteBuffer;
+
+public class IntRAKEDecoder extends RAKEDecoder {
+
+ @Override
+ public int readInt(ByteBuffer buffer) {
+ parseBuffer(buffer, 32);
+ String subNumBuffer = numBuffer.substring(0, 32);
+ this.numBuffer = "";
+ if (subNumBuffer.charAt(0) == '0') return Integer.parseInt(subNumBuffer,
2);
+ else {
+ String tmpSubNumBuffer = "0";
+ for (int i = 1; i < subNumBuffer.length(); i++) {
+ if (subNumBuffer.charAt(i) == '1') tmpSubNumBuffer += "0";
+ else tmpSubNumBuffer += "1";
+ }
+
+ return -Integer.parseInt(tmpSubNumBuffer, 2) - 1;
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/IntRLBEDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/IntRLBEDecoder.java
new file mode 100644
index 0000000..eb4b423
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/IntRLBEDecoder.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+
+import java.nio.ByteBuffer;
+
+public class IntRLBEDecoder extends Decoder {
+ /** constructor of IntRLBEDecoder */
+ public IntRLBEDecoder() {
+ super(TSEncoding.RLBE);
+ numberLeftInBuffer = 0;
+ byteBuffer = 0;
+ }
+
+ /** how many numbers expected to decode in following block */
+ private int blocksize;
+
+ /** origin values are stored in data */
+ private int[] data;
+
+ /** whether the first value is decoded */
+ private int writeindex = -1;
+
+ /** the pointer of current last value */
+ private int readindex = -1;
+
+ /** fibonacci values are stored in fibonacci */
+ private int[] fibonacci;
+
+ /** read bits from input stream to byteBuffer and get bit from byteBuffer */
+ private byte byteBuffer;
+
+ /** valid bits in byteBuffer */
+ private int numberLeftInBuffer;
+
+ /**
+ * read the header of a block, determine the size of block and malloc space
values
+ *
+ * @param buffer inputstream buffer
+ */
+ private void readhead(ByteBuffer buffer) {
+ for (int i = 0; i <= writeindex; i++) {
+ data[i] = 0;
+ }
+ writeindex = -1;
+ readindex = -1;
+ clearBuffer(buffer);
+ readblocksize(buffer);
+ data = new int[blocksize * 2 + 1];
+ fibonacci = new int[blocksize * 2 + 1];
+ for (int i = 0; i < blocksize * 2; i++) {
+ data[i] = 0;
+ fibonacci[i] = 0;
+ }
+ fibonacci[0] = 1;
+ fibonacci[1] = 1;
+ }
+
+ /**
+ * read a block from inputstream buffer
+ *
+ * @param buffer inputstream buffer
+ */
+ private void readT(ByteBuffer buffer) {
+ // read the header of the block
+ readhead(buffer);
+ while (writeindex < blocksize - 1) {
+ int seglength = 0, runlength = 0;
+ // read first 6 bits: length of each binary words.
+ for (int j = 5; j >= 0; j--) {
+ seglength |= (readbit(buffer) << j);
+ }
+
+ // generate repeat time of rle on delta
+ int now = readbit(buffer);
+ int next = readbit(buffer);
+
+ int j = 1;
+ while (true) {
+ if (j > 1) fibonacci[j] = fibonacci[j - 1] + fibonacci[j - 2];
+ if (now == 1) runlength += fibonacci[j];
+ // when now and next are both 1, the 1 of next is the symbol of ending
of fibonacci code
+ if (now == 1 && next == 1) break;
+ j++;
+ now = next;
+ next = readbit(buffer);
+ }
+ // read the delta value one by one
+ for (int i = 1; i <= runlength; i++) {
+
+ int readinttemp = 0;
+ for (int k = seglength - 1; k >= 0; k--) {
+ readinttemp += (readbit(buffer) << k);
+ }
+ if (seglength == 32) readinttemp -= (1 << 31);
+ if (writeindex == -1) {
+ data[++writeindex] = readinttemp;
+ } else {
+ ++writeindex;
+ data[writeindex] = data[writeindex - 1] + readinttemp;
+ }
+ }
+ }
+ }
+
+ @Override
+ public int readInt(ByteBuffer buffer) {
+ if (readindex < writeindex) {
+ return data[++readindex];
+ } else {
+ readT(buffer);
+ return data[++readindex];
+ }
+ }
+
+ @Override
+ public boolean hasNext(ByteBuffer buffer) {
+ return (buffer.remaining() > 0 || readindex < writeindex);
+ }
+
+ @Override
+ public void reset() {
+ // do nothing
+ }
+
+ /**
+ * get a bit from byteBuffer, when there is no bit in byteBuffer, get new 8
bits from inputstream
+ * buffer
+ *
+ * @param buffer inputstream buffer
+ * @return the top bit of byteBuffer
+ */
+ private int readbit(ByteBuffer buffer) {
+ if (numberLeftInBuffer == 0) {
+ loadBuffer(buffer);
+ numberLeftInBuffer = 8;
+ }
+ int top = ((byteBuffer >> 7) & 1);
+ byteBuffer <<= 1;
+ numberLeftInBuffer--;
+ return top;
+ }
+
+ /**
+ * get 8 bits from inputstream buffer to byteBuffer
+ *
+ * @param buffer inputstream buffer
+ */
+ private void loadBuffer(ByteBuffer buffer) {
+ byteBuffer = buffer.get();
+ }
+
+ /**
+ * clear all remaining bits in byteBuffer
+ *
+ * @param buffer inputstream buffer
+ */
+ private void clearBuffer(ByteBuffer buffer) {
+ while (numberLeftInBuffer > 0) {
+ readbit(buffer);
+ }
+ }
+
+ /**
+ * read the first integer of the block: blocksize
+ *
+ * @param buffer inputstream buffer
+ */
+ private void readblocksize(ByteBuffer buffer) {
+ blocksize = 0;
+ for (int i = 31; i >= 0; i--) {
+ if (readbit(buffer) == 1) {
+ blocksize |= (1 << i);
+ }
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/IntSprintzDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/IntSprintzDecoder.java
new file mode 100644
index 0000000..97b8a31
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/IntSprintzDecoder.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
+import org.apache.iotdb.tsfile.encoding.bitpacking.IntPacker;
+import org.apache.iotdb.tsfile.encoding.fire.IntFire;
+import org.apache.iotdb.tsfile.utils.ReadWriteForEncodingUtils;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+public class IntSprintzDecoder extends SprintzDecoder {
+
+ IntPacker packer;
+ IntFire firePred;
+ private int preValue;
+ private final int[] currentBuffer;
+ private int currentValue;
+ private final String predictScheme =
+ TSFileDescriptor.getInstance().getConfig().getSprintzPredictScheme();
+
+ public IntSprintzDecoder() {
+ super();
+ currentBuffer = new int[Block_size + 1];
+ firePred = new IntFire(2);
+ reset();
+ }
+
+ @Override
+ public boolean hasNext(ByteBuffer buffer) throws IOException {
+ int minLenth = Integer.BYTES + 1;
+ return (isBlockReaded && currentCount < Block_size) || buffer.remaining()
>= minLenth;
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ currentValue = 0;
+ preValue = 0;
+ currentCount = 0;
+ Arrays.fill(currentBuffer, 0);
+ }
+
+ @Override
+ protected void decodeBlock(ByteBuffer in) throws IOException {
+ bitWidth =
ReadWriteForEncodingUtils.readIntLittleEndianPaddedOnBitWidth(in, 1);
+ if ((bitWidth & (1 << 7)) != 0) {
+ decodeSize = bitWidth & ~(1 << 7);
+ IntRleDecoder decoder = new IntRleDecoder();
+ for (int i = 0; i < decodeSize; i++) {
+ currentBuffer[i] = decoder.readInt(in);
+ }
+ } else {
+ decodeSize = Block_size + 1;
+ preValue = ReadWriteForEncodingUtils.readUnsignedVarInt(in);
+ currentBuffer[0] = preValue;
+ int[] tmpBuffer = new int[8];
+ packer = new IntPacker(bitWidth);
+ byte[] packcle = new byte[bitWidth];
+ for (int i = 0; i < bitWidth; i++) {
+ packcle[i] = in.get();
+ }
+ packer.unpack8Values(packcle, 0, tmpBuffer);
+ for (int i = 0; i < 8; i++) currentBuffer[i + 1] = tmpBuffer[i];
+ recalculate();
+ }
+ isBlockReaded = true;
+ }
+
+ @Override
+ protected void recalculate() {
+ for (int i = 1; i <= Block_size; i++) {
+ if (currentBuffer[i] % 2 == 0) currentBuffer[i] = -currentBuffer[i] / 2;
+ else currentBuffer[i] = (currentBuffer[i] + 1) / 2;
+ }
+ if (predictScheme.equals("delta")) {
+ for (int i = 1; i < currentBuffer.length; i++) {
+ currentBuffer[i] += currentBuffer[i - 1];
+ }
+ } else if (predictScheme.equals("fire")) {
+ firePred.reset();
+ int pre = currentBuffer[0];
+ for (int i = 1; i <= Block_size; i++) {
+ int pred = firePred.predict(currentBuffer[i - 1]);
+ int err = currentBuffer[i];
+ currentBuffer[i] = pred + err;
+ firePred.train(currentBuffer[i - 1], currentBuffer[i], err);
+ }
+ } else {
+ throw new UnsupportedOperationException("Sprintz predictive method {} is
not supported.");
+ }
+ }
+
+ @Override
+ public int readInt(ByteBuffer buffer) {
+ if (!isBlockReaded) {
+ try {
+ decodeBlock(buffer);
+ } catch (IOException e) {
+ logger.error("Error occured when readInt with Sprintz Decoder.", e);
+ }
+ }
+ currentValue = currentBuffer[currentCount++];
+ if (currentCount == decodeSize) {
+ isBlockReaded = false;
+ currentCount = 0;
+ }
+ return currentValue;
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/LongRAKEDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/LongRAKEDecoder.java
new file mode 100644
index 0000000..10167cf
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/LongRAKEDecoder.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import java.nio.ByteBuffer;
+
+public class LongRAKEDecoder extends RAKEDecoder {
+
+ @Override
+ public long readLong(ByteBuffer buffer) {
+ parseBuffer(buffer, 64);
+ String subNumBuffer = numBuffer.substring(0, 64);
+ this.numBuffer = "";
+ if (subNumBuffer.charAt(0) == '0') return Long.parseLong(subNumBuffer, 2);
+ else {
+ String tmpSubNumBuffer = "0";
+ for (int i = 1; i < subNumBuffer.length(); i++) {
+ if (subNumBuffer.charAt(i) == '1') tmpSubNumBuffer += "0";
+ else tmpSubNumBuffer += "1";
+ }
+
+ return -Long.parseLong(tmpSubNumBuffer, 2) - 1;
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/LongRLBEDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/LongRLBEDecoder.java
new file mode 100644
index 0000000..974ad99
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/LongRLBEDecoder.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+
+import java.nio.ByteBuffer;
+
+public class LongRLBEDecoder extends Decoder {
+ /** constructor of LongRLBEDecoder */
+ public LongRLBEDecoder() {
+ super(TSEncoding.RLBE);
+ numberLeftInBuffer = 0;
+ byteBuffer = 0;
+ }
+
+ /** how many numbers expected to decode in following block */
+ private int blocksize;
+
+ /** origin values are stored in data */
+ private long[] data;
+
+ /** whether the first value is decoded */
+ private int writeindex = -1;
+
+ /** the pointer of current last value */
+ private int readindex = -1;
+
+ /** fibonacci values are stored in fibonacci */
+ private long[] fibonacci;
+
+ /** read bits from input stream to byteBuffer and get bit from byteBuffer */
+ private byte byteBuffer;
+
+ /** valid bits in byteBuffer */
+ private int numberLeftInBuffer;
+
+ /**
+ * read the header of a block, determine the size of block and malloc space
values
+ *
+ * @param buffer inputstream buffer
+ */
+ private void readhead(ByteBuffer buffer) {
+ for (int i = 0; i <= writeindex; i++) {
+ data[i] = 0;
+ }
+ writeindex = -1;
+ readindex = -1;
+ clearBuffer(buffer);
+ readblocksize(buffer);
+ data = new long[blocksize * 2 + 1];
+ fibonacci = new long[blocksize * 2 + 1];
+ for (int i = 0; i < blocksize * 2; i++) {
+ data[i] = 0;
+ fibonacci[i] = 0;
+ }
+ fibonacci[0] = 1;
+ fibonacci[1] = 1;
+ }
+
+ /**
+ * read a block from inputstream buffer
+ *
+ * @param buffer inputstream buffer
+ */
+ private void readT(ByteBuffer buffer) {
+ // read the header of the block
+ readhead(buffer);
+ while (writeindex < blocksize - 1) {
+ int seglength = 0, runlength = 0;
+ // read first 7 bits: length of each binary words.
+ for (int j = 6; j >= 0; j--) {
+ seglength |= (readbit(buffer) << j);
+ }
+
+ // generate repeat time of rle on delta
+ int now = readbit(buffer);
+ int next = readbit(buffer);
+
+ int j = 1;
+ while (true) {
+ if (j > 1) fibonacci[j] = fibonacci[j - 1] + fibonacci[j - 2];
+ if (now == 1) runlength += fibonacci[j];
+ // when now and next are both 1, the 1 of next is the symbol of ending
of fibonacci code
+ if (now == 1 && next == 1) break;
+ j++;
+ now = next;
+ next = readbit(buffer);
+ }
+ // read the delta value one by one
+ for (int i = 1; i <= runlength; i++) {
+
+ long readlongtemp = 0;
+ for (int k = seglength - 1; k >= 0; k--) {
+ readlongtemp += ((long) readbit(buffer) << k);
+ }
+ if (seglength == 64) readlongtemp -= ((long) 1 << 63);
+ if (writeindex == -1) {
+ data[++writeindex] = readlongtemp;
+ } else {
+ ++writeindex;
+ data[writeindex] = data[writeindex - 1] + readlongtemp;
+ }
+ }
+ }
+ }
+
+ @Override
+ public long readLong(ByteBuffer buffer) {
+ if (readindex < writeindex) {
+ return data[++readindex];
+ } else {
+ readT(buffer);
+ return data[++readindex];
+ }
+ }
+
+ @Override
+ public boolean hasNext(ByteBuffer buffer) {
+ return (buffer.remaining() > 0 || readindex < writeindex);
+ }
+
+ @Override
+ public void reset() {
+ // do nothing
+ }
+
+ /**
+ * get a bit from byteBuffer, when there is no bit in byteBuffer, get new 8
bits from inputstream
+ * buffer
+ *
+ * @param buffer inputstream buffer
+ * @return the top bit of byteBuffer
+ */
+ private int readbit(ByteBuffer buffer) {
+ if (numberLeftInBuffer == 0) {
+ loadBuffer(buffer);
+ numberLeftInBuffer = 8;
+ }
+ int top = ((byteBuffer >> 7) & 1);
+ byteBuffer <<= 1;
+ numberLeftInBuffer--;
+ return top;
+ }
+
+ /**
+ * get 8 bits from inputstream buffer to byteBuffer
+ *
+ * @param buffer inputstream buffer
+ */
+ private void loadBuffer(ByteBuffer buffer) {
+ byteBuffer = buffer.get();
+ }
+
+ /**
+ * clear all remaining bits in byteBuffer
+ *
+ * @param buffer inputstream buffer
+ */
+ private void clearBuffer(ByteBuffer buffer) {
+ while (numberLeftInBuffer > 0) {
+ readbit(buffer);
+ }
+ }
+
+ /**
+ * read the first integer of the block: blocksize
+ *
+ * @param buffer inputstream buffer
+ */
+ private void readblocksize(ByteBuffer buffer) {
+ blocksize = 0;
+ for (int i = 31; i >= 0; i--) {
+ if (readbit(buffer) == 1) {
+ blocksize |= (1 << i);
+ }
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/LongSprintzDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/LongSprintzDecoder.java
new file mode 100644
index 0000000..9f0b2ec
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/LongSprintzDecoder.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
+import org.apache.iotdb.tsfile.encoding.bitpacking.LongPacker;
+import org.apache.iotdb.tsfile.encoding.fire.LongFire;
+import org.apache.iotdb.tsfile.utils.ReadWriteForEncodingUtils;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+public class LongSprintzDecoder extends SprintzDecoder {
+ LongPacker packer;
+ LongFire firePred;
+ private long preValue;
+ private final long[] currentBuffer;
+ private long currentValue;
+ private final String predictScheme =
+ TSFileDescriptor.getInstance().getConfig().getSprintzPredictScheme();
+
+ public LongSprintzDecoder() {
+ super();
+ firePred = new LongFire(3);
+ currentBuffer = new long[Block_size + 1];
+ reset();
+ }
+
+ @Override
+ public boolean hasNext(ByteBuffer buffer) throws IOException {
+ // int minLenth = Long.BYTES + 1;
+ return (isBlockReaded && currentCount < Block_size) || buffer.remaining()
> 0;
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ preValue = 0;
+ currentValue = 0;
+ currentCount = 0;
+ Arrays.fill(currentBuffer, 0);
+ }
+
+ @Override
+ protected void decodeBlock(ByteBuffer in) throws IOException {
+ bitWidth =
ReadWriteForEncodingUtils.readIntLittleEndianPaddedOnBitWidth(in, 1);
+ if ((bitWidth & (1 << 7)) != 0) {
+ decodeSize = bitWidth & ~(1 << 7);
+ LongRleDecoder decoder = new LongRleDecoder();
+ for (int i = 0; i < decodeSize; i++) {
+ currentBuffer[i] = decoder.readLong(in);
+ }
+ } else {
+ decodeSize = Block_size + 1;
+ preValue = in.getLong();
+ currentBuffer[0] = preValue;
+ long[] tmpBuffer = new long[8];
+ packer = new LongPacker(bitWidth);
+ byte[] packcle = new byte[bitWidth];
+ for (int i = 0; i < bitWidth; i++) {
+ packcle[i] = in.get();
+ }
+ packer.unpack8Values(packcle, 0, tmpBuffer);
+ for (int i = 0; i < 8; i++) currentBuffer[i + 1] = tmpBuffer[i];
+ recalculate();
+ }
+ isBlockReaded = true;
+ }
+
+ @Override
+ protected void recalculate() {
+ for (int i = 1; i <= Block_size; i++) {
+ if (currentBuffer[i] % 2 == 0) currentBuffer[i] = -currentBuffer[i] / 2;
+ else currentBuffer[i] = (currentBuffer[i] + 1) / 2;
+ }
+ if (predictScheme.equals("delta")) {
+ for (int i = 1; i < currentBuffer.length; i++) {
+ currentBuffer[i] += currentBuffer[i - 1];
+ }
+ } else if (predictScheme.equals("fire")) {
+ firePred.reset();
+ for (int i = 1; i <= Block_size; i++) {
+ long pred = firePred.predict(currentBuffer[i - 1]);
+ long err = currentBuffer[i];
+ currentBuffer[i] = pred + err;
+ firePred.train(currentBuffer[i - 1], currentBuffer[i], err);
+ }
+ } else {
+ throw new UnsupportedOperationException("Sprintz predictive method {} is
not supported.");
+ }
+ }
+
+ @Override
+ public long readLong(ByteBuffer buffer) {
+ if (!isBlockReaded) {
+ try {
+ decodeBlock(buffer);
+ } catch (IOException e) {
+ logger.error("Error occured when readInt with Sprintz Decoder.", e);
+ }
+ }
+ currentValue = currentBuffer[currentCount++];
+ if (currentCount == decodeSize) {
+ isBlockReaded = false;
+ currentCount = 0;
+ }
+ return currentValue;
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/RAKEDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/RAKEDecoder.java
new file mode 100644
index 0000000..a0118ed
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/RAKEDecoder.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.ByteBuffer;
+
+import static java.lang.Math.pow;
+
+public abstract class RAKEDecoder extends Decoder {
+ private static final Logger logger =
LoggerFactory.getLogger(RAKEDecoder.class);
+ protected boolean isReadFinish;
+ // 8-bit buffer of bits to read in
+ protected String rakeBuffer;
+ protected String numBuffer;
+ // decompression data is 8-bit buffer
+ protected int deleteRakeBuffer;
+ // number of bits remaining in buffer
+ protected int numberLeftInBuffer;
+ protected int L;
+ private int T;
+
+ public RAKEDecoder() {
+ super(TSEncoding.RAKE);
+ reset();
+ }
+
+ protected void readBuffer(ByteBuffer buffer) {
+ String str = Integer.toBinaryString(ReadWriteIOUtils.read(buffer));
+ int zeros = 8 - str.length();
+ for (int i = 0; i < zeros; i++) {
+ rakeBuffer += '0';
+ }
+ this.rakeBuffer += str;
+ this.numberLeftInBuffer += 8;
+ if (!hasNext(buffer)) {
+ isReadFinish = true;
+ }
+ }
+
+ protected void parseBuffer(ByteBuffer buffer, int len) {
+ while (!isReadFinish || numBuffer.length() % len != 0) {
+ readBuffer(buffer);
+ int i = 0;
+ while (i + L < this.numberLeftInBuffer) {
+ if (rakeBuffer.charAt(i) == '0') {
+ for (int j = 0; j < T; j++) numBuffer += '0';
+ i++;
+ } else {
+ String sub = rakeBuffer.substring(i + 1, i + L + 1);
+ int bias = Integer.parseInt(sub, 2);
+ for (int j = 0; j < bias; j++) numBuffer += '0';
+ numBuffer += '1';
+ i += (L + 1);
+ }
+ // process the remaining end of long number
+ int lengthNumBuffer = numBuffer.length();
+ if (lengthNumBuffer > len - T && lengthNumBuffer < len) {
+ while (i + len - numBuffer.length() > numberLeftInBuffer) {
+ numBuffer += this.rakeBuffer.substring(i, numberLeftInBuffer);
+ i = numberLeftInBuffer;
+ this.rakeBuffer = this.rakeBuffer.substring(i, numberLeftInBuffer);
+ deleteRakeBuffer += i;
+ numberLeftInBuffer -= i;
+ readBuffer(buffer);
+ i = 0;
+ }
+ lengthNumBuffer = numBuffer.length();
+ numBuffer += this.rakeBuffer.substring(i, i + len -
numBuffer.length());
+ i += len - lengthNumBuffer;
+ }
+ if (numBuffer.length() % len == 0) {
+ this.rakeBuffer = this.rakeBuffer.substring(i, numberLeftInBuffer);
+ numberLeftInBuffer -= i;
+ deleteRakeBuffer += i;
+ i = 0;
+ deleteRakeBuffer %= 8;
+
+ if (deleteRakeBuffer != 0) {
+ if (i + 8 - deleteRakeBuffer > numberLeftInBuffer) {
+ deleteRakeBuffer += numberLeftInBuffer - i;
+ i = numberLeftInBuffer;
+ this.rakeBuffer = this.rakeBuffer.substring(i);
+ numberLeftInBuffer -= i;
+ readBuffer(buffer);
+ i = 0;
+ }
+ i += (8 - deleteRakeBuffer);
+ this.rakeBuffer = this.rakeBuffer.substring(i);
+ deleteRakeBuffer = 0;
+ numberLeftInBuffer -= i;
+ }
+ return;
+ }
+ }
+ this.rakeBuffer = this.rakeBuffer.substring(i, numberLeftInBuffer);
+ deleteRakeBuffer += i;
+ numberLeftInBuffer -= i;
+ }
+ }
+
+ // @Override
+ // public int readInt(ByteBuffer buffer) {
+ // parseBuffer(buffer, 32);
+ // String subNumBuffer = numBuffer.substring(0, 32);
+ // this.numBuffer = "";
+ // if (subNumBuffer.charAt(0) == '0') return
Integer.parseInt(subNumBuffer, 2);
+ // else {
+ // String tmpSubNumBuffer = "0";
+ // for (int i = 1; i < subNumBuffer.length(); i++) {
+ // if (subNumBuffer.charAt(i) == '1') tmpSubNumBuffer += "0";
+ // else tmpSubNumBuffer += "1";
+ // }
+ //
+ // return -Integer.parseInt(tmpSubNumBuffer, 2) - 1;
+ // }
+ // }
+
+ // @Override
+ // public long readLong(ByteBuffer buffer) {
+ // parseBuffer(buffer, 64);
+ // String subNumBuffer = numBuffer.substring(0, 64);
+ // this.numBuffer = "";
+ // if (subNumBuffer.charAt(0) == '0') return Long.parseLong(subNumBuffer,
2);
+ // else {
+ // String tmpSubNumBuffer = "0";
+ // for (int i = 1; i < subNumBuffer.length(); i++) {
+ // if (subNumBuffer.charAt(i) == '1') tmpSubNumBuffer += "0";
+ // else tmpSubNumBuffer += "1";
+ // }
+ //
+ // return -Long.parseLong(tmpSubNumBuffer, 2) - 1;
+ // }
+ // }
+
+ // @Override
+ // public float readFloat(ByteBuffer buffer) {
+ // parseBuffer(buffer, 32);
+ // String subNumBuffer = numBuffer.substring(0, 32);
+ // this.numBuffer = "";
+ // if (subNumBuffer.charAt(0) == '0')
+ // return Float.intBitsToFloat(Integer.parseUnsignedInt(numBuffer, 2));
+ // else {
+ // String tmpSubNumBuffer = "0";
+ // for (int i = 1; i < subNumBuffer.length(); i++) {
+ // tmpSubNumBuffer += subNumBuffer.charAt(i);
+ // }
+ // return
-Float.intBitsToFloat(Integer.parseUnsignedInt(tmpSubNumBuffer, 2));
+ // }
+ // }
+
+ // @Override
+ // public double readDouble(ByteBuffer buffer) {
+ // parseBuffer(buffer, 64);
+ // String subNumBuffer = numBuffer.substring(0, 64);
+ // this.numBuffer = "";
+ // if (subNumBuffer.charAt(0) == '0')
+ // return Double.longBitsToDouble(Long.parseUnsignedLong(numBuffer, 2));
+ // else {
+ // String tmpSubNumBuffer = "0";
+ // for (int i = 1; i < subNumBuffer.length(); i++) {
+ // tmpSubNumBuffer += subNumBuffer.charAt(i);
+ // }
+ // return
-Double.longBitsToDouble(Long.parseUnsignedLong(tmpSubNumBuffer, 2));
+ // }
+ // }
+
+ @Override
+ public boolean hasNext(ByteBuffer buffer) {
+ return buffer.remaining() > 0;
+ }
+
+ @Override
+ public void reset() {
+ this.isReadFinish = false;
+ this.numberLeftInBuffer = 0;
+ this.rakeBuffer = "";
+ this.numBuffer = "";
+ this.L = 2;
+ this.T = (int) pow(2, L);
+ this.deleteRakeBuffer = 0;
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/SprintzDecoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/SprintzDecoder.java
new file mode 100644
index 0000000..0d1debf
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/SprintzDecoder.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.decoder;
+
+import org.apache.iotdb.tsfile.encoding.encoder.SprintzEncoder;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public abstract class SprintzDecoder extends Decoder {
+ protected static final Logger logger =
LoggerFactory.getLogger(SprintzEncoder.class);
+ protected int bitWidth;
+ protected int Block_size = 8;
+ protected boolean isBlockReaded;
+ protected int currentCount;
+ protected int decodeSize;
+
+ public SprintzDecoder() {
+ super(TSEncoding.SPRINTZ);
+ isBlockReaded = false;
+ currentCount = 0;
+ }
+
+ @Override
+ public void reset() {
+ isBlockReaded = false;
+ currentCount = 0;
+ }
+
+ protected abstract void decodeBlock(ByteBuffer in) throws IOException;
+
+ protected abstract void recalculate();
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/DoubleRAKEEncoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/DoubleRAKEEncoder.java
new file mode 100644
index 0000000..0acbe4c
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/DoubleRAKEEncoder.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import java.io.ByteArrayOutputStream;
+
+public class DoubleRAKEEncoder extends RAKEEncoder {
+
+ @Override
+ public void encode(double value, ByteArrayOutputStream out) {
+ isReadFinish = false;
+ String bit_value = Long.toBinaryString(Double.doubleToLongBits(value));
+ encodeNumber(bit_value, 64, out);
+ }
+
+ @Override
+ public int getOneItemMaxSize() {
+ return 1 + (1 + 1) * Double.BYTES;
+ }
+
+ @Override
+ public long getMaxByteSize() {
+ return 1 + (long) (1 + groupNum) * Double.BYTES;
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/DoubleRLBE.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/DoubleRLBE.java
new file mode 100644
index 0000000..429ef35
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/DoubleRLBE.java
@@ -0,0 +1,272 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public class DoubleRLBE extends RLBE {
+ /** delta values */
+ private double[] DiffValue = new double[blockSize + 1];
+
+ /** repeat times on length code */
+ private long[] Lengrle = new long[blockSize + 1];
+
+ /** previous value of original value */
+ private double previousvalue;
+
+ /** constructor of DoubleRLBE */
+ public DoubleRLBE() {
+ super();
+ reset();
+ }
+
+ protected void reset() {
+ writeIndex = -1;
+ LengthCode = new int[blockSize + 1];
+ for (int i = 0; i < blockSize; i++) {
+ DiffValue[i] = 0;
+ LengthCode[i] = 0;
+ byteBuffer = 0;
+ numberLeftInBuffer = 0;
+ Lengrle[i] = 0;
+ }
+ }
+
+ /**
+ * calculate the binary code length of given long integer
+ *
+ * @param val the long integer to calculate length
+ * @return the length of val's binary code
+ */
+ private int calBinarylength(long val) {
+ if (val == 0) return 1;
+ int i = 64;
+ while ((((long) 1 << (i - 1)) & val) == 0 && i > 0) i--;
+ return i;
+ }
+
+ /**
+ * calculate the binary code length of given double note: double is
transfered into long first
+ *
+ * @param v the double to calculate length
+ * @return the length of val's binary code
+ */
+ private int calBinarylength(double v) {
+ long val = Double.doubleToRawLongBits(v);
+ if (val == 0) return 1;
+ int i = 64;
+ while ((((long) 1 << (i - 1)) & val) == 0 && i > 0) i--;
+ return i;
+ }
+
+ /**
+ * encode one input integer value
+ *
+ * @param value the integer to be encoded
+ * @param out the output stream to flush in when buffer is full
+ */
+ public void encodeValue(double value, ByteArrayOutputStream out) {
+ if (writeIndex == -1) {
+ // when the first value hasn't encoded yet
+ DiffValue[++writeIndex] = value;
+ LengthCode[writeIndex] = calBinarylength(value);
+ previousvalue = value;
+ return;
+ }
+ // calculate delta value
+ DiffValue[++writeIndex] = value - previousvalue;
+ // caldulate the length of delta value
+ LengthCode[writeIndex] = calBinarylength(DiffValue[writeIndex]);
+ previousvalue = value;
+ if (writeIndex == blockSize - 1) {
+ // when encoded number reach to blocksize
+ flush(out);
+ }
+ }
+
+ @Override
+ public void encode(double value, ByteArrayOutputStream out) {
+ encodeValue(value, out);
+ }
+
+ @Override
+ public void flush(ByteArrayOutputStream out) {
+ flushBlock(out);
+ }
+
+ /**
+ * calculate fibonacci code of input long integer
+ *
+ * @param val the long integer to be fibonacci-encoded
+ * @return the reverse fibonacci code of val in binary code
+ */
+ protected long calcFibonacci(long val) {
+ // fibonacci values are stored in Fib
+ long[] Fib = new long[blockSize * 2 + 1];
+ Fib[0] = 1;
+ Fib[1] = 1;
+ int i;
+ // generate fibonacci values from 1 to the first one larger than val
+ for (i = 2; Fib[i - 1] <= val; i++) {
+ Fib[i] = Fib[i - 1] + Fib[i - 2];
+ }
+
+ i--;
+ long valfib = 0;
+ // calculate fibonacci code
+ while (val > 0) {
+ while (Fib[i] > val && i >= 1) i--;
+ valfib |= (1 << (i - 1));
+ val -= Fib[i];
+ }
+ return valfib;
+ }
+
+ /** run length on DiffValue then store length at the first index in Lengrle.
*/
+ private void rleonlengthcode() {
+ int i = 0;
+ while (i <= writeIndex) {
+ int j = i;
+ int temprlecal = 0;
+ while (LengthCode[j] == LengthCode[i] && j <= writeIndex) {
+ j++;
+ temprlecal++;
+ }
+ // store repeat time at the first repeating value's position
+ Lengrle[i] = temprlecal;
+ i = j;
+ }
+ }
+
+ /**
+ * flush all encoded values in a block to output stream
+ *
+ * @param out the output stream to be flushed to
+ */
+ protected void flushBlock(ByteArrayOutputStream out) {
+ if (writeIndex == -1) {
+ return;
+ }
+ // store the number of values
+ writewriteIndex(out);
+ // calculate length code of delta binary length
+ rleonlengthcode();
+ for (int i = 0; i <= writeIndex; i++) {
+ if (Lengrle[i] > 0) // flush the adjacent same length delta values
+ try {
+ flushsegment(i, out);
+ } catch (IOException e) {
+ logger.error("flush data to stream failed!", e);
+ }
+ }
+ clearBuffer(out);
+ reset();
+ }
+
+ /**
+ * flush the adjacent same-length delta values
+ *
+ * @param i the position of the first delta value
+ * @param out output stream
+ * @throws IOException
+ */
+ private void flushsegment(int i, ByteArrayOutputStream out) throws
IOException {
+ // write the first 6 bits: length code in binary words.
+ for (int j = 6; j >= 0; j--) {
+ if ((LengthCode[i] & (1 << j)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ // write the fibonacci code in normal direction
+ long fib = calcFibonacci(Lengrle[i]);
+ int fiblen = calBinarylength(fib);
+ for (int j = 0; j < fiblen; j++) {
+ if ((fib & (1 << j)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ // write '1' to note the end of fibonacci code
+ writeBit(true, out);
+
+ // write Binary code words
+ int j = i;
+ do {
+ int tempDifflen = calBinarylength(DiffValue[j]);
+ long tempDiff = Double.doubleToRawLongBits(DiffValue[j]);
+ for (int k = tempDifflen - 1; k >= 0; k--) {
+ if ((tempDiff & ((long) 1 << k)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ j++;
+ } while (Lengrle[j] == 0 && j <= writeIndex);
+ }
+
+ @Override
+ public int getOneItemMaxSize() {
+ return 4 * 4 * 2;
+ }
+
+ @Override
+ public long getMaxByteSize() {
+ return 5 * 4 * blockSize * 2;
+ }
+
+ /**
+ * write one bit to byteBuffer, when byteBuffer is full, flush byteBuffer to
output stream
+ *
+ * @param b the bit to be written
+ * @param out output stream
+ */
+ protected void writeBit(boolean b, ByteArrayOutputStream out) {
+ byteBuffer <<= 1;
+ if (b) {
+ byteBuffer |= 1;
+ }
+
+ numberLeftInBuffer++;
+ if (numberLeftInBuffer == 8) {
+ clearBuffer(out);
+ }
+ }
+
+ /**
+ * flush bits left in byteBuffer to output stream
+ *
+ * @param out output stream
+ */
+ protected void clearBuffer(ByteArrayOutputStream out) {
+ if (numberLeftInBuffer == 0) return;
+ if (numberLeftInBuffer > 0) byteBuffer <<= (8 - numberLeftInBuffer);
+ out.write(byteBuffer);
+ numberLeftInBuffer = 0;
+ byteBuffer = 0;
+ }
+
+ /**
+ * write the number of encoded values to output stream
+ *
+ * @param out output stream
+ */
+ private void writewriteIndex(ByteArrayOutputStream out) {
+ for (int i = 31; i >= 0; i--) {
+ if ((writeIndex + 1 & (1 << i)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/DoubleSprintzEncoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/DoubleSprintzEncoder.java
new file mode 100644
index 0000000..d71b000
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/DoubleSprintzEncoder.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import org.apache.iotdb.tsfile.encoding.bitpacking.LongPacker;
+import org.apache.iotdb.tsfile.encoding.fire.LongFire;
+import org.apache.iotdb.tsfile.exception.encoding.TsFileEncodingException;
+import org.apache.iotdb.tsfile.utils.ReadWriteForEncodingUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Vector;
+
+public class DoubleSprintzEncoder extends SprintzEncoder {
+
+ /** bit packer */
+ LongPacker packer;
+
+ /** Long Fire Predictor * */
+ LongFire firePred;
+
+ /** we save all value in a list and calculate its bitwidth. */
+ protected Vector<Double> values;
+
+ /** convert to Long Buffer * */
+ long[] convertBuffer;
+
+ public DoubleSprintzEncoder() {
+ super();
+ values = new Vector<Double>();
+ firePred = new LongFire(3);
+ convertBuffer = new long[Block_size];
+ }
+
+ @Override
+ protected void reset() {
+ super.reset();
+ values.clear();
+ }
+
+ @Override
+ public int getOneItemMaxSize() {
+ return 1 + (1 + Block_size) * Double.BYTES;
+ }
+
+ @Override
+ public long getMaxByteSize() {
+ return 1 + (long) (values.size() + 1) * Double.BYTES;
+ }
+
+ protected long predict(Double value, Double preVlaue) throws
TsFileEncodingException {
+ long pred;
+ if (PredictMethod.equals("delta")) {
+ pred = delta(value, preVlaue);
+ } else if (PredictMethod.equals("fire")) {
+ pred = fire(value, preVlaue);
+ } else {
+ throw new TsFileEncodingException(
+ "Config: Predict Method {} of SprintzEncoder is not supported.");
+ }
+ if (pred <= 0) pred = -2 * pred;
+ else pred = 2 * pred - 1; // TODO:overflow
+ return pred;
+ }
+
+ @Override
+ protected void bitPack() throws IOException {
+ double preValue = values.get(0);
+ values.remove(0);
+ this.bitWidth =
ReadWriteForEncodingUtils.getLongMaxBitWidth(convertBuffer, Block_size);
+ packer = new LongPacker(this.bitWidth);
+ byte[] bytes = new byte[bitWidth];
+ packer.pack8Values(convertBuffer, 0, bytes);
+ ReadWriteForEncodingUtils.writeIntLittleEndianPaddedOnBitWidth(bitWidth,
byteCache, 1);
+ byteCache.write(ByteBuffer.allocate(8).putDouble(preValue).array());
+ byteCache.write(bytes, 0, bytes.length);
+ }
+
+ protected long delta(Double value, Double preValue) {
+ return Double.doubleToLongBits(value) - Double.doubleToLongBits(preValue);
+ }
+
+ protected long fire(Double value, Double preValue) {
+ long prev = Double.doubleToLongBits(preValue);
+ long val = Double.doubleToLongBits(value);
+ long pred = firePred.predict(prev);
+ long err = val - pred;
+ firePred.train(prev, val, err);
+ return err;
+ }
+
+ @Override
+ protected void entropy() {
+ // TODO
+ }
+
+ @Override
+ public void flush(ByteArrayOutputStream out) throws IOException {
+ if (byteCache.size() > 0) {
+ byteCache.writeTo(out);
+ }
+ if (!values.isEmpty()) {
+ int size = values.size();
+ size |= (1 << 7);
+ ReadWriteForEncodingUtils.writeIntLittleEndianPaddedOnBitWidth(size,
out, 1);
+ DoublePrecisionEncoderV2 encoder = new DoublePrecisionEncoderV2();
+ for (double val : values) {
+ encoder.encode(val, out);
+ }
+ encoder.flush(out);
+ }
+ reset();
+ }
+
+ @Override
+ public void encode(double value, ByteArrayOutputStream out) {
+ if (!isFirstCached) {
+ values.add(value);
+ isFirstCached = true;
+ return;
+ } else {
+ values.add(value);
+ }
+ if (values.size() == Block_size + 1) {
+ try {
+ firePred.reset();
+ for (int i = 1; i <= Block_size; i++) {
+ convertBuffer[i - 1] = predict(values.get(i), values.get(i - 1));
+ }
+ bitPack();
+ isFirstCached = false;
+ values.clear();
+ groupNum++;
+ if (groupNum == groupMax) {
+ flush(out);
+ }
+ } catch (IOException e) {
+ logger.error("Error occured when encoding INT32 Type value with with
Sprintz", e);
+ }
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/FloatRAKEEncoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/FloatRAKEEncoder.java
new file mode 100644
index 0000000..22c4731
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/FloatRAKEEncoder.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import java.io.ByteArrayOutputStream;
+
+public class FloatRAKEEncoder extends RAKEEncoder {
+
+ @Override
+ public void encode(float value, ByteArrayOutputStream out) {
+ isReadFinish = false;
+ String bit_value = Integer.toBinaryString(Float.floatToRawIntBits(value));
+ encodeNumber(bit_value, 32, out);
+ }
+
+ @Override
+ public int getOneItemMaxSize() {
+ return 1 + (1 + 1) * Float.BYTES;
+ }
+
+ @Override
+ public long getMaxByteSize() {
+ return 1 + (long) (1 + groupNum) * Float.BYTES;
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/FloatRLBE.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/FloatRLBE.java
new file mode 100644
index 0000000..ee3677e
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/FloatRLBE.java
@@ -0,0 +1,273 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public class FloatRLBE extends RLBE {
+ /** delta values */
+ private float[] DiffValue = new float[blockSize + 1];
+
+ /** repeat times on length code */
+ private int[] Lengrle = new int[blockSize + 1];
+
+ /** previous value of original value */
+ private float previousvalue;
+
+ /** constructor of FloatRLBE */
+ public FloatRLBE() {
+ super();
+ reset();
+ }
+
+ protected void reset() {
+ writeIndex = -1;
+ LengthCode = new int[blockSize + 1];
+ for (int i = 0; i < blockSize; i++) {
+ DiffValue[i] = 0;
+ LengthCode[i] = 0;
+ byteBuffer = 0;
+ numberLeftInBuffer = 0;
+ Lengrle[i] = 0;
+ }
+ }
+
+ /**
+ * calculate the binary code length of given float note: binary code of
float is transfered into
+ * binary code of int first
+ *
+ * @param v the integer to calculate length
+ * @return the length of val's binary code
+ */
+ private int calBinarylength(float v) {
+ int val = Float.floatToRawIntBits(v);
+ if (val == 0) return 1;
+ int i = 32;
+ while (((1 << (i - 1)) & val) == 0 && i > 0) i--;
+ return i;
+ }
+
+ /**
+ * calculate the binary code length of given integer
+ *
+ * @param val the integer to calculate length
+ * @return the length of val's binary code
+ */
+ private int calBinarylength(int val) {
+ if (val == 0) return 1;
+ int i = 32;
+ while (((1 << (i - 1)) & val) == 0 && i > 0) i--;
+ return i;
+ }
+
+ /**
+ * encode one input float value
+ *
+ * @param value the float to be encoded
+ * @param out the output stream to flush in when buffer is full
+ */
+ public void encodeValue(float value, ByteArrayOutputStream out) {
+ if (writeIndex == -1) {
+ // when the first value hasn't encoded yet
+ DiffValue[++writeIndex] = value;
+ LengthCode[writeIndex] = calBinarylength(value);
+ previousvalue = value;
+ return;
+ }
+ // calculate delta value
+ DiffValue[++writeIndex] = value - previousvalue;
+ // caldulate the length of delta value
+ LengthCode[writeIndex] = calBinarylength(DiffValue[writeIndex]);
+ previousvalue = value;
+ if (writeIndex == blockSize - 1) {
+ // when encoded number reach to blocksize
+ flush(out);
+ }
+ }
+
+ @Override
+ public void encode(float value, ByteArrayOutputStream out) {
+ encodeValue(value, out);
+ }
+
+ @Override
+ public void flush(ByteArrayOutputStream out) {
+ flushBlock(out);
+ }
+
+ /**
+ * calculate fibonacci code of input integer
+ *
+ * @param val the integer to be fibonacci-encoded
+ * @return the reverse fibonacci code of val in binary code
+ */
+ protected int calcFibonacci(int val) {
+ // fibonacci values are stored in Fib
+ int[] Fib = new int[blockSize * 2 + 1];
+ Fib[0] = 1;
+ Fib[1] = 1;
+ int i;
+ // generate fibonacci values from 1 to the first one larger than val
+ for (i = 2; Fib[i - 1] <= val; i++) {
+ Fib[i] = Fib[i - 1] + Fib[i - 2];
+ }
+
+ i--;
+ int valfib = 0;
+ // calculate fibonacci code
+ while (val > 0) {
+ while (Fib[i] > val && i >= 1) i--;
+ valfib |= (1 << (i - 1));
+ val -= Fib[i];
+ }
+ return valfib;
+ }
+
+ /** run length on DiffValue then store length at the first index in Lengrle.
*/
+ private void rleonlengthcode() {
+ int i = 0;
+ while (i <= writeIndex) {
+ int j = i;
+ int temprlecal = 0;
+ while (LengthCode[j] == LengthCode[i] && j <= writeIndex) {
+ j++;
+ temprlecal++;
+ }
+ // store repeat time at the first repeating value's position
+ Lengrle[i] = temprlecal;
+ i = j;
+ }
+ }
+
+ /**
+ * flush all encoded values in a block to output stream
+ *
+ * @param out the output stream to be flushed to
+ */
+ protected void flushBlock(ByteArrayOutputStream out) {
+ if (writeIndex == -1) {
+ return;
+ }
+ // store the number of values
+ writewriteIndex(out);
+ // calculate length code of delta binary length
+ rleonlengthcode();
+ for (int i = 0; i <= writeIndex; i++) {
+ if (Lengrle[i] > 0) // flush the adjacent same length delta values
+ try {
+ flushsegment(i, out);
+ } catch (IOException e) {
+ logger.error("flush data to stream failed!", e);
+ }
+ }
+ clearBuffer(out);
+ reset();
+ }
+
+ /**
+ * flush the adjacent same-length delta values
+ *
+ * @param i the position of the first delta value
+ * @param out output stream
+ * @throws IOException
+ */
+ private void flushsegment(int i, ByteArrayOutputStream out) throws
IOException {
+ // write the first 6 bits: length code in binary words.
+ for (int j = 5; j >= 0; j--) {
+ if ((LengthCode[i] & (1 << j)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ // write the fibonacci code in normal direction
+ int fib = calcFibonacci(Lengrle[i]);
+ int fiblen = calBinarylength(fib);
+ for (int j = 0; j < fiblen; j++) {
+ if ((fib & (1 << j)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ // write '1' to note the end of fibonacci code
+ writeBit(true, out);
+
+ // write Binary code words
+ int j = i;
+ do {
+ int tempDifflen = calBinarylength(DiffValue[j]);
+ int tempDiff = Float.floatToRawIntBits(DiffValue[j]);
+ for (int k = tempDifflen - 1; k >= 0; k--) {
+ if ((tempDiff & (1 << k)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ j++;
+ } while (Lengrle[j] == 0 && j <= writeIndex);
+ }
+
+ @Override
+ public int getOneItemMaxSize() {
+ return 4 * 4;
+ }
+
+ @Override
+ public long getMaxByteSize() {
+ return 5 * 4 * blockSize;
+ }
+
+ /**
+ * write one bit to byteBuffer, when byteBuffer is full, flush byteBuffer to
output stream
+ *
+ * @param b the bit to be written
+ * @param out output stream
+ */
+ protected void writeBit(boolean b, ByteArrayOutputStream out) {
+ byteBuffer <<= 1;
+ if (b) {
+ byteBuffer |= 1;
+ }
+
+ numberLeftInBuffer++;
+ if (numberLeftInBuffer == 8) {
+ clearBuffer(out);
+ }
+ }
+
+ /**
+ * flush bits left in byteBuffer to output stream
+ *
+ * @param out output stream
+ */
+ protected void clearBuffer(ByteArrayOutputStream out) {
+ if (numberLeftInBuffer == 0) return;
+ if (numberLeftInBuffer > 0) byteBuffer <<= (8 - numberLeftInBuffer);
+ out.write(byteBuffer);
+ numberLeftInBuffer = 0;
+ byteBuffer = 0;
+ }
+
+ /**
+ * write the number of encoded values to output stream
+ *
+ * @param out output stream
+ */
+ private void writewriteIndex(ByteArrayOutputStream out) {
+ for (int i = 31; i >= 0; i--) {
+ if ((writeIndex + 1 & (1 << i)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/FloatSprintzEncoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/FloatSprintzEncoder.java
new file mode 100644
index 0000000..c02c66d
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/FloatSprintzEncoder.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import org.apache.iotdb.tsfile.encoding.bitpacking.IntPacker;
+import org.apache.iotdb.tsfile.encoding.fire.IntFire;
+import org.apache.iotdb.tsfile.exception.encoding.TsFileEncodingException;
+import org.apache.iotdb.tsfile.utils.ReadWriteForEncodingUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Vector;
+
+public class FloatSprintzEncoder extends SprintzEncoder {
+
+ /** bit packer */
+ IntPacker packer;
+
+ /** Int Fire Predictor * */
+ IntFire firePred;
+
+ /** we save all value in a list and calculate its bitwidth. */
+ protected Vector<Float> values;
+
+ /** convert to integer Buffer * */
+ int[] convertBuffer;
+
+ public FloatSprintzEncoder() {
+ super();
+ values = new Vector<Float>();
+ firePred = new IntFire(2);
+ convertBuffer = new int[Block_size];
+ }
+
+ protected void reset() {
+ super.reset();
+ values.clear();
+ }
+
+ @Override
+ public int getOneItemMaxSize() {
+ return 1 + (1 + Block_size) * Integer.BYTES;
+ }
+
+ @Override
+ public long getMaxByteSize() {
+ return 1 + (long) (values.size() + 1) * Integer.BYTES;
+ }
+
+ protected int predict(Float value, Float preVlaue) throws
TsFileEncodingException {
+ int pred;
+ if (PredictMethod.equals("delta")) {
+ pred = delta(value, preVlaue);
+ } else if (PredictMethod.equals("fire")) {
+ pred = fire(value, preVlaue);
+ } else {
+ throw new TsFileEncodingException(
+ "Config: Predict Method {} of SprintzEncoder is not supported.");
+ }
+ if (pred <= 0) pred = -2 * pred;
+ else pred = 2 * pred - 1; // TODO:overflow
+ return pred;
+ }
+
+ @Override
+ protected void bitPack() throws IOException {
+ float preValue = values.get(0);
+ values.remove(0);
+ this.bitWidth = ReadWriteForEncodingUtils.getIntMaxBitWidth(convertBuffer,
Block_size);
+ packer = new IntPacker(this.bitWidth);
+ byte[] bytes = new byte[bitWidth];
+ packer.pack8Values(convertBuffer, 0, bytes);
+ ReadWriteForEncodingUtils.writeIntLittleEndianPaddedOnBitWidth(bitWidth,
byteCache, 1);
+
byteCache.write(ByteBuffer.allocate(Float.BYTES).putFloat(preValue).array());
+ byteCache.write(bytes, 0, bytes.length);
+ }
+
+ protected int delta(Float value, Float preValue) {
+ return Float.floatToIntBits(value) - Float.floatToIntBits(preValue);
+ }
+
+ protected int fire(Float value, Float preValue) {
+ int prev = Float.floatToIntBits(preValue);
+ int val = Float.floatToIntBits(value);
+ int pred = firePred.predict(prev);
+ int err = val - pred;
+ firePred.train(prev, val, err);
+ return err;
+ }
+
+ @Override
+ protected void entropy() {
+ // TODO
+ }
+
+ @Override
+ public void flush(ByteArrayOutputStream out) throws IOException {
+ if (byteCache.size() > 0) {
+ byteCache.writeTo(out);
+ }
+ if (!values.isEmpty()) {
+ int size = values.size();
+ size |= (1 << 7);
+ ReadWriteForEncodingUtils.writeIntLittleEndianPaddedOnBitWidth(size,
out, 1);
+ SinglePrecisionEncoderV2 encoder = new SinglePrecisionEncoderV2();
+ for (float val : values) {
+ encoder.encode(val, out);
+ }
+ encoder.flush(out);
+ }
+ reset();
+ }
+
+ @Override
+ public void encode(float value, ByteArrayOutputStream out) {
+ if (!isFirstCached) {
+ values.add(value);
+ isFirstCached = true;
+ return;
+ } else {
+ values.add(value);
+ }
+ if (values.size() == Block_size + 1) {
+ try {
+ firePred.reset();
+ for (int i = 1; i <= Block_size; i++) {
+ convertBuffer[i - 1] = predict(values.get(i), values.get(i - 1));
+ }
+ bitPack();
+ isFirstCached = false;
+ values.clear();
+ groupNum++;
+ if (groupNum == groupMax) {
+ flush(out);
+ }
+ } catch (IOException e) {
+ logger.error("Error occured when encoding Float Type value with with
Sprintz", e);
+ }
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/IntRAKEEncoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/IntRAKEEncoder.java
new file mode 100644
index 0000000..e183da6
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/IntRAKEEncoder.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import java.io.ByteArrayOutputStream;
+
+public class IntRAKEEncoder extends RAKEEncoder {
+
+ @Override
+ public void encode(int value, ByteArrayOutputStream out) {
+ isReadFinish = false;
+ String bit_value = Integer.toBinaryString(value);
+ encodeNumber(bit_value, 32, out);
+ }
+
+ @Override
+ public int getOneItemMaxSize() {
+ return 1 + (1 + 1) * Integer.BYTES;
+ }
+
+ @Override
+ public long getMaxByteSize() {
+ return 1 + (long) (1 + groupNum) * Integer.BYTES;
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/IntRLBE.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/IntRLBE.java
new file mode 100644
index 0000000..1686846
--- /dev/null
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/IntRLBE.java
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public class IntRLBE extends RLBE {
+ /** delta values */
+ private int[] DiffValue = new int[blockSize + 1];
+
+ /** repeat times on length code */
+ private int[] Lengrle = new int[blockSize + 1];
+
+ /** previous value of original value */
+ private int previousvalue;
+
+ /** constructor of IntRLBE */
+ public IntRLBE() {
+ super();
+ reset();
+ }
+
+ protected void reset() {
+ writeIndex = -1;
+ LengthCode = new int[blockSize + 1];
+ for (int i = 0; i < blockSize; i++) {
+ DiffValue[i] = 0;
+ LengthCode[i] = 0;
+ byteBuffer = 0;
+ numberLeftInBuffer = 0;
+ Lengrle[i] = 0;
+ }
+ }
+
+ /**
+ * calculate the binary code length of given integer
+ *
+ * @param val the integer to calculate length
+ * @return the length of val's binary code
+ */
+ private int calBinarylength(int val) {
+ if (val == 0) return 1;
+ int i = 32;
+ while (((1 << (i - 1)) & val) == 0 && i > 0) i--;
+ return i;
+ }
+
+ /**
+ * encode one input integer value
+ *
+ * @param value the integer to be encoded
+ * @param out the output stream to flush in when buffer is full
+ */
+ public void encodeValue(int value, ByteArrayOutputStream out) {
+ if (writeIndex == -1) {
+ // when the first value hasn't encoded yet
+ DiffValue[++writeIndex] = value;
+ LengthCode[writeIndex] = calBinarylength(value);
+ previousvalue = value;
+ return;
+ }
+ // calculate delta value
+ DiffValue[++writeIndex] = value - previousvalue;
+ // caldulate the length of delta value
+ LengthCode[writeIndex] = calBinarylength(DiffValue[writeIndex]);
+ previousvalue = value;
+ if (writeIndex == blockSize - 1) {
+ // when encoded number reach to blocksize
+ flush(out);
+ }
+ }
+
+ @Override
+ public void encode(int value, ByteArrayOutputStream out) {
+ encodeValue(value, out);
+ }
+
+ @Override
+ public void flush(ByteArrayOutputStream out) {
+ flushBlock(out);
+ }
+
+ /**
+ * calculate fibonacci code of input integer
+ *
+ * @param val the integer to be fibonacci-encoded
+ * @return the reverse fibonacci code of val in binary code
+ */
+ protected int calcFibonacci(int val) {
+ // fibonacci values are stored in Fib
+ int[] Fib = new int[blockSize * 2 + 1];
+ Fib[0] = 1;
+ Fib[1] = 1;
+ int i;
+ // generate fibonacci values from 1 to the first one larger than val
+ for (i = 2; Fib[i - 1] <= val; i++) {
+ Fib[i] = Fib[i - 1] + Fib[i - 2];
+ }
+
+ i--;
+ int valfib = 0;
+ // calculate fibonacci code
+ while (val > 0) {
+ while (Fib[i] > val && i >= 1) i--;
+ valfib |= (1 << (i - 1));
+ val -= Fib[i];
+ }
+ return valfib;
+ }
+
+ /** run length on DiffValue then store length at the first index in Lengrle.
*/
+ private void rleonlengthcode() {
+ int i = 0;
+ while (i <= writeIndex) {
+ int j = i;
+ int temprlecal = 0;
+ while (LengthCode[j] == LengthCode[i] && j <= writeIndex) {
+ j++;
+ temprlecal++;
+ }
+ // store repeat time at the first repeating value's position
+ Lengrle[i] = temprlecal;
+ i = j;
+ }
+ }
+
+ /**
+ * flush all encoded values in a block to output stream
+ *
+ * @param out the output stream to be flushed to
+ */
+ protected void flushBlock(ByteArrayOutputStream out) {
+ if (writeIndex == -1) {
+ return;
+ }
+ // store the number of values
+ writewriteIndex(out);
+ // calculate length code of delta binary length
+ rleonlengthcode();
+ for (int i = 0; i <= writeIndex; i++) {
+ if (Lengrle[i] > 0) // flush the adjacent same length delta values
+ try {
+ flushsegment(i, out);
+ } catch (IOException e) {
+ logger.error("flush data to stream failed!", e);
+ }
+ }
+ clearBuffer(out);
+ reset();
+ }
+
+ /**
+ * flush the adjacent same-length delta values
+ *
+ * @param i the position of the first delta value
+ * @param out output stream
+ * @throws IOException
+ */
+ private void flushsegment(int i, ByteArrayOutputStream out) throws
IOException {
+ // write the first 6 bits: length code in binary words.
+ for (int j = 5; j >= 0; j--) {
+ if ((LengthCode[i] & (1 << j)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ // write the fibonacci code in normal direction
+ int fib = calcFibonacci(Lengrle[i]);
+ int fiblen = calBinarylength(fib);
+ for (int j = 0; j < fiblen; j++) {
+ if ((fib & (1 << j)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ // write '1' to note the end of fibonacci code
+ writeBit(true, out);
+
+ // write Binary code words
+ int j = i;
+ do {
+ int tempDifflen = calBinarylength(DiffValue[j]);
+ for (int k = tempDifflen - 1; k >= 0; k--) {
+ if ((DiffValue[j] & (1 << k)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ j++;
+ } while (Lengrle[j] == 0 && j <= writeIndex);
+ }
+
+ @Override
+ public int getOneItemMaxSize() {
+ return 4 * 4;
+ }
+
+ @Override
+ public long getMaxByteSize() {
+ return 5 * 4 * blockSize;
+ }
+
+ /**
+ * write one bit to byteBuffer, when byteBuffer is full, flush byteBuffer to
output stream
+ *
+ * @param b the bit to be written
+ * @param out output stream
+ */
+ protected void writeBit(boolean b, ByteArrayOutputStream out) {
+ byteBuffer <<= 1;
+ if (b) {
+ byteBuffer |= 1;
+ }
+
+ numberLeftInBuffer++;
+ if (numberLeftInBuffer == 8) {
+ clearBuffer(out);
+ }
+ }
+
+ /**
+ * flush bits left in byteBuffer to output stream
+ *
+ * @param out output stream
+ */
+ protected void clearBuffer(ByteArrayOutputStream out) {
+ if (numberLeftInBuffer == 0) return;
+ if (numberLeftInBuffer > 0) byteBuffer <<= (8 - numberLeftInBuffer);
+ out.write(byteBuffer);
+ numberLeftInBuffer = 0;
+ byteBuffer = 0;
+ }
+
+ /**
+ * write the number of encoded values to output stream
+ *
+ * @param out output stream
+ */
+ private void writewriteIndex(ByteArrayOutputStream out) {
+ for (int i = 31; i >= 0; i--) {
+ if ((writeIndex + 1 & (1 << i)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/IntSprintzEncoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/IntSprintzEncoder.java
new file mode 100644
index 0000000..ca27390
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/IntSprintzEncoder.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import org.apache.iotdb.tsfile.encoding.bitpacking.IntPacker;
+import org.apache.iotdb.tsfile.encoding.fire.IntFire;
+import org.apache.iotdb.tsfile.exception.encoding.TsFileEncodingException;
+import org.apache.iotdb.tsfile.utils.ReadWriteForEncodingUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Vector;
+
+public class IntSprintzEncoder extends SprintzEncoder {
+
+ /** bit packer */
+ IntPacker packer;
+
+ /** Fire predictor * */
+ IntFire firePred;
+
+ /** we save all value in a list and calculate its bitwidth. */
+ protected Vector<Integer> values;
+
+ public IntSprintzEncoder() {
+ super();
+ values = new Vector<>();
+ firePred = new IntFire(2);
+ }
+
+ @Override
+ protected void reset() {
+ super.reset();
+ values.clear();
+ }
+
+ @Override
+ public int getOneItemMaxSize() {
+ return 1 + (1 + Block_size) * Integer.BYTES;
+ }
+
+ @Override
+ public long getMaxByteSize() {
+ return 1 + (long) (values.size() + 1) * Integer.BYTES;
+ }
+
+ protected Integer predict(Integer value, Integer preVlaue) throws
TsFileEncodingException {
+ Integer pred;
+ if (PredictMethod.equals("delta")) {
+ pred = delta(value, preVlaue);
+ } else if (PredictMethod.equals("fire")) {
+ pred = fire(value, preVlaue);
+ } else {
+ throw new TsFileEncodingException(
+ "Config: Predict Method {} of SprintzEncoder is not supported.");
+ }
+ if (pred <= 0) pred = -2 * pred;
+ else pred = 2 * pred - 1; // TODO:overflow
+ return pred;
+ }
+
+ @Override
+ protected void bitPack() throws IOException {
+ int preValue = values.get(0);
+ values.remove(0);
+ this.bitWidth = ReadWriteForEncodingUtils.getIntMaxBitWidth(values);
+ packer = new IntPacker(this.bitWidth);
+ byte[] bytes = new byte[bitWidth];
+ int[] tmpBuffer = new int[Block_size];
+ for (int i = 0; i < Block_size; i++) tmpBuffer[i] = values.get(i);
+ packer.pack8Values(tmpBuffer, 0, bytes);
+ ReadWriteForEncodingUtils.writeIntLittleEndianPaddedOnBitWidth(bitWidth,
byteCache, 1);
+ ReadWriteForEncodingUtils.writeUnsignedVarInt(preValue, byteCache);
+ byteCache.write(bytes, 0, bytes.length);
+ }
+
+ protected Integer delta(Integer value, Integer preValue) {
+ return value - preValue;
+ }
+
+ protected Integer fire(Integer value, Integer preValue) {
+ int pred = firePred.predict(preValue);
+ int err = value - pred;
+ firePred.train(preValue, value, err);
+ return err;
+ }
+
+ @Override
+ protected void entropy() {
+ // TODO
+ }
+
+ @Override
+ public void flush(ByteArrayOutputStream out) throws IOException {
+ if (byteCache.size() > 0) {
+ byteCache.writeTo(out);
+ }
+ if (!values.isEmpty()) {
+ int size = values.size();
+ size |= (1 << 7);
+ ReadWriteForEncodingUtils.writeIntLittleEndianPaddedOnBitWidth(size,
out, 1);
+ IntRleEncoder encoder = new IntRleEncoder();
+ for (int val : values) {
+ encoder.encode(val, out);
+ }
+ encoder.flush(out);
+ }
+ reset();
+ }
+
+ @Override
+ public void encode(int value, ByteArrayOutputStream out) {
+ if (!isFirstCached) {
+ values.add(value);
+ isFirstCached = true;
+ return;
+ } else {
+ values.add(value);
+ }
+ if (values.size() == Block_size + 1) {
+ try {
+ int pre = values.get(0);
+ firePred.reset();
+ for (int i = 1; i <= Block_size; i++) {
+ int tmp = values.get(i);
+ values.set(i, predict(values.get(i), pre));
+ pre = tmp;
+ }
+ bitPack();
+ isFirstCached = false;
+ values.clear();
+ groupNum++;
+ if (groupNum == groupMax) {
+ flush(out);
+ }
+ } catch (IOException e) {
+ logger.error("Error occured when encoding INT32 Type value with with
Sprintz", e);
+ }
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/LongRAKEEncoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/LongRAKEEncoder.java
new file mode 100644
index 0000000..fe896cb
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/LongRAKEEncoder.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import java.io.ByteArrayOutputStream;
+
+public class LongRAKEEncoder extends RAKEEncoder {
+
+ @Override
+ public void encode(long value, ByteArrayOutputStream out) {
+ isReadFinish = false;
+ String bit_value = Long.toBinaryString(value);
+ encodeNumber(bit_value, 64, out);
+ }
+
+ @Override
+ public int getOneItemMaxSize() {
+ return 1 + (1 + 1) * Long.BYTES;
+ }
+
+ @Override
+ public long getMaxByteSize() {
+ return 1 + (long) (1 + groupNum) * Long.BYTES;
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/LongRLBE.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/LongRLBE.java
new file mode 100644
index 0000000..5ec12b9
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/LongRLBE.java
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public class LongRLBE extends RLBE {
+ /** delta values */
+ private long[] DiffValue = new long[blockSize + 1];
+
+ /** repeat times on length code */
+ private long[] Lengrle = new long[blockSize + 1];
+
+ /** previous value of original value */
+ private long previousvalue;
+
+ /** constructor of LongRLBE */
+ public LongRLBE() {
+ super();
+ reset();
+ }
+
+ protected void reset() {
+ writeIndex = -1;
+ LengthCode = new int[blockSize + 1];
+ for (int i = 0; i < blockSize; i++) {
+ DiffValue[i] = 0;
+ LengthCode[i] = 0;
+ byteBuffer = 0;
+ numberLeftInBuffer = 0;
+ Lengrle[i] = 0;
+ }
+ }
+
+ /**
+ * calculate the binary code length of given long integer
+ *
+ * @param val the long integer to calculate length
+ * @return the length of val's binary code
+ */
+ private int calBinarylength(long val) {
+ if (val == 0) return 1;
+ int i = 64;
+ while ((((long) 1 << (i - 1)) & val) == 0 && i > 0) i--;
+ return i;
+ }
+
+ /**
+ * encode one input long integer value
+ *
+ * @param value the long integer to be encoded
+ * @param out the output stream to flush in when buffer is full
+ */
+ public void encodeValue(long value, ByteArrayOutputStream out) {
+ if (writeIndex == -1) {
+ // when the first value hasn't encoded yet
+ DiffValue[++writeIndex] = value;
+ LengthCode[writeIndex] = calBinarylength(value);
+ previousvalue = value;
+ return;
+ }
+ // calculate delta value
+ DiffValue[++writeIndex] = value - previousvalue;
+ // caldulate the length of delta value
+ LengthCode[writeIndex] = calBinarylength(DiffValue[writeIndex]);
+ previousvalue = value;
+ if (writeIndex == blockSize - 1) {
+ // when encoded number reach to blocksize
+ flush(out);
+ }
+ }
+
+ @Override
+ public void encode(long value, ByteArrayOutputStream out) {
+ encodeValue(value, out);
+ }
+
+ @Override
+ public void flush(ByteArrayOutputStream out) {
+ flushBlock(out);
+ }
+
+ /**
+ * calculate fibonacci code of input long integer
+ *
+ * @param val the long integer to be fibonacci-encoded
+ * @return the reverse fibonacci code of val in binary code
+ */
+ protected long calcFibonacci(long val) {
+ // fibonacci values are stored in Fib
+ long[] Fib = new long[blockSize * 2 + 1];
+ Fib[0] = 1;
+ Fib[1] = 1;
+ int i;
+ // generate fibonacci values from 1 to the first one larger than val
+ for (i = 2; Fib[i - 1] <= val; i++) {
+ Fib[i] = Fib[i - 1] + Fib[i - 2];
+ }
+
+ i--;
+ long valfib = 0;
+ // calculate fibonacci code
+ while (val > 0) {
+ while (Fib[i] > val && i >= 1) i--;
+ valfib |= (1 << (i - 1));
+ val -= Fib[i];
+ }
+ return valfib;
+ }
+
+ /** run length on DiffValue then store length at the first index in Lengrle.
*/
+ private void rleonlengthcode() {
+ int i = 0;
+ while (i <= writeIndex) {
+ int j = i;
+ int temprlecal = 0;
+ while (LengthCode[j] == LengthCode[i] && j <= writeIndex) {
+ j++;
+ temprlecal++;
+ }
+ // store repeat time at the first repeating value's position
+ Lengrle[i] = temprlecal;
+ i = j;
+ }
+ }
+
+ /**
+ * flush all encoded values in a block to output stream
+ *
+ * @param out the output stream to be flushed to
+ */
+ protected void flushBlock(ByteArrayOutputStream out) {
+ if (writeIndex == -1) {
+ return;
+ }
+ // store the number of values
+ writewriteIndex(out);
+ // calculate length code of delta binary length
+ rleonlengthcode();
+ for (int i = 0; i <= writeIndex; i++) {
+ if (Lengrle[i] > 0) // flush the adjacent same length delta values
+ try {
+ flushsegment(i, out);
+ } catch (IOException e) {
+ logger.error("flush data to stream failed!", e);
+ }
+ }
+ clearBuffer(out);
+ reset();
+ }
+
+ /**
+ * flush the adjacent same-length delta values
+ *
+ * @param i the position of the first delta value
+ * @param out output stream
+ * @throws IOException
+ */
+ private void flushsegment(int i, ByteArrayOutputStream out) throws
IOException {
+ // write the first 7 bits: length code in binary words.
+ for (int j = 6; j >= 0; j--) {
+ if ((LengthCode[i] & (1 << j)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ // write the fibonacci code in normal direction
+ long fib = calcFibonacci(Lengrle[i]);
+ int fiblen = calBinarylength(fib);
+ for (int j = 0; j < fiblen; j++) {
+ if ((fib & (1 << j)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ // write '1' to note the end of fibonacci code
+ writeBit(true, out);
+
+ // write Binary code words
+ int j = i;
+ do {
+ int tempDifflen = calBinarylength(DiffValue[j]);
+ for (int k = tempDifflen - 1; k >= 0; k--) {
+ if ((DiffValue[j] & ((long) 1 << k)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ j++;
+ } while (Lengrle[j] == 0 && j <= writeIndex);
+ }
+
+ @Override
+ public int getOneItemMaxSize() {
+ return 4 * 4 * 2;
+ }
+
+ @Override
+ public long getMaxByteSize() {
+ return 5 * 4 * blockSize * 2;
+ }
+
+ /**
+ * write one bit to byteBuffer, when byteBuffer is full, flush byteBuffer to
output stream
+ *
+ * @param b the bit to be written
+ * @param out output stream
+ */
+ protected void writeBit(boolean b, ByteArrayOutputStream out) {
+ byteBuffer <<= 1;
+ if (b) {
+ byteBuffer |= 1;
+ }
+
+ numberLeftInBuffer++;
+ if (numberLeftInBuffer == 8) {
+ clearBuffer(out);
+ }
+ }
+
+ /**
+ * flush bits left in byteBuffer to output stream
+ *
+ * @param out output stream
+ */
+ protected void clearBuffer(ByteArrayOutputStream out) {
+ if (numberLeftInBuffer == 0) return;
+ if (numberLeftInBuffer > 0) byteBuffer <<= (8 - numberLeftInBuffer);
+ out.write(byteBuffer);
+ numberLeftInBuffer = 0;
+ byteBuffer = 0;
+ }
+
+ /**
+ * write the number of encoded values to output stream
+ *
+ * @param out output stream
+ */
+ private void writewriteIndex(ByteArrayOutputStream out) {
+ for (int i = 31; i >= 0; i--) {
+ if ((writeIndex + 1 & (1 << i)) > 0) writeBit(true, out);
+ else writeBit(false, out);
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/LongSprintzEncoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/LongSprintzEncoder.java
new file mode 100644
index 0000000..7b6dffd
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/LongSprintzEncoder.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import org.apache.iotdb.tsfile.encoding.bitpacking.LongPacker;
+import org.apache.iotdb.tsfile.encoding.fire.LongFire;
+import org.apache.iotdb.tsfile.exception.encoding.TsFileEncodingException;
+import org.apache.iotdb.tsfile.utils.ReadWriteForEncodingUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Vector;
+
+public class LongSprintzEncoder extends SprintzEncoder {
+
+ /** bit packer */
+ LongPacker packer;
+
+ /** Long Fire predictor * */
+ LongFire firePred;
+
+ /** we save all value in a list and calculate its bitwidth. */
+ protected Vector<Long> values;
+
+ public LongSprintzEncoder() {
+ super();
+ values = new Vector<>();
+ firePred = new LongFire(3);
+ }
+
+ @Override
+ protected void reset() {
+ super.reset();
+ values.clear();
+ }
+
+ @Override
+ public int getOneItemMaxSize() {
+ return 1 + (1 + Block_size) * Long.BYTES;
+ }
+
+ @Override
+ public long getMaxByteSize() {
+ return 1 + (1 + values.size()) * Long.BYTES;
+ }
+
+ protected Long predict(Long value, Long preVlaue) throws
TsFileEncodingException {
+ Long pred;
+ if (PredictMethod.equals("delta")) {
+ pred = delta(value, preVlaue);
+ } else if (PredictMethod.equals("fire")) {
+ pred = fire(value, preVlaue);
+ } else {
+ throw new TsFileEncodingException(
+ "Config: Predict Method {} of SprintzEncoder is not supported.");
+ }
+ if (pred <= 0) pred = -2 * pred;
+ else pred = 2 * pred - 1; // TODO:overflow
+ return pred;
+ }
+
+ @Override
+ protected void bitPack() throws IOException {
+ long preValue = values.get(0);
+ values.remove(0);
+ this.bitWidth = ReadWriteForEncodingUtils.getLongMaxBitWidth(values);
+ packer = new LongPacker(this.bitWidth);
+ byte[] bytes = new byte[bitWidth];
+ long[] tmpBuffer = new long[Block_size];
+ for (int i = 0; i < Block_size; i++) tmpBuffer[i] = values.get(i);
+ packer.pack8Values(tmpBuffer, 0, bytes);
+ ReadWriteForEncodingUtils.writeIntLittleEndianPaddedOnBitWidth(bitWidth,
byteCache, 1);
+ byteCache.write(ByteBuffer.allocate(8).putLong(preValue).array());
+ byteCache.write(bytes, 0, bytes.length);
+ }
+
+ protected Long delta(Long value, Long preValue) {
+ return value - preValue;
+ }
+
+ protected Long fire(Long value, Long preValue) {
+ long pred = firePred.predict(preValue);
+ long err = value - pred;
+ firePred.train(preValue, value, err);
+ return err;
+ }
+
+ @Override
+ protected void entropy() {
+ // TODO
+ }
+
+ @Override
+ public void flush(ByteArrayOutputStream out) throws IOException {
+ if (byteCache.size() > 0) {
+ byteCache.writeTo(out);
+ }
+ if (!values.isEmpty()) {
+ int size = values.size();
+ size |= (1 << 7);
+ ReadWriteForEncodingUtils.writeIntLittleEndianPaddedOnBitWidth(size,
out, 1);
+ LongRleEncoder encoder = new LongRleEncoder();
+ for (long val : values) {
+ encoder.encode(val, out);
+ }
+ encoder.flush(out);
+ }
+ reset();
+ }
+
+ @Override
+ public void encode(long value, ByteArrayOutputStream out) {
+ if (!isFirstCached) {
+ values.add(value);
+ isFirstCached = true;
+ return;
+ } else {
+ values.add(value);
+ }
+ if (values.size() == Block_size + 1) {
+ try {
+ long pre = values.get(0);
+ firePred.reset();
+ for (int i = 1; i <= Block_size; i++) {
+ long tmp = values.get(i);
+ values.set(i, predict(values.get(i), pre));
+ pre = tmp;
+ }
+ bitPack();
+ isFirstCached = false;
+ values.clear();
+ groupNum++;
+ if (groupNum == groupMax) {
+ flush(out);
+ }
+ } catch (IOException e) {
+ logger.error("Error occured when encoding INT64 Type value with with
Sprintz", e);
+ }
+ }
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/RAKEEncoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/RAKEEncoder.java
new file mode 100644
index 0000000..137c789
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/RAKEEncoder.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import static java.lang.Math.pow;
+
+public abstract class RAKEEncoder extends Encoder {
+ public String rakeBuffer;
+ private byte byteBuffer;
+ protected int numberLeftInBuffer;
+ /** whether to finish reading int, long, double or float * */
+ protected boolean isReadFinish;
+ /** group size maximum * */
+ protected int groupMax = 16;
+
+ /** group number * */
+ protected int groupNum;
+
+ private int T;
+ private int L;
+ protected ByteArrayOutputStream byteCache;
+ private static final Logger logger =
LoggerFactory.getLogger(RAKEEncoder.class);
+
+ /** constructor. * */
+ public RAKEEncoder() {
+
+ super(TSEncoding.RAKE);
+ L = 2;
+ T = (int) pow(2, L);
+ isReadFinish = false;
+ rakeBuffer = "";
+ byteCache = new ByteArrayOutputStream();
+ groupNum = 0;
+ }
+
+ protected void reset() {
+ byteCache.reset();
+ isReadFinish = false;
+ groupNum = 0;
+ }
+
+ /** encode binary digits of the string type into the byte stream */
+ protected void encodeNumber(String bit_value, int length,
ByteArrayOutputStream out) {
+ int zeros = length - bit_value.length();
+ for (int i = 0; i < zeros; i++) {
+ rakeBuffer += '0';
+ }
+ rakeBuffer += bit_value;
+ int len = rakeBuffer.length();
+ int i = 0;
+ boolean found = false;
+ int bias = 0;
+ while (i + T <= len) {
+ for (int j = 0; j < T; j++) {
+ if (rakeBuffer.charAt(i + j) == '1') {
+ found = true;
+ bias = j;
+ break;
+ }
+ }
+ if (found) {
+ String b = Integer.toBinaryString(bias);
+ writeBit(true, byteCache);
+ int zero_b = L - b.length();
+ for (int k = 0; k < zero_b; k++) {
+ writeBit(false, byteCache);
+ }
+ for (int k = 0; k < b.length() - 1; k++) {
+ writeBit(b.charAt(k) == '1', byteCache);
+ }
+ if (i == len - bias - 1) {
+ isReadFinish = true;
+ }
+ writeBit(b.charAt(b.length() - 1) == '1', byteCache);
+ i += (bias + 1);
+ } else {
+ if (i == len - T) {
+ isReadFinish = true;
+ }
+ writeBit(false, byteCache);
+ i += T;
+ }
+ if (i + T > len && i < len && !isReadFinish) {
+ for (int k = i; k < len - 1; k++) {
+ writeBit(rakeBuffer.charAt(k) == '1', byteCache);
+ }
+ isReadFinish = true;
+ writeBit(rakeBuffer.charAt(len - 1) == '1', byteCache);
+ break;
+ }
+ found = false;
+ }
+ isReadFinish = true;
+ rakeBuffer = "";
+ groupNum++;
+ if (groupNum > groupMax) {
+ try {
+ this.flush(out);
+ groupNum = 0;
+ } catch (IOException e) {
+ logger.error("Error occured when encoding INT32 Type value with with
RAKE", e);
+ }
+ }
+ }
+
+ protected void writeBit(boolean b, ByteArrayOutputStream out) {
+ // add bit to buffer
+ byteBuffer <<= 1;
+ if (b) {
+ byteBuffer |= 1;
+ }
+
+ // if buffer is full (8 bits), write out as a single byte
+ numberLeftInBuffer++;
+ if (numberLeftInBuffer == 8 || isReadFinish) {
+ clearBuffer(out);
+ }
+ }
+
+ /** clean all useless value in bufferedValues and set 0. */
+ protected void clearBuffer(ByteArrayOutputStream out) {
+ if (numberLeftInBuffer == 0) {
+ return;
+ }
+ if (numberLeftInBuffer > 0) {
+ byteBuffer <<= (8 - numberLeftInBuffer);
+ }
+ // write a byte into out
+ out.write(byteBuffer);
+ numberLeftInBuffer = 0;
+ byteBuffer = 0;
+ }
+
+ @Override
+ public void flush(ByteArrayOutputStream out) throws IOException {
+ if (byteCache.size() > 0) {
+ byteCache.writeTo(out);
+ }
+ byteCache.reset();
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/RLBE.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/RLBE.java
new file mode 100644
index 0000000..072c7e8
--- /dev/null
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/RLBE.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+
+public class RLBE extends Encoder {
+ /** Every BLOCK_DEFAULT_SIZE values are followed by a header */
+ protected static final int BLOCK_DEFAULT_SIZE = 10000;
+
+ protected static final Logger logger = LoggerFactory.getLogger(RLBE.class);
+
+ /** output stream to buffer {@code <length> <fibonacci code> <delta value>}
*/
+ protected ByteArrayOutputStream out;
+
+ protected int blockSize = BLOCK_DEFAULT_SIZE;
+
+ /** Storage bits into byteBuffer and flush when full */
+ protected byte byteBuffer;
+ /** Valid bits left in byteBuffer */
+ protected int numberLeftInBuffer;
+
+ /** Differential Value of InputData is stored in DiffValue */
+
+ /** Length of binary code of delta values are stored in LengthCode */
+ protected int[] LengthCode;
+
+ /** When writeIndex == -1, the first value is not stored */
+ protected int writeIndex = -1;
+
+ /** Constructor of RLBE */
+ public RLBE() {
+ super(TSEncoding.RLBE);
+ // blockSize = size;
+ }
+
+ @Override
+ public void flush(ByteArrayOutputStream out) {}
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/SprintzEncoder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/SprintzEncoder.java
new file mode 100644
index 0000000..cc5daad
--- /dev/null
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/SprintzEncoder.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.encoder;
+
+import org.apache.iotdb.tsfile.common.conf.TSFileConfig;
+import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public abstract class SprintzEncoder extends Encoder {
+ protected static final Logger logger =
LoggerFactory.getLogger(SprintzEncoder.class);
+
+ /** Segment block size to compress:8 */
+ protected int Block_size = 8;
+
+ /** group size maximum * */
+ protected int groupMax = 16;
+
+ /** group number * */
+ protected int groupNum;
+
+ /** the bit width used for bit-packing and rle. */
+ protected int bitWidth;
+
+ /** output stream to buffer {@code <bitwidth> <encoded-data>}. */
+ protected ByteArrayOutputStream byteCache;
+
+ /** selecet the predict method */
+ protected String PredictMethod =
+ TSFileDescriptor.getInstance().getConfig().getSprintzPredictScheme();;
+
+ protected boolean isFirstCached = false;
+
+ protected TSFileConfig config = TSFileDescriptor.getInstance().getConfig();
+
+ public SprintzEncoder() {
+ super(TSEncoding.SPRINTZ);
+ byteCache = new ByteArrayOutputStream();
+ }
+
+ protected void reset() {
+ byteCache.reset();
+ isFirstCached = false;
+ groupNum = 0;
+ }
+
+ protected abstract void bitPack() throws IOException;
+
+ protected abstract void entropy();
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/TSEncodingBuilder.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/TSEncodingBuilder.java
index 74f9c3c..cc16acd 100644
---
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/TSEncodingBuilder.java
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/TSEncodingBuilder.java
@@ -70,6 +70,12 @@ public abstract class TSEncodingBuilder {
return new GorillaV2();
case DICTIONARY:
return new Dictionary();
+ case RAKE:
+ return new Rake();
+ case SPRINTZ:
+ return new Sprintz();
+ case RLBE:
+ return new RLBE();
default:
throw new UnsupportedOperationException(type.toString());
}
@@ -314,4 +320,74 @@ public abstract class TSEncodingBuilder {
// do nothing
}
}
+
+ public static class Rake extends TSEncodingBuilder {
+
+ @Override
+ public Encoder getEncoder(TSDataType type) {
+ switch (type) {
+ case FLOAT:
+ return new FloatRAKEEncoder();
+ case DOUBLE:
+ return new DoubleRAKEEncoder();
+ case INT32:
+ return new IntRAKEEncoder();
+ case INT64:
+ return new LongRAKEEncoder();
+ default:
+ throw new UnSupportedDataTypeException("Rake doesn't support data
type: " + type);
+ }
+ }
+
+ @Override
+ public void initFromProps(Map<String, String> props) {
+ // do nothing
+ }
+ }
+
+ public static class Sprintz extends TSEncodingBuilder {
+ @Override
+ public Encoder getEncoder(TSDataType type) {
+ switch (type) {
+ case INT32:
+ return new IntSprintzEncoder();
+ case INT64:
+ return new LongSprintzEncoder();
+ case FLOAT:
+ return new FloatSprintzEncoder();
+ case DOUBLE:
+ return new DoubleSprintzEncoder();
+ default:
+ throw new UnSupportedDataTypeException("Sprintz doesn't support data
type: " + type);
+ }
+ }
+
+ @Override
+ public void initFromProps(Map<String, String> props) {
+ // do nothing
+ }
+ }
+
+ public static class RLBE extends TSEncodingBuilder {
+ @Override
+ public Encoder getEncoder(TSDataType type) {
+ switch (type) {
+ case INT32:
+ return new IntRLBE();
+ case INT64:
+ return new LongRLBE();
+ case FLOAT:
+ return new FloatRLBE();
+ case DOUBLE:
+ return new DoubleRLBE();
+ default:
+ throw new UnSupportedDataTypeException("RLBE doesn't support data
type: " + type);
+ }
+ }
+
+ @Override
+ public void initFromProps(Map<String, String> props) {
+ // do nothing
+ }
+ }
}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/fire/Fire.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/fire/Fire.java
new file mode 100644
index 0000000..c9049b4
--- /dev/null
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/fire/Fire.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.fire;
+
+/**
+ * This class is used for Fast Integer REgression in Sprintz encoding
method.Users can create a Fire
+ * object and use it to train and predict the time-ordered integer-like data.
+ */
+public abstract class Fire<T extends Comparable<T>> {
+ // Learning rate by binary shift
+ protected int learnShift;
+ // the bit width of the data to be predicted
+ protected int bitWidth;
+ // accumulate the regression loss
+ protected int accumulator;
+ // store the difference of predicted value and the real value temporarily
+ protected T delta;
+
+ public Fire(int learning_rate) {
+ learnShift = learning_rate;
+ }
+
+ /**
+ * predict the incoming integer using the last value
+ *
+ * @param value the last value
+ * @return the predicted value
+ */
+ public abstract T predict(T value);
+
+ /**
+ * train the learning machine with the last prediction
+ *
+ * @param pre last value to be predicted
+ * @param val current value to be predicted
+ * @param err the predictive error of current value
+ */
+ public abstract void train(T pre, T val, T err);
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/fire/IntFire.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/fire/IntFire.java
new file mode 100644
index 0000000..9744ce6
--- /dev/null
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/fire/IntFire.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.fire;
+
+public class IntFire extends Fire<Integer> {
+
+ public IntFire(int learning_rate) {
+ super(learning_rate);
+ bitWidth = 8;
+ accumulator = 0;
+ delta = 0;
+ }
+
+ public void reset() {
+ accumulator = 0;
+ delta = 0;
+ }
+
+ @Override
+ public Integer predict(Integer value) {
+ // calculate the parameter alpha
+ int alpha = accumulator >> learnShift;
+ // calculate the Incremental of last value in current prediction
+ int diff = (alpha * delta) >> bitWidth;
+ return value + diff;
+ }
+
+ @Override
+ public void train(Integer pre, Integer val, Integer err) {
+ // update the gradient of learning machine.
+ int gradient = err > 0 ? -delta : delta;
+ accumulator -= gradient;
+ delta = val - pre;
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/fire/LongFire.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/fire/LongFire.java
new file mode 100644
index 0000000..0429bb3
--- /dev/null
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/fire/LongFire.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.iotdb.tsfile.encoding.fire;
+
+public class LongFire extends Fire<Long> {
+ public LongFire(int learning_rate) {
+ super(learning_rate);
+ bitWidth = 16;
+ accumulator = 0;
+ delta = 0L;
+ }
+
+ public void reset() {
+ accumulator = 0;
+ delta = 0L;
+ }
+
+ @Override
+ public Long predict(Long value) {
+ long alpha = accumulator >> learnShift;
+ long diff = (alpha * delta) >> bitWidth;
+ return value + diff;
+ }
+
+ @Override
+ public void train(Long pre, Long val, Long err) {
+ long gradient = err > 0 ? -delta : delta;
+ accumulator -= gradient;
+ delta = val - pre;
+ }
+}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/enums/TSEncoding.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/enums/TSEncoding.java
index de95fac..f6f029d 100644
---
a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/enums/TSEncoding.java
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/enums/TSEncoding.java
@@ -27,7 +27,10 @@ public enum TSEncoding {
BITMAP((byte) 5),
GORILLA_V1((byte) 6),
REGULAR((byte) 7),
- GORILLA((byte) 8);
+ GORILLA((byte) 8),
+ SPRINTZ((byte) 9),
+ RAKE((byte) 10),
+ RLBE((byte) 11);
private final byte type;
@@ -65,6 +68,12 @@ public enum TSEncoding {
return TSEncoding.REGULAR;
case 8:
return TSEncoding.GORILLA;
+ case 9:
+ return TSEncoding.SPRINTZ;
+ case 10:
+ return TSEncoding.RAKE;
+ case 11:
+ return TSEncoding.RLBE;
default:
throw new IllegalArgumentException("Invalid input: " + encoding);
}
diff --git
a/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/ReadWriteForEncodingUtils.java
b/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/ReadWriteForEncodingUtils.java
index b9d562b..924220f 100644
---
a/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/ReadWriteForEncodingUtils.java
+++
b/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/ReadWriteForEncodingUtils.java
@@ -47,6 +47,15 @@ public class ReadWriteForEncodingUtils {
return max;
}
+ public static int getIntMaxBitWidth(int[] list, int size) {
+ int max = 1;
+ for (int i = 0; i < size; i++) {
+ int bitWidth = 32 - Integer.numberOfLeadingZeros(list[i]);
+ max = Math.max(bitWidth, max);
+ }
+ return max;
+ }
+
/**
* check all number in a long list and find max bit width.
*
@@ -62,6 +71,15 @@ public class ReadWriteForEncodingUtils {
return max;
}
+ public static int getLongMaxBitWidth(long[] list, int size) {
+ int max = 1;
+ for (int i = 0; i < size; i++) {
+ int bitWidth = 64 - Long.numberOfLeadingZeros(list[i]);
+ max = Math.max(bitWidth, max);
+ }
+ return max;
+ }
+
/** transform an int var to byte[] format. */
public static byte[] getUnsignedVarInt(int value) {
int preValue = value;