|
@@ -16,6 +16,8 @@ import java.util.BitSet;
|
|
|
*/
|
|
|
public class LogBuffer {
|
|
|
|
|
|
+ static final BigDecimal DECIMAL_ZERO_1_SCALE = BigDecimal.valueOf(0, 1);
|
|
|
+ static final BigDecimal DECIMAL_ONE_1_SCALE = BigDecimal.valueOf(10, 1);
|
|
|
protected byte[] buffer;
|
|
|
|
|
|
protected int origin, limit;
|
|
@@ -1263,6 +1265,15 @@ public class LogBuffer {
|
|
|
throw new IllegalArgumentException("limit excceed: " + (position + binSize - origin));
|
|
|
}
|
|
|
|
|
|
+ if (precision <= 20 && intg <= 18 && frac <= 9) {
|
|
|
+ // use compact BigDecimal
|
|
|
+ BigDecimal compactDecimal = getBigDecimalCompact(precision, scale, intg, frac, intg0x);
|
|
|
+ if (compactDecimal != null) {
|
|
|
+ position += binSize;
|
|
|
+ return compactDecimal;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
BigDecimal decimal = getDecimal0(position, intg, frac, // NL
|
|
|
intg0,
|
|
|
frac0,
|
|
@@ -1272,6 +1283,162 @@ public class LogBuffer {
|
|
|
return decimal;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * use compact BigDecimal
|
|
|
+ */
|
|
|
+ private BigDecimal getBigDecimalCompact(int precision, int scale, int intg, int frac, int intg0x) {
|
|
|
+ if (precision > 20 || intg > 18 && frac > 9) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ BigDecimal compactDecimal = null;
|
|
|
+ long longValue = 0;
|
|
|
+ int small = 0;
|
|
|
+ int pos = position;
|
|
|
+ byte b0 = buffer[position];
|
|
|
+ final int mask = ((b0 & 0x80) == 0x80) ? 0 : -1;
|
|
|
+ b0 ^= 0x80;
|
|
|
+
|
|
|
+ switch (intg0x) {
|
|
|
+ case 0:
|
|
|
+ if (intg == 0) {
|
|
|
+ longValue = 0;
|
|
|
+ } else {
|
|
|
+ longValue = (b0 << 24)
|
|
|
+ | ((0xff & buffer[pos + 1]) << 16)
|
|
|
+ | ((0xff & buffer[pos + 2]) << 8)
|
|
|
+ | (0xff & buffer[pos + 3]);
|
|
|
+ longValue ^= mask;
|
|
|
+ pos += 4;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ case 2:
|
|
|
+ longValue = b0;
|
|
|
+ longValue ^= mask;
|
|
|
+ pos += 1;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ case 4:
|
|
|
+ longValue = (b0 << 8) | (0xff & buffer[pos + 1]);
|
|
|
+ longValue ^= mask;
|
|
|
+ pos += 2;
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ case 6:
|
|
|
+ longValue = (b0 << 16) | ((0xff & buffer[pos + 1]) << 8) | (0xff & buffer[pos + 2]);
|
|
|
+ longValue ^= mask;
|
|
|
+ pos += 3;
|
|
|
+ break;
|
|
|
+ case 7:
|
|
|
+ case 8:
|
|
|
+ longValue = (b0 << 24)
|
|
|
+ | ((0xff & buffer[pos + 1]) << 16)
|
|
|
+ | ((0xff & buffer[pos + 2]) << 8)
|
|
|
+ | (0xff & buffer[pos + 3]);
|
|
|
+ longValue ^= mask;
|
|
|
+ pos += 4;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (intg > 9) {
|
|
|
+ int value = getInt32BE(buffer, pos);
|
|
|
+ value ^= mask;
|
|
|
+ longValue *= 1_000_000_000;
|
|
|
+ longValue += value;
|
|
|
+ pos += 4;
|
|
|
+ }
|
|
|
+
|
|
|
+ int power = 1;
|
|
|
+ if (pos != position) {
|
|
|
+ b0 = buffer[pos];
|
|
|
+ }
|
|
|
+ switch (frac) {
|
|
|
+ case 0:
|
|
|
+ small = 0;
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ case 2:
|
|
|
+ power = frac == 1 ? 10 : 100;
|
|
|
+ small = b0;
|
|
|
+ small ^= mask;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ case 4:
|
|
|
+ power = frac == 3 ? 1_000 : 10_000;
|
|
|
+ small = (b0 << 8) | (0xff & buffer[pos + 1]);
|
|
|
+ small ^= mask;
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ case 6:
|
|
|
+ power = frac == 5 ? 100_000 : 1_000_000;
|
|
|
+ small = (b0 << 16) | ((0xff & buffer[pos + 1]) << 8) | (0xff & buffer[pos + 2]);
|
|
|
+ small ^= mask;
|
|
|
+ break;
|
|
|
+ case 7:
|
|
|
+ case 8:
|
|
|
+ case 9:
|
|
|
+ power = frac == 7 ? 10_000_000 : frac == 8 ? 100_000_000 : 1_000_000_000;
|
|
|
+ small = (b0 << 24)
|
|
|
+ | ((0xff & buffer[pos + 1]) << 16)
|
|
|
+ | ((0xff & buffer[pos + 2]) << 8)
|
|
|
+ | (0xff & buffer[pos + 3]);
|
|
|
+ small ^= mask;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (small == 0) {
|
|
|
+ if (frac == 0) {
|
|
|
+ if (mask != 0) {
|
|
|
+ longValue = -longValue;
|
|
|
+ }
|
|
|
+ compactDecimal = BigDecimal.valueOf(longValue, 0);
|
|
|
+ } else if (longValue == 0) {
|
|
|
+ if (scale < 9) {
|
|
|
+ compactDecimal = DECIMAL_ZERO_1_SCALE;
|
|
|
+ } else {
|
|
|
+ compactDecimal = BigDecimal.valueOf(longValue, scale);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (scale < 9) {
|
|
|
+ long unscaleValue = longValue * 10;
|
|
|
+ if (unscaleValue >= longValue) {
|
|
|
+ if (mask != 0) {
|
|
|
+ unscaleValue = -unscaleValue;
|
|
|
+ }
|
|
|
+ if (unscaleValue == 10) {
|
|
|
+ compactDecimal = DECIMAL_ONE_1_SCALE;
|
|
|
+ } else {
|
|
|
+ compactDecimal = BigDecimal.valueOf(unscaleValue, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ long unscaleValue = longValue * power;
|
|
|
+ if (unscaleValue >= longValue) {
|
|
|
+ if (mask != 0) {
|
|
|
+ unscaleValue = -unscaleValue;
|
|
|
+ }
|
|
|
+ compactDecimal = BigDecimal.valueOf(unscaleValue, scale);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ long unscaleValue = longValue * power + small;
|
|
|
+ if (unscaleValue >= longValue) {
|
|
|
+ if (mask != 0) {
|
|
|
+ unscaleValue = -unscaleValue;
|
|
|
+ }
|
|
|
+ compactDecimal = BigDecimal.valueOf(unscaleValue, scale);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return compactDecimal;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Return big decimal from buffer.
|
|
|
*
|
|
@@ -1445,8 +1612,9 @@ public class LogBuffer {
|
|
|
}
|
|
|
|
|
|
d_copy[begin] ^= 0x80; /* restore sign */
|
|
|
- String decimal = String.valueOf(buf, 0, pos);
|
|
|
- return new BigDecimal(decimal);
|
|
|
+ // String decimal = String.valueOf(buf, 0, pos);
|
|
|
+ // return new BigDecimal(decimal);
|
|
|
+ return new BigDecimal(buf, 0, pos);
|
|
|
}
|
|
|
|
|
|
/**
|