You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by le...@apache.org on 2022/10/10 08:25:22 UTC
[iotdb] 01/03: width 8 multiple faster, otherwise no
This is an automated email from the ASF dual-hosted git repository.
leirui pushed a commit to branch research/M4-visualization
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 082283ef4d16721c27d7a8eb48f3225eb3aabcb2
Author: Lei Rui <10...@qq.com>
AuthorDate: Mon Oct 10 15:39:59 2022 +0800
width 8 multiple faster, otherwise no
---
.../iotdb/session/MyBasicOperationTest2.java | 16 +-
...rationTest2.java => MyBasicOperationTest3.java} | 57 +++---
.../session/MyRealDataTest1_WriteAndQuery.java | 94 ++++-----
.../tsfile/common/constant/TsFileConstant.java | 26 ++-
.../encoding/decoder/DeltaBinaryDecoder.java | 42 ++--
.../org/apache/iotdb/tsfile/utils/BytesUtils.java | 211 +++++++++++++--------
6 files changed, 272 insertions(+), 174 deletions(-)
diff --git a/session/src/test/java/org/apache/iotdb/session/MyBasicOperationTest2.java b/session/src/test/java/org/apache/iotdb/session/MyBasicOperationTest2.java
index eed2b00e6e..819054b5e4 100644
--- a/session/src/test/java/org/apache/iotdb/session/MyBasicOperationTest2.java
+++ b/session/src/test/java/org/apache/iotdb/session/MyBasicOperationTest2.java
@@ -11,7 +11,7 @@ public class MyBasicOperationTest2 {
// op1: long v = BytesUtils.bytesToLong(deltaBuf, packWidth * i, packWidth);
// op2: put bytes as a whole into long
- int repeat = 1000000;
+ int repeat = 1;
DescriptiveStatistics op1 = new DescriptiveStatistics();
DescriptiveStatistics op2 = new DescriptiveStatistics();
for (int k = 0; k < repeat; k++) {
@@ -19,7 +19,7 @@ public class MyBasicOperationTest2 {
Random r = new Random();
int low = 0; // inclusive
int high = 256; // exclusive
- int packNum = 128;
+ int packNum = 2;
int packWidth = 8; // equal to one byte length
byte[] buf = new byte[packNum];
for (int i = 0; i < packNum; i++) {
@@ -32,7 +32,7 @@ public class MyBasicOperationTest2 {
long start = System.nanoTime();
for (int i = 0; i < packNum; i++) {
sum += BytesUtils.bytesToLong(buf, packWidth * i, packWidth);
-// System.out.println(BytesUtils.bytesToLong(buf, packWidth * i, packWidth));
+ System.out.println(BytesUtils.bytesToLong(buf, packWidth * i, packWidth));
}
long elapsedTime = System.nanoTime() - start;
System.out.println(elapsedTime / 1000.0 + "us");
@@ -47,7 +47,7 @@ public class MyBasicOperationTest2 {
sum += (buf[i] & 0xff) << 8; // &0xff is to convert bytes to unsigned bytes
// op2_b: 把一个byte的高位x个比特装到一个long的低位x个比特
// TODO 如何把一个byte一次分成高位x个比特和低位y个比特
-// System.out.println("---");
+ System.out.println("---");
// System.out.println(buf[i]);
// System.out.println((buf[i] & 0xff & 0b11100000) >> 5);
sum += (buf[i] & 0xff & 0b11100000) >> 5;
@@ -55,6 +55,14 @@ public class MyBasicOperationTest2 {
// op2_c: 把一个byte的低位y个比特装到一个long的从低位到高位pos=packWidth-1的开始
// System.out.println((buf[i] & 0xff & ~0b11100000) << 3);
sum += (buf[i] & 0xff & ~0b11100000) << 3;
+
+ // op2_d: 把一个byte里的一部分比特装到一个long里
+ int oneNum = 2;
+ int mask = (int) Math.pow(2, oneNum) - 1;
+ int shift = 4;
+ mask = mask << shift; // 0b00110000
+ System.out.println(mask);
+ System.out.println((buf[i] & 0xff & mask) >> shift);
}
elapsedTime = System.nanoTime() - start;
System.out.println(elapsedTime / 1000.0 + "us");
diff --git a/session/src/test/java/org/apache/iotdb/session/MyBasicOperationTest2.java b/session/src/test/java/org/apache/iotdb/session/MyBasicOperationTest3.java
similarity index 66%
copy from session/src/test/java/org/apache/iotdb/session/MyBasicOperationTest2.java
copy to session/src/test/java/org/apache/iotdb/session/MyBasicOperationTest3.java
index eed2b00e6e..a281b1c117 100644
--- a/session/src/test/java/org/apache/iotdb/session/MyBasicOperationTest2.java
+++ b/session/src/test/java/org/apache/iotdb/session/MyBasicOperationTest3.java
@@ -3,15 +3,19 @@ package org.apache.iotdb.session;
import java.text.DecimalFormat;
import java.util.Random;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
+import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
import org.apache.iotdb.tsfile.utils.BytesUtils;
+import org.junit.Assert;
-public class MyBasicOperationTest2 {
+public class MyBasicOperationTest3 {
public static void main(String[] args) {
// op1: long v = BytesUtils.bytesToLong(deltaBuf, packWidth * i, packWidth);
- // op2: put bytes as a whole into long
+ // op2: put bytes as a whole into long, i.e., BytesUtils.bytesToLong2(deltaBuf, packWidth * i, packWidth);
int repeat = 1000000;
+ int packNum = 128;
+ int packWidth = 2;
DescriptiveStatistics op1 = new DescriptiveStatistics();
DescriptiveStatistics op2 = new DescriptiveStatistics();
for (int k = 0; k < repeat; k++) {
@@ -19,52 +23,51 @@ public class MyBasicOperationTest2 {
Random r = new Random();
int low = 0; // inclusive
int high = 256; // exclusive
- int packNum = 128;
- int packWidth = 8; // equal to one byte length
- byte[] buf = new byte[packNum];
+ byte[] buf = new byte[packNum * 8];
for (int i = 0; i < packNum; i++) {
- int v = r.nextInt(high - low) + low;
+// int v = r.nextInt(high - low) + low;
+ int v = 187;
BytesUtils.longToBytes(v, buf, i * packWidth, packWidth);
}
// test op1
- long sum = 0;
+ long[] value1 = new long[packNum];
long start = System.nanoTime();
for (int i = 0; i < packNum; i++) {
- sum += BytesUtils.bytesToLong(buf, packWidth * i, packWidth);
+ value1[i] = BytesUtils.bytesToLong(buf, packWidth * i, packWidth);
// System.out.println(BytesUtils.bytesToLong(buf, packWidth * i, packWidth));
}
long elapsedTime = System.nanoTime() - start;
- System.out.println(elapsedTime / 1000.0 + "us");
- System.out.println(sum);
+// System.out.println(elapsedTime / 1000.0 + "us");
+// System.out.println(sum);
op1.addValue(elapsedTime / 1000.0);
// test op2
- sum = 0;
+ long[] value2 = new long[packNum];
start = System.nanoTime();
for (int i = 0; i < packNum; i++) {
- // op2_a: 把一个byte装到一个long里从低位到高位偏移offset,又即byte的最低位在long中的pos(从低到高从0开始数)
- sum += (buf[i] & 0xff) << 8; // &0xff is to convert bytes to unsigned bytes
- // op2_b: 把一个byte的高位x个比特装到一个long的低位x个比特
- // TODO 如何把一个byte一次分成高位x个比特和低位y个比特
-// System.out.println("---");
-// System.out.println(buf[i]);
-// System.out.println((buf[i] & 0xff & 0b11100000) >> 5);
- sum += (buf[i] & 0xff & 0b11100000) >> 5;
-
- // op2_c: 把一个byte的低位y个比特装到一个long的从低位到高位pos=packWidth-1的开始
-// System.out.println((buf[i] & 0xff & ~0b11100000) << 3);
- sum += (buf[i] & 0xff & ~0b11100000) << 3;
+ value2[i] = BytesUtils.bytesToLong2(buf, packWidth * i, packWidth);
+// System.out.println(BytesUtils.bytesToLong2(buf, packWidth * i, packWidth));
+// Assert.assertEquals(value1[i], value2[i]);
}
elapsedTime = System.nanoTime() - start;
- System.out.println(elapsedTime / 1000.0 + "us");
- System.out.println(sum);
+// System.out.println(elapsedTime / 1000.0 + "us");
+// System.out.println(sum2);
op2.addValue(elapsedTime / 1000.0);
+
+ System.out.println("---------------");
+ for (int i = 0; i < packNum; i++) {
+ Assert.assertEquals(value1[i], value2[i]);
+ }
}
- printStat(op1, "op1-convertBitToLong");
- printStat(op2, "op2-compareByte");
+ printStat(op1, "op1-bytesToLong");
+ printStat(op2, "op2-bytesToLong2");
System.out.println("op1/op2=" + op1.getMean() / op2.getMean());
System.out.println("op2/op1=" + op2.getMean() / op1.getMean());
+ System.out.println("repeat=" + repeat);
+ System.out.println("packNum=" + packNum);
+ System.out.println("packWidth=" + packWidth);
+ TsFileConstant.printByteToLongStatistics();
}
private static String printStat(DescriptiveStatistics statistics, String name) {
diff --git a/session/src/test/java/org/apache/iotdb/session/MyRealDataTest1_WriteAndQuery.java b/session/src/test/java/org/apache/iotdb/session/MyRealDataTest1_WriteAndQuery.java
index c6fa88c7a7..6024cd118a 100644
--- a/session/src/test/java/org/apache/iotdb/session/MyRealDataTest1_WriteAndQuery.java
+++ b/session/src/test/java/org/apache/iotdb/session/MyRealDataTest1_WriteAndQuery.java
@@ -53,29 +53,29 @@ public class MyRealDataTest1_WriteAndQuery {
private static final String queryFormat_UDF =
"select M4(%1$s,'tqs'='%3$d','tqe'='%4$d','w'='%5$d') from %2$s where time>=%3$d and time<%4$d";
- // private static String device = "root.game";
- // private static String measurement = "s6";
- // private static TSDataType tsDataType = TSDataType.INT64; // TSDataType.DOUBLE;
- // private static String timestamp_precision = "ns"; // ns, us, ms
- // private static long dataMinTime = 0;
- // private static long dataMaxTime = 617426057626L;
- // private static long total_time_length = dataMaxTime - dataMinTime;
- // private static int total_point_number = 1200000;
- // private static int iotdb_chunk_point_size = 100000;
- // private static long chunkAvgTimeLen = (long) Math
- // .ceil(total_time_length / Math.ceil(total_point_number * 1.0 / iotdb_chunk_point_size));
- // private static String filePath =
- //
- // "D:\\github\\m4-lsm\\M4-visualization-exp\\src\\main\\java\\org\\apache\\iotdb\\datasets\\BallSpeed.csv";
- // private static int deletePercentage = 0; // 0 means no deletes. 0-100
- // private static int deleteLenPercentage = 0; // 0-100 每次删除的时间长度,用chunkAvgTimeLen的百分比表示
- // private static int timeIdx = 0; // 时间戳idx,从0开始
- // private static int valueIdx = 1; // 值idx,从0开始
- // private static int w = 2;
- // private static long range = total_time_length;
- // private static boolean enableRegularityTimeDecode = true;
- // private static long regularTimeInterval = 511996L;
- // private static String approach = "mac"; // 选择查询执行算法: 1: MAC, 2: MOC, 3: CPV
+ private static String device = "root.game";
+ private static String measurement = "s6";
+ private static TSDataType tsDataType = TSDataType.INT64; // TSDataType.DOUBLE;
+ private static String timestamp_precision = "ns"; // ns, us, ms
+ private static long dataMinTime = 0;
+ private static long dataMaxTime = 617426057626L;
+ private static long total_time_length = dataMaxTime - dataMinTime;
+ private static int total_point_number = 1200000;
+ private static int iotdb_chunk_point_size = 100000;
+ private static long chunkAvgTimeLen = (long) Math
+ .ceil(total_time_length / Math.ceil(total_point_number * 1.0 / iotdb_chunk_point_size));
+ private static String filePath =
+
+ "D:\\github\\m4-lsm\\M4-visualization-exp\\src\\main\\java\\org\\apache\\iotdb\\datasets\\BallSpeed.csv";
+ private static int deletePercentage = 0; // 0 means no deletes. 0-100
+ private static int deleteLenPercentage = 0; // 0-100 每次删除的时间长度,用chunkAvgTimeLen的百分比表示
+ private static int timeIdx = 0; // 时间戳idx,从0开始
+ private static int valueIdx = 1; // 值idx,从0开始
+ private static int w = 2;
+ private static long range = total_time_length;
+ private static boolean enableRegularityTimeDecode = false;
+ private static long regularTimeInterval = 511996L;
+ private static String approach = "mac"; // 选择查询执行算法: 1: MAC, 2: MOC, 3: CPV
// private static String device = "root.debs2012";
// private static String measurement = "mf03";
@@ -101,30 +101,30 @@ public class MyRealDataTest1_WriteAndQuery {
// private static long regularTimeInterval = 10000900L;
// private static String approach = "mac"; // 选择查询执行算法: 1: MAC, 2: MOC, 3: CPV
- private static String device = "root.debs2012";
- private static String measurement = "mf03";
- private static TSDataType tsDataType = TSDataType.INT64; // TSDataType.DOUBLE;
- private static String timestamp_precision = "ns"; // ns, us, ms
- private static long dataMinTime = 1329955200008000000L;
- private static long dataMaxTime = 1329965999991000000L;
- private static long total_time_length = dataMaxTime - dataMinTime;
- private static int total_point_number = 1076102;
- private static int iotdb_chunk_point_size = 100000;
- private static long chunkAvgTimeLen =
- (long)
- Math.ceil(
- total_time_length / Math.ceil(total_point_number * 1.0 / iotdb_chunk_point_size));
- private static String filePath =
- "D:\\github\\m4-lsm\\M4-visualization-exp\\src\\main\\java\\org\\apache\\iotdb\\datasets\\MF03_2.csv";
- private static int deletePercentage = 0; // 0 means no deletes. 0-100
- private static int deleteLenPercentage = 0; // 0-100 每次删除的时间长度,用chunkAvgTimeLen的百分比表示
- private static int timeIdx = 0; // 时间戳idx,从0开始
- private static int valueIdx = 1; // 值idx,从0开始
- private static int w = 2;
- private static long range = total_time_length;
- private static boolean enableRegularityTimeDecode = true;
- private static long regularTimeInterval = 10000000L;
- private static String approach = "mac"; // 选择查询执行算法: 1: MAC, 2: MOC, 3: CPV
+// private static String device = "root.debs2012";
+// private static String measurement = "mf03";
+// private static TSDataType tsDataType = TSDataType.INT64; // TSDataType.DOUBLE;
+// private static String timestamp_precision = "ns"; // ns, us, ms
+// private static long dataMinTime = 1329955200008000000L;
+// private static long dataMaxTime = 1329965999991000000L;
+// private static long total_time_length = dataMaxTime - dataMinTime;
+// private static int total_point_number = 1076102;
+// private static int iotdb_chunk_point_size = 100000;
+// private static long chunkAvgTimeLen =
+// (long)
+// Math.ceil(
+// total_time_length / Math.ceil(total_point_number * 1.0 / iotdb_chunk_point_size));
+// private static String filePath =
+// "D:\\github\\m4-lsm\\M4-visualization-exp\\src\\main\\java\\org\\apache\\iotdb\\datasets\\MF03_2.csv";
+// private static int deletePercentage = 0; // 0 means no deletes. 0-100
+// private static int deleteLenPercentage = 0; // 0-100 每次删除的时间长度,用chunkAvgTimeLen的百分比表示
+// private static int timeIdx = 0; // 时间戳idx,从0开始
+// private static int valueIdx = 1; // 值idx,从0开始
+// private static int w = 2;
+// private static long range = total_time_length;
+// private static boolean enableRegularityTimeDecode = true;
+// private static long regularTimeInterval = 10000000L;
+// private static String approach = "mac"; // 选择查询执行算法: 1: MAC, 2: MOC, 3: CPV
// private static String device = "root.kobelco.trans.03.1090001603.2401604";
// private static String measurement = "KOB_0002_00_67";
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/common/constant/TsFileConstant.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/common/constant/TsFileConstant.java
index 75be680e75..bb9492fdb2 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/common/constant/TsFileConstant.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/common/constant/TsFileConstant.java
@@ -53,5 +53,29 @@ public class TsFileConstant {
public static DescriptiveStatistics prepareAllRegulars = new DescriptiveStatistics();
- private TsFileConstant() {}
+ public static long bytesToLong_byteNum1_wholeByte = 0;
+ public static long bytesToLong_byteNum1_smallByte = 0;
+ public static long byteToLong_byteNums_firstByte_wholeByte = 0;
+ public static long byteToLong_byteNums_firstByte_smallByte = 0;
+ public static long byteToLong_byteNums_lastByte_wholeByte = 0;
+ public static long byteToLong_byteNums_lastByte_smallByte = 0;
+ public static long byteToLong_byteNums_middleWholeByte = 0;
+
+ private TsFileConstant() {
+ }
+
+ public static void printByteToLongStatistics() {
+ System.out.println("bytesToLong_byteNum1_wholeByte=" + bytesToLong_byteNum1_wholeByte);
+ System.out.println("bytesToLong_byteNum1_smallByte=" + bytesToLong_byteNum1_smallByte);
+ System.out.println(
+ "byteToLong_byteNums_firstByte_wholeByte=" + byteToLong_byteNums_firstByte_wholeByte);
+ System.out.println(
+ "byteToLong_byteNums_firstByte_smallByte=" + byteToLong_byteNums_firstByte_smallByte);
+ System.out.println(
+ "byteToLong_byteNums_lastByte_wholeByte=" + byteToLong_byteNums_lastByte_wholeByte);
+ System.out.println(
+ "byteToLong_byteNums_lastByte_smallByte=" + byteToLong_byteNums_lastByte_smallByte);
+ System.out
+ .println("byteToLong_byteNums_middleWholeByte=" + byteToLong_byteNums_middleWholeByte);
+ }
}
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DeltaBinaryDecoder.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DeltaBinaryDecoder.java
index 4f91f0b589..e799d33268 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DeltaBinaryDecoder.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DeltaBinaryDecoder.java
@@ -19,6 +19,10 @@
package org.apache.iotdb.tsfile.encoding.decoder;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
import org.apache.iotdb.tsfile.encoding.encoder.DeltaBinaryEncoder;
@@ -27,15 +31,9 @@ import org.apache.iotdb.tsfile.utils.BytesUtils;
import org.apache.iotdb.tsfile.utils.Pair;
import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map;
-
/**
* This class is a decoder for decoding the byte array that encoded by {@code
- * DeltaBinaryEncoder}.DeltaBinaryDecoder just supports integer and long values.<br>
- * .
+ * DeltaBinaryEncoder}.DeltaBinaryDecoder just supports integer and long values.<br> .
*
* @see DeltaBinaryEncoder
*/
@@ -44,16 +42,24 @@ public abstract class DeltaBinaryDecoder extends Decoder {
protected long count = 0;
protected byte[] deltaBuf;
- /** the first value in one pack. */
+ /**
+ * the first value in one pack.
+ */
protected int readIntTotalCount = 0;
protected int nextReadIndex = 0;
- /** max bit length of all value in a pack. */
+ /**
+ * max bit length of all value in a pack.
+ */
protected int packWidth;
- /** data number in this pack. */
+ /**
+ * data number in this pack.
+ */
protected int packNum;
- /** how many bytes data takes after encoding. */
+ /**
+ * how many bytes data takes after encoding.
+ */
protected int encodingLength;
public DeltaBinaryDecoder() {
@@ -86,7 +92,9 @@ public abstract class DeltaBinaryDecoder extends Decoder {
private int firstValue;
private int[] data;
private int previous;
- /** minimum value for all difference. */
+ /**
+ * minimum value for all difference.
+ */
private int minDeltaBase;
public IntDeltaDecoder() {
@@ -170,7 +178,9 @@ public abstract class DeltaBinaryDecoder extends Decoder {
private long firstValue;
private long[] data;
private long previous;
- /** minimum value for all difference. */
+ /**
+ * minimum value for all difference.
+ */
private long minDeltaBase;
private boolean enableRegularityTimeDecode;
@@ -239,7 +249,7 @@ public abstract class DeltaBinaryDecoder extends Decoder {
}
} else if (newRegularDelta < 0
|| newRegularDelta
- >= Math.pow(2, packWidth)) { // no need to compare equality cause impossible
+ >= Math.pow(2, packWidth)) { // no need to compare equality cause impossible
for (int i = 0; i < packNum; i++) {
long v = BytesUtils.bytesToLong(deltaBuf, packWidth * i, packWidth);
data[i] = previous + minDeltaBase + v;
@@ -267,6 +277,8 @@ public abstract class DeltaBinaryDecoder extends Decoder {
if (newRegularDelta != 0) {
// otherwise newRegularDelta=0 so leave byteArray as initial zeros
+ // TODO consider if these steps can be accelerated
+
// put bit-packed newRegularDelta starting at position i,
// and pad the front and back with newRegularDeltas
// 1. deal with padding the first byte
@@ -345,7 +357,7 @@ public abstract class DeltaBinaryDecoder extends Decoder {
// System.out.println("[RL]equals");
// TsFileConstant.countForRegularEqual++;
} else {
- long v = BytesUtils.bytesToLong(deltaBuf, packWidth * i, packWidth);
+ long v = BytesUtils.bytesToLong2(deltaBuf, packWidth * i, packWidth);
data[i] = previous + minDeltaBase + v;
// System.out.println("[RL]no");
// TsFileConstant.countForRegularNOTEqual++;
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/BytesUtils.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/BytesUtils.java
index 622b228731..49dee499e8 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/BytesUtils.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/BytesUtils.java
@@ -18,26 +18,24 @@
*/
package org.apache.iotdb.tsfile.utils;
-import org.apache.iotdb.tsfile.common.conf.TSFileConfig;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
+import org.apache.iotdb.tsfile.common.conf.TSFileConfig;
+import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* BytesUtils is a utility class. It provide conversion among byte array and other type including
- * integer, long, float, boolean, double and string. <br>
- * It also provide other usable function as follow:<br>
- * reading function which receives InputStream. <br>
- * concat function to join a list of byte array to one.<br>
- * get and set one bit in a byte array.
+ * integer, long, float, boolean, double and string. <br> It also provide other usable function as
+ * follow:<br> reading function which receives InputStream. <br> concat function to join a list of
+ * byte array to one.<br> get and set one bit in a byte array.
*/
public class BytesUtils {
- private BytesUtils() {}
+ private BytesUtils() {
+ }
private static final Logger LOG = LoggerFactory.getLogger(BytesUtils.class);
@@ -48,19 +46,20 @@ public class BytesUtils {
* @return byte[4] for integer
*/
public static byte[] intToBytes(int i) {
- return new byte[] {
- (byte) ((i >> 24) & 0xFF),
- (byte) ((i >> 16) & 0xFF),
- (byte) ((i >> 8) & 0xFF),
- (byte) (i & 0xFF)
+ return new byte[]{
+ (byte) ((i >> 24) & 0xFF),
+ (byte) ((i >> 16) & 0xFF),
+ (byte) ((i >> 8) & 0xFF),
+ (byte) (i & 0xFF)
};
}
/**
- * integer convert to byte array, then write four bytes to parameter desc start from index:offset.
+ * integer convert to byte array, then write four bytes to parameter desc start from
+ * index:offset.
*
- * @param i integer to convert
- * @param desc byte array be written
+ * @param i integer to convert
+ * @param desc byte array be written
* @param offset position in desc byte array that conversion result should start
* @return byte array
*/
@@ -81,8 +80,8 @@ public class BytesUtils {
*
* @param srcNum input integer variable
* @param result byte array to convert
- * @param pos start position
- * @param width bit-width
+ * @param pos start position
+ * @param width bit-width
*/
public static void intToBytes(int srcNum, byte[] result, int pos, int width) {
int temp = 0;
@@ -160,7 +159,7 @@ public class BytesUtils {
/**
* convert four-bytes byte array cut from parameters to integer.
*
- * @param bytes source bytes which length should be greater than 4
+ * @param bytes source bytes which length should be greater than 4
* @param offset position in parameter byte array that conversion result should start
* @return integer
*/
@@ -182,8 +181,8 @@ public class BytesUtils {
* given a byte array, read width bits from specified position bits and convert it to an integer.
*
* @param result input byte array
- * @param pos bit offset rather than byte offset
- * @param width bit-width
+ * @param pos bit offset rather than byte offset
+ * @param width bit-width
* @return integer variable
*/
public static int bytesToInt(byte[] result, int pos, int width) {
@@ -217,8 +216,8 @@ public class BytesUtils {
/**
* float convert to boolean, then write four bytes to parameter desc start from index:offset.
*
- * @param x float
- * @param desc byte array be written
+ * @param x float
+ * @param desc byte array be written
* @param offset position in desc byte array that conversion result should start
*/
public static void floatToBytes(float x, byte[] desc, int offset) {
@@ -257,7 +256,7 @@ public class BytesUtils {
/**
* convert four-bytes byte array cut from parameters to float.
*
- * @param b source bytes which length should be greater than 4
+ * @param b source bytes which length should be greater than 4
* @param offset position in parameter byte array that conversion result should start
* @return float
*/
@@ -296,8 +295,8 @@ public class BytesUtils {
/**
* convert double to byte into the given byte array started from offset.
*
- * @param d input double
- * @param bytes target byte[]
+ * @param d input double
+ * @param bytes target byte[]
* @param offset start pos
*/
public static void doubleToBytes(double d, byte[] bytes, int offset) {
@@ -340,7 +339,7 @@ public class BytesUtils {
/**
* convert eight-bytes byte array cut from parameters to double.
*
- * @param bytes source bytes which length should be greater than 8
+ * @param bytes source bytes which length should be greater than 8
* @param offset position in parameter byte array that conversion result should start
* @return double
*/
@@ -395,10 +394,11 @@ public class BytesUtils {
}
/**
- * boolean convert to byte array, then write four bytes to parameter desc start from index:offset.
+ * boolean convert to byte array, then write four bytes to parameter desc start from
+ * index:offset.
*
- * @param x input boolean
- * @param desc byte array be written
+ * @param x input boolean
+ * @param desc byte array be written
* @param offset position in desc byte array that conversion result should start
* @return byte[1]
*/
@@ -428,7 +428,7 @@ public class BytesUtils {
/**
* convert one-bytes byte array cut from parameters to boolean.
*
- * @param b source bytes which length should be greater than 1
+ * @param b source bytes which length should be greater than 1
* @param offset position in parameter byte array that conversion result should start
* @return boolean
*/
@@ -452,10 +452,9 @@ public class BytesUtils {
/**
* specify the result array length. then, convert long to Big-Endian byte from low to high. <br>
- * e.g.<br>
- * the binary presentation of long number 1000L is {6 bytes equal 0000000} 00000011 11101000<br>
- * if len = 2, it will return byte array :{00000011 11101000}(Big-Endian) if len = 1, it will
- * return byte array :{11101000}.
+ * e.g.<br> the binary presentation of long number 1000L is {6 bytes equal 0000000} 00000011
+ * 11101000<br> if len = 2, it will return byte array :{00000011 11101000}(Big-Endian) if len = 1,
+ * it will return byte array :{11101000}.
*
* @param num long variable to be converted
* @param len length of result byte array
@@ -472,8 +471,8 @@ public class BytesUtils {
/**
* long convert to byte array, then write four bytes to parameter desc start from index:offset.
*
- * @param num input long variable
- * @param desc byte array be written
+ * @param num input long variable
+ * @param desc byte array be written
* @param offset position in desc byte array that conversion result should start
* @return byte array
*/
@@ -491,8 +490,8 @@ public class BytesUtils {
*
* @param srcNum input long variable
* @param result byte array to convert
- * @param pos start position
- * @param width bit-width
+ * @param pos start position
+ * @param width bit-width
*/
public static void longToBytes(long srcNum, byte[] result, int pos, int width) {
int temp = 0;
@@ -524,12 +523,11 @@ public class BytesUtils {
/**
* specify the input byte array length. then, convert byte array to long value from low to high.
* <br>
- * e.g.<br>
- * the input byte array is {00000011 11101000}. if len = 2, return 1000 if len = 1, return
- * 232(only calculate the low byte).
+ * e.g.<br> the input byte array is {00000011 11101000}. if len = 2, return 1000 if len = 1,
+ * return 232(only calculate the low byte).
*
* @param byteNum byte array to be converted
- * @param len length of input byte array to be converted
+ * @param len length of input byte array to be converted
* @return long
*/
public static long bytesToLong(byte[] byteNum, int len) {
@@ -545,8 +543,8 @@ public class BytesUtils {
* given a byte array, read width bits from specified pos bits and convert it to an long.
*
* @param result input byte array
- * @param pos bit offset rather than byte offset
- * @param width bit-width
+ * @param pos bit offset rather than byte offset
+ * @param width bit-width
* @return long variable
*/
public static long bytesToLong(byte[] result, int pos, int width) {
@@ -563,28 +561,85 @@ public class BytesUtils {
* given a byte array, read width bits from specified pos bits and convert it to an long.
*
* @param result input byte array
- * @param pos bit offset rather than byte offset
- * @param width bit-width
+ * @param pos bit offset rather than byte offset
+ * @param width bit-width
* @return long variable
*/
public static long bytesToLong2(byte[] result, int pos, int width) {
- long value = 0;
-// int temp = 0;
-// for (int i = 0; i < width; i++) {
-// temp = (pos + width - 1 - i) / 8;
-// value = setLongN(value, i, getByteN(result[temp], pos + width - 1 - i));
-// }
- //TODO new implementation
+ // pos is global over the byte array, from low to high, starting from 0
+ // TODO new implementation
+ if (width == 0) {
+ return 0;
+ }
+
+ int endPos = pos + width - 1;
+ int startByte = pos / 8;
+ int endByte = endPos / 8;
+ int byteNum = endByte - startByte + 1;
+ int startPosInByte = pos % 8; // in a byte from high to low bits starting from 0
+ int endPosInByte = endPos % 8;
+
+ // TODO if in the same byte
+ if (byteNum == 1) {
+ if (endPosInByte - startPosInByte == 7) {
+ // put the whole byte into the long value
+ TsFileConstant.bytesToLong_byteNum1_wholeByte++;
+ return result[startByte] & 0xff;
+ } else {
+ // put bits in the byte from the global position pos to pos+width-1 into the long value
+ TsFileConstant.bytesToLong_byteNum1_smallByte++;
+ int mask = (int) Math.pow(2, 8 - width) - 1; // TODO consider if this to make static
+ mask = (~mask & 0xff) >> startPosInByte;
+ return (result[startByte] & 0xff & mask) >> (7 - endPosInByte);
+ }
+ }
+ // TODO if across two bytes
+ else {
+ long value = 0;
+ // 1. deal with the first byte
+ int shift = width - (8 - startPosInByte);
+ if (startPosInByte == 0) {
+ // put the whole byte into the long value's front place among the last width bits
+ TsFileConstant.byteToLong_byteNums_firstByte_wholeByte++;
+ value = value | ((result[startByte] & 0xff) << shift);
+ } else {
+ // put the bits in the first byte from relative position pos%8 to the end into the long value's front place among the last width bits
+ TsFileConstant.byteToLong_byteNums_firstByte_smallByte++;
+ int mask =
+ (int) Math.pow(2, 8 - startPosInByte) - 1; // TODO consider if this to make static
+ value = value | ((result[startByte] & 0xff & mask) << shift);
+ }
+
+ // 2. deal with the last byte
+ if (endPosInByte == 7) {
+ // put the whole byte into the long value's back place among the last width bits
+ TsFileConstant.byteToLong_byteNums_lastByte_wholeByte++;
+ value = value | (result[endByte] & 0xff);
+ } else {
+ // put the bits in the last byte from relative position 0 to (pos+width-1)%8 into the long value's back place among the last width bits
+ TsFileConstant.byteToLong_byteNums_lastByte_smallByte++;
+ int mask =
+ (int) Math.pow(2, 7 - endPosInByte) - 1; // TODO consider if this to make static
+ value = value | ((result[endByte] & 0xff & ~mask) >> (7 - endPosInByte));
+ }
+
+ // 3. deal with the middle bytes
+ for (int k = startByte + 1; k < endByte; k++) {
+ TsFileConstant.byteToLong_byteNums_middleWholeByte++;
+ shift -= 8;
+ value = value | ((result[k] & 0xff) << shift);
+ }
+ return value;
+ }
- return value;
}
/**
* convert eight-bytes byte array cut from parameters to long.
*
* @param byteNum source bytes which length should be greater than 8
- * @param len length of input byte array to be converted
- * @param offset position in parameter byte array that conversion result should start
+ * @param len length of input byte array to be converted
+ * @param offset position in parameter byte array that conversion result should start
* @return long
*/
public static long bytesToLongFromOffset(byte[] byteNum, int len, int offset) {
@@ -658,8 +713,8 @@ public class BytesUtils {
/**
* cut out specified length byte array from parameter start from input byte array src and return.
*
- * @param src input byte array
- * @param start start index of src
+ * @param src input byte array
+ * @param start start index of src
* @param length cut off length
* @return byte array
*/
@@ -676,12 +731,11 @@ public class BytesUtils {
}
/**
- * get one bit in input integer. the offset is from low to high and start with 0<br>
- * e.g.<br>
+ * get one bit in input integer. the offset is from low to high and start with 0<br> e.g.<br>
* data:1000(00000000 00000000 00000011 11101000), if offset is 4, return 0(111 "0" 1000) if
* offset is 9, return 1(00000 "1" 1 11101000).
*
- * @param data input int variable
+ * @param data input int variable
* @param offset bit offset
* @return 0 or 1
*/
@@ -696,14 +750,13 @@ public class BytesUtils {
/**
* set one bit in input integer. the offset is from low to high and start with index 0<br>
- * e.g.<br>
- * data:1000({00000000 00000000 00000011 11101000}), if offset is 4, value is 1, return
+ * e.g.<br> data:1000({00000000 00000000 00000011 11101000}), if offset is 4, value is 1, return
* 1016({00000000 00000000 00000011 111 "1" 1000}) if offset is 9, value is 0 return 488({00000000
* 00000000 000000 "0" 1 11101000}) if offset is 0, value is 0 return 1000(no change).
*
- * @param data input int variable
+ * @param data input int variable
* @param offset bit offset
- * @param value value to set
+ * @param value value to set
* @return int variable
*/
public static int setIntN(int data, int offset, int value) {
@@ -716,12 +769,11 @@ public class BytesUtils {
}
/**
- * get one bit in input byte. the offset is from low to high and start with 0<br>
- * e.g.<br>
+ * get one bit in input byte. the offset is from low to high and start with 0<br> e.g.<br>
* data:16(00010000), if offset is 4, return 1(000 "1" 0000) if offset is 7, return 0("0"
* 0010000).
*
- * @param data input byte variable
+ * @param data input byte variable
* @param offset bit offset
* @return 0/1
*/
@@ -735,14 +787,13 @@ public class BytesUtils {
}
/**
- * set one bit in input byte. the offset is from low to high and start with index 0<br>
- * e.g.<br>
+ * set one bit in input byte. the offset is from low to high and start with index 0<br> e.g.<br>
* data:16(00010000), if offset is 4, value is 0, return 0({000 "0" 0000}) if offset is 1, value
* is 1, return 18({00010010}) if offset is 0, value is 0, return 16(no change).
*
- * @param data input byte variable
+ * @param data input byte variable
* @param offset bit offset
- * @param value value to set
+ * @param value value to set
* @return byte variable
*/
public static byte setByteN(byte data, int offset, int value) {
@@ -757,7 +808,7 @@ public class BytesUtils {
/**
* get one bit in input long. the offset is from low to high and start with 0.
*
- * @param data input long variable
+ * @param data input long variable
* @param offset bit offset
* @return 0/1
*/
@@ -773,9 +824,9 @@ public class BytesUtils {
/**
* set one bit in input long. the offset is from low to high and start with index 0.
*
- * @param data input long variable
+ * @param data input long variable
* @param offset bit offset
- * @param value value to set
+ * @param value value to set
* @return long variable
*/
public static long setLongN(long data, int offset, int value) {
@@ -851,7 +902,7 @@ public class BytesUtils {
* read bytes specified length from InputStream safely.
*
* @param count number of byte to read
- * @param in InputStream
+ * @param in InputStream
* @return byte array
* @throws IOException cannot read from InputStream
*/