From 6429cc93f82952dc82099723b503c6a9bbe3bed6 Mon Sep 17 00:00:00 2001 From: redkale Date: Wed, 16 Oct 2024 20:50:59 +0800 Subject: [PATCH] json --- .../redkale/convert/json/JsonBytesWriter.java | 112 ++++++------------ .../redkale/convert/json/JsonCharsWriter.java | 111 ++++++----------- .../org/redkale/convert/json/JsonWriter.java | 35 ++++-- .../convert/json/_DyncUserJsonEncoder.java | 2 +- .../convert/json/_DyncWorldJsonEncoder.java | 2 +- 5 files changed, 99 insertions(+), 163 deletions(-) diff --git a/src/main/java/org/redkale/convert/json/JsonBytesWriter.java b/src/main/java/org/redkale/convert/json/JsonBytesWriter.java index 2de8590fc..333d36d5d 100644 --- a/src/main/java/org/redkale/convert/json/JsonBytesWriter.java +++ b/src/main/java/org/redkale/convert/json/JsonBytesWriter.java @@ -601,47 +601,26 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { count += bs.length; return; } - final byte sign = value >= 0 ? 0 : BYTE_NEGATIVE; - if (value < 0) { - value = -value; - } - int size; - for (int i = 0; ; i++) { - if (value <= sizeTable[i]) { - size = i + 1; - break; - } - } - if (sign != 0) { - size++; // 负数 - } + final boolean negative = value < 0; + int size = stringSize(value); byte[] bytes = expand(size); - - int q, r; int charPos = count + size; - + int i = negative ? value : -value; + int q, r; // Generate two digits per iteration - while (value >= 65536) { - q = value / 100; - // really: r = i - (q * 100); - r = value - ((q << 6) + (q << 5) + (q << 2)); - value = q; + while (i <= -100) { + q = i / 100; + r = (q * 100) - i; + i = q; bytes[--charPos] = (byte) DigitOnes[r]; bytes[--charPos] = (byte) DigitTens[r]; } - - // Fall thru to fast mode for smaller numbers - // assert(i <= 65536, i); - for (; ; ) { - q = (value * 52429) >>> (16 + 3); - r = value - ((q << 3) + (q << 1)); // r = i-(q*10) ... - bytes[--charPos] = (byte) digits[r]; - value = q; - if (value == 0) { - break; - } + // We know there are at most two digits left at this point. + bytes[--charPos] = (byte) DigitOnes[-i]; + if (i < -9) { + bytes[--charPos] = (byte) DigitTens[-i]; } - if (sign != 0) { + if (negative) { bytes[--charPos] = BYTE_NEGATIVE; } count += size; @@ -663,63 +642,38 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple { count += bs.length; return; } - final char sign = value >= 0 ? 0 : '-'; - if (value < 0) { - value = -value; - } - int size = 19; - long p = 10; - for (int i = 1; i < 19; i++) { - if (value < p) { - size = i; - break; - } - p = 10 * p; - } - if (sign != 0) { - size++; // 负数 - } + final boolean negative = value < 0; + int size = stringSize(value); byte[] bytes = expand(size); - + int charPos = count + size; + long i = negative ? value : -value; long q; int r; - int charPos = count + size; - - // Get 2 digits/iteration using longs until quotient fits into an int - while (value > Integer.MAX_VALUE) { - q = value / 100; - // really: r = i - (q * 100); - r = (int) (value - ((q << 6) + (q << 5) + (q << 2))); - value = q; - content[--charPos] = (byte) DigitOnes[r]; - content[--charPos] = (byte) DigitTens[r]; + while (i <= Integer.MIN_VALUE) { + q = i / 100; + r = (int) ((q * 100) - i); + i = q; + bytes[--charPos] = (byte) DigitOnes[r]; + bytes[--charPos] = (byte) DigitTens[r]; } - // Get 2 digits/iteration using ints int q2; - int i2 = (int) value; - while (i2 >= 65536) { + int i2 = (int) i; + while (i2 <= -100) { q2 = i2 / 100; - // really: r = i2 - (q * 100); - r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2)); + r = (q2 * 100) - i2; i2 = q2; bytes[--charPos] = (byte) DigitOnes[r]; bytes[--charPos] = (byte) DigitTens[r]; } - - // Fall thru to fast mode for smaller numbers - // assert(i2 <= 65536, i2); - for (; ; ) { - q2 = (i2 * 52429) >>> (16 + 3); - r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ... - bytes[--charPos] = (byte) digits[r]; - i2 = q2; - if (i2 == 0) { - break; - } + // We know there are at most two digits left at this point. + bytes[--charPos] = (byte) DigitOnes[-i2]; + if (i2 < -9) { + bytes[--charPos] = (byte) DigitTens[-i2]; } - if (sign != 0) { - bytes[--charPos] = (byte) sign; + + if (negative) { + bytes[--charPos] = BYTE_NEGATIVE; } count += size; } diff --git a/src/main/java/org/redkale/convert/json/JsonCharsWriter.java b/src/main/java/org/redkale/convert/json/JsonCharsWriter.java index 8c8fb476c..1e42218b6 100644 --- a/src/main/java/org/redkale/convert/json/JsonCharsWriter.java +++ b/src/main/java/org/redkale/convert/json/JsonCharsWriter.java @@ -10,8 +10,6 @@ import static org.redkale.convert.json.JsonWriter.BYTE_DQUOTE; import static org.redkale.convert.json.JsonWriter.DEFAULT_SIZE; import static org.redkale.convert.json.JsonWriter.DigitOnes; import static org.redkale.convert.json.JsonWriter.DigitTens; -import static org.redkale.convert.json.JsonWriter.digits; -import static org.redkale.convert.json.JsonWriter.sizeTable; import org.redkale.util.StringWrapper; import org.redkale.util.Utility; @@ -448,44 +446,28 @@ public class JsonCharsWriter extends JsonWriter { writeTo(TENTHOUSAND_CHARS2[-value]); return; } - final char sign = value >= 0 ? 0 : '-'; - if (value < 0) value = -value; - int size; - for (int i = 0; ; i++) { - if (value <= sizeTable[i]) { - size = i + 1; - break; - } - } - if (sign != 0) { - size++; // 负数 - } + final boolean negative = value < 0; + int size = stringSize(value); char[] chars = expand(size); - - int q, r; int charPos = count + size; - + int i = negative ? value : -value; + int q, r; // Generate two digits per iteration - while (value >= 65536) { - q = value / 100; - // really: r = i - (q * 100); - r = value - ((q << 6) + (q << 5) + (q << 2)); - value = q; + while (i <= -100) { + q = i / 100; + r = (q * 100) - i; + i = q; chars[--charPos] = DigitOnes[r]; chars[--charPos] = DigitTens[r]; } - - // Fall thru to fast mode for smaller numbers - // assert(i <= 65536, i); - for (; ; ) { - q = (value * 52429) >>> (16 + 3); - r = value - ((q << 3) + (q << 1)); // r = i-(q*10) ... - chars[--charPos] = digits[r]; - value = q; - if (value == 0) break; + // We know there are at most two digits left at this point. + chars[--charPos] = DigitOnes[-i]; + if (i < -9) { + chars[--charPos] = DigitTens[-i]; } - if (sign != 0) { - chars[--charPos] = sign; + + if (negative) { + chars[--charPos] = '-'; } count += size; } @@ -500,56 +482,39 @@ public class JsonCharsWriter extends JsonWriter { writeTo(TENTHOUSAND_CHARS2[(int) -value]); return; } - final char sign = value >= 0 ? 0 : '-'; - if (value < 0) value = -value; - int size = 19; - long p = 10; - for (int i = 1; i < 19; i++) { - if (value < p) { - size = i; - break; - } - p = 10 * p; - } - if (sign != 0) size++; // 负数 - expand(size); - + final boolean negative = value < 0; + int size = stringSize(value); + char[] chars = expand(size); + int charPos = count + size; + long i = negative ? value : -value; long q; int r; - int charPos = count + size; - - // Get 2 digits/iteration using longs until quotient fits into an int - while (value > Integer.MAX_VALUE) { - q = value / 100; - // really: r = i - (q * 100); - r = (int) (value - ((q << 6) + (q << 5) + (q << 2))); - value = q; - content[--charPos] = DigitOnes[r]; - content[--charPos] = DigitTens[r]; + while (i <= Integer.MIN_VALUE) { + q = i / 100; + r = (int) ((q * 100) - i); + i = q; + chars[--charPos] = DigitOnes[r]; + chars[--charPos] = DigitTens[r]; } - // Get 2 digits/iteration using ints int q2; - int i2 = (int) value; - while (i2 >= 65536) { + int i2 = (int) i; + while (i2 <= -100) { q2 = i2 / 100; - // really: r = i2 - (q * 100); - r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2)); + r = (q2 * 100) - i2; i2 = q2; - content[--charPos] = DigitOnes[r]; - content[--charPos] = DigitTens[r]; + chars[--charPos] = DigitOnes[r]; + chars[--charPos] = DigitTens[r]; + } + // We know there are at most two digits left at this point. + chars[--charPos] = DigitOnes[-i2]; + if (i2 < -9) { + chars[--charPos] = DigitTens[-i2]; } - // Fall thru to fast mode for smaller numbers - // assert(i2 <= 65536, i2); - for (; ; ) { - q2 = (i2 * 52429) >>> (16 + 3); - r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ... - content[--charPos] = digits[r]; - i2 = q2; - if (i2 == 0) break; + if (negative) { + chars[--charPos] = '-'; } - if (sign != 0) content[--charPos] = sign; count += size; } diff --git a/src/main/java/org/redkale/convert/json/JsonWriter.java b/src/main/java/org/redkale/convert/json/JsonWriter.java index 6f774ad7e..b736b3b35 100644 --- a/src/main/java/org/redkale/convert/json/JsonWriter.java +++ b/src/main/java/org/redkale/convert/json/JsonWriter.java @@ -362,14 +362,31 @@ public abstract class JsonWriter extends Writer { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; - static final char[] digits = { - '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', 'a', 'b', - 'c', 'd', 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z' - }; + protected static int stringSize(int x) { + int d = 1; + if (x >= 0) { + d = 0; + x = -x; + } + int p = -10; + for (int i = 1; i < 10; i++) { + if (x > p) return i + d; + p = 10 * p; + } + return 10 + d; + } - static final int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE}; + protected static int stringSize(long x) { + int d = 1; + if (x >= 0) { + d = 0; + x = -x; + } + long p = -10; + for (int i = 1; i < 19; i++) { + if (x > p) return i + d; + p = 10 * p; + } + return 19 + d; + } } diff --git a/src/test/java/org/redkale/test/convert/json/_DyncUserJsonEncoder.java b/src/test/java/org/redkale/test/convert/json/_DyncUserJsonEncoder.java index bd1e883fa..f3c9567aa 100644 --- a/src/test/java/org/redkale/test/convert/json/_DyncUserJsonEncoder.java +++ b/src/test/java/org/redkale/test/convert/json/_DyncUserJsonEncoder.java @@ -52,7 +52,7 @@ public class _DyncUserJsonEncoder extends JsonDynEncoder { comma = out.writeFieldLongValue(idFieldBytes, idFieldChars, comma, value.getId()); comma = out.writeFieldStringValue(nameFieldBytes, nameFieldChars, comma, value.getName()); comma = out.writeFieldStringValue(sexFieldBytes, sexFieldChars, comma, value.getSex()); - comma = out.writeFieldStringValue(nickNameFieldBytes, nickNameFieldChars, comma, value.getNickName()); + out.writeFieldStringValue(nickNameFieldBytes, nickNameFieldChars, comma, value.getNickName()); out.writeTo('}'); } } diff --git a/src/test/java/org/redkale/test/convert/json/_DyncWorldJsonEncoder.java b/src/test/java/org/redkale/test/convert/json/_DyncWorldJsonEncoder.java index d53fe1659..41ee56440 100644 --- a/src/test/java/org/redkale/test/convert/json/_DyncWorldJsonEncoder.java +++ b/src/test/java/org/redkale/test/convert/json/_DyncWorldJsonEncoder.java @@ -35,7 +35,7 @@ public class _DyncWorldJsonEncoder extends JsonDynEncoder { out.writeTo('{'); boolean comma = false; comma = out.writeFieldIntValue(idFieldBytes, idFieldChars, comma, value.getId()); - comma = out.writeFieldIntValue(randomNumberFieldBytes, randomNumberFieldChars, comma, value.getRandomNumber()); + out.writeFieldIntValue(randomNumberFieldBytes, randomNumberFieldChars, comma, value.getRandomNumber()); out.writeTo('}'); } }