Improve Decimal64 coding 25/106025/2
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 18 May 2023 08:42:26 +0000 (10:42 +0200)
committerRobert Varga <nite@hq.sk>
Thu, 18 May 2023 10:36:40 +0000 (10:36 +0000)
We are defining the Potassium output format, make sure we do not use
Strings to encode Decimal64, just plain binary -- up to 9 bytes.

JIRA: YANGTOOLS-568
Change-Id: If0f42d0b16594fd3ed6703277d41e547ef197302
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
codec/yang-data-codec-binfmt/src/main/java/org/opendaylight/yangtools/yang/data/codec/binfmt/PotassiumDataInput.java
codec/yang-data-codec-binfmt/src/main/java/org/opendaylight/yangtools/yang/data/codec/binfmt/PotassiumDataOutput.java
codec/yang-data-codec-binfmt/src/main/java/org/opendaylight/yangtools/yang/data/codec/binfmt/PotassiumValue.java
codec/yang-data-codec-binfmt/src/test/java/org/opendaylight/yangtools/yang/data/codec/binfmt/NormalizedNodeStreamReaderWriterTest.java

index ee5e05c18a2586d1f17762eeb9785a2943614042..73550a9fb8054d714caa4852b7c359ab05b722a5 100644 (file)
@@ -26,6 +26,7 @@ import java.util.concurrent.ExecutionException;
 import javax.xml.transform.dom.DOMSource;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.concepts.Either;
+import org.opendaylight.yangtools.concepts.WritableObjects;
 import org.opendaylight.yangtools.util.xml.UntrustedXML;
 import org.opendaylight.yangtools.yang.common.Decimal64;
 import org.opendaylight.yangtools.yang.common.Empty;
@@ -719,9 +720,8 @@ final class PotassiumDataInput extends AbstractNormalizedNodeDataInput {
                 return Uint64.ZERO;
             case PotassiumValue.UINT64_4B:
                 return Uint64.fromLongBits(input.readInt() & 0xFFFFFFFFL);
-            case PotassiumValue.BIGDECIMAL:
-                // FIXME: use string -> Decimal64 cache
-                return Decimal64.valueOf(input.readUTF());
+            case PotassiumValue.DECIMAL64:
+                return Decimal64.of(input.readByte(), WritableObjects.readLong(input));
             case PotassiumValue.STRING_EMPTY:
                 return "";
             case PotassiumValue.STRING_UTF:
index 2834c5e8c7eefd7c45f1c3189ca194820f82781a..dbc4c3c61b42180921f89b9a67622e086ee26348 100644 (file)
@@ -12,7 +12,6 @@ import static com.google.common.base.Preconditions.checkArgument;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.io.StringWriter;
-import java.math.BigDecimal;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
 import java.util.Deque;
@@ -27,6 +26,7 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.concepts.WritableObjects;
 import org.opendaylight.yangtools.yang.common.Decimal64;
 import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -320,9 +320,10 @@ final class PotassiumDataOutput extends AbstractNormalizedNodeDataOutput {
             output.writeByte(PotassiumValue.EMPTY);
         } else if (value instanceof Set<?> set) {
             writeValue(set);
-        } else if (value instanceof BigDecimal || value instanceof Decimal64) {
-            output.writeByte(PotassiumValue.BIGDECIMAL);
-            output.writeUTF(value.toString());
+        } else if (value instanceof Decimal64 decimal) {
+            output.writeByte(PotassiumValue.DECIMAL64);
+            output.writeByte(decimal.scale());
+            WritableObjects.writeLong(output, decimal.unscaledValue());
         } else {
             throw new IOException("Unhandled value type " + value.getClass());
         }
index 0313bf022147dd5a76412a7ae77bfd2c9b89db9d..a9c21a3c515f1e5aa671854969cfd137e2d2e022 100644 (file)
@@ -8,8 +8,7 @@
 package org.opendaylight.yangtools.yang.data.codec.binfmt;
 
 import java.io.DataOutput;
-import java.math.BigDecimal;
-import java.math.BigInteger;
+import org.opendaylight.yangtools.yang.common.Decimal64;
 import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.common.Uint32;
@@ -176,18 +175,12 @@ final class PotassiumValue {
      * Reference a previously defined QNameModule. Reference number is encoded as {@code int}.
      */
     static final byte MODREF_4B      = 0x1C;
-
-    /**
-     * A {@link BigDecimal}, encoded through {@link DataOutput#writeUTF(String)}.
-     */
-    // This is legacy compatibility. At some point we will remove support for writing these.
-    static final byte BIGDECIMAL     = 0x1D;
     /**
-     * A {@link BigInteger}, encoded through {@link DataOutput#writeUTF(String)}.
+     * A {@link Decimal64}, encoded with fraction-digits byte and a WritableObjects.writeLong().
      */
-    // This is legacy compatibility. At some point we will remove support for writing these.
-    static final byte BIGINTEGER     = 0x1E;
+    static final byte DECIMAL64     = 0x1D;
 
+    // 0x1E reserved
     // 0x1F reserved
 
     /**
index e724e6e8cc88afa9f9c01242ebb5408e1e2c5e95..faf038e422fa4cc53f7f8c265974b84a1a835aeb 100644 (file)
@@ -55,7 +55,7 @@ public class NormalizedNodeStreamReaderWriterTest {
     @Parameters(name = "{0} {1}")
     public static Iterable<Object[]> data() {
         return Collections.singletonList(
-            new Object[] { NormalizedNodeStreamVersion.POTASSIUM, 1_049_589, 2_289_103, 139, 796, 103, 229, 99 });
+            new Object[] { NormalizedNodeStreamVersion.POTASSIUM, 1_049_587, 2_289_103, 139, 794, 103, 229, 99 });
     }
 
     @Parameter(0)