Added, revised, and debugged some tests and test issues. Updated javadocs and pom.xml. We now add SystemSchema.json to azure-cosmos-serialization.jar. Javadocs don't currently build.

This commit is contained in:
David Noble
2019-09-16 23:32:26 -07:00
parent 446d44b24b
commit dee374eacc
38 changed files with 1835 additions and 1966 deletions

View File

@@ -132,6 +132,7 @@ Licensed under the MIT License.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
</configuration>
</plugin>
@@ -187,8 +188,31 @@ Licensed under the MIT License.
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.10</version>
<configuration>
<classpathContainers>
<classpathContainer>
org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8
</classpathContainer>
</classpathContainers>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<inherited>true</inherited>
<version>3.1.1</version>
<!--inherited>true</inherited-->
<configuration>
<quiet>true</quiet>
<verbose>false</verbose>
@@ -207,9 +231,33 @@ Licensed under the MIT License.
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/../schemas</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>attach-sources</id>
@@ -219,27 +267,7 @@ Licensed under the MIT License.
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
<configuration>
<classpathContainers>
<classpathContainer>
org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8
</classpathContainer>
</classpathContainers>
</configuration>
</plugin>
<plugin>
<!--plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
@@ -255,7 +283,7 @@ Licensed under the MIT License.
</goals>
</execution>
</executions>
</plugin>
</plugin-->
</plugins>
</build>

View File

@@ -4,25 +4,17 @@
package com.azure.data.cosmos.serialization.hybridrow;
/**
* An IEEE 128-bit floating point value.
* Represents an IEEE 754-2008 128-bit decimal floating point number.
* <p>
* A binary integer decimal representation of a 128-bit decimal value, supporting 34 decimal digits of
* significand and an exponent range of -6143 to +6144.
* <list type="table">
* <listheader>
* <term>Source</term> <description>Link</description>
* </listheader> <item>
* <term>Wikipedia:</term>
* <description>https: //en.wikipedia.org/wiki/Decimal128_floating-point_format</description>
* </item> <item>
* <term>The spec:</term> <description>https: //ieeexplore.ieee.org/document/4610935</description>
* </item> <item>
* <term>Decimal Encodings:</term> <description>http: //speleotrove.com/decimal/decbits.html</description>
* </item>
* </list>
* The {@link Float128} represents an IEEE 754-2008 floating point number as a pair of {@code long} values:
* {@link #high} and {@link #low}.
*
* @see <a href="https://en.wikipedia.org/wiki/Decimal128_floating-point_format">decimal128 floating-point format</a>
* @see <a href="https://ieeexplore.ieee.org/document/4610935">754-2008: IEEE Standard for Floating-Point Arithmetic</a>
* @see <a href="http://speleotrove.com/decimal/decbits.html">Decimal Arithmetic Encodings Version 1.01 7 Apr 2009</a>
*/
public final class Float128 {
/**
* The size (in bytes) of a {@link Float128}.
*/
@@ -45,6 +37,8 @@ public final class Float128 {
/**
* The high-order 64 bits of the IEEE 754-2008 128-bit decimal floating point, using the BID encoding scheme.
*
* @return the high-order 64 bits of the IEEE 754-2008 128-bit floating point number represented by this object.
*/
public long high() {
return this.high;
@@ -52,6 +46,8 @@ public final class Float128 {
/**
* The low-order 64 bits of the IEEE 754-2008 128-bit decimal floating point, using the BID encoding scheme.
*
* @return the low-order 64 bits of the IEEE 754-2008 128-bit floating point number represented by this object.
*/
public long low() {
return this.low;

View File

@@ -27,14 +27,18 @@ public final class HybridRowHeader {
}
/**
* The unique identifier of the schema whose layout was used to write this row.
* The unique identifier of the schema whose layout was used to write this {@link HybridRowHeader}.
*
* @return unique identifier of the schema whose layout was used to write this {@link HybridRowHeader}.
*/
public SchemaId schemaId() {
return this.schemaId;
}
/**
* The version of the HybridRow library used to write this row.
* The version of the HybridRow serialization library used to write this {@link HybridRowHeader}.
*
* @return version of the HybridRow serialization library used to write this {@link HybridRowHeader}.
*/
public HybridRowVersion version() {
return this.version;

View File

@@ -198,8 +198,8 @@ public final class RowBuffer {
/**
* Compute the number of bytes necessary to store the unsigned 32-bit integer value using the varuint encoding.
*
* @param value The value to be encoded
* @return The number of bytes needed to store the varuint encoding of {@code value}
* @param value the value to be encoded
* @return the number of bytes needed to store the varuint encoding of {@code value}
*/
public static int count7BitEncodedUInt(long value) {
checkArgument(0 <= value && value <= 0x00000000FFFFFFFFL, "value: %s", value);
@@ -212,6 +212,12 @@ public final class RowBuffer {
return i;
}
/**
* Decrement the unsigned 32-bit integer value at the given {@code offset} in this {@link RowBuffer}.
*
* @param offset offset of a 32-bit unsigned integer value in this {@link RowBuffer}.
* @param decrement the decrement value.
*/
public void decrementUInt32(int offset, long decrement) {
long value = this.buffer.getUnsignedIntLE(offset);
this.buffer.setIntLE(offset, (int) (value - decrement));
@@ -266,7 +272,9 @@ public final class RowBuffer {
}
/**
* The root header for the row.
* The root header of this {@link RowBuffer}.
*
* @return root header of this {@link RowBuffer}.
*/
public HybridRowHeader header() {
return this.readHeader();
@@ -291,6 +299,12 @@ public final class RowBuffer {
// this.buffer.writerIndex(this.length() + shift);
// }
/**
* Decrement the unsigned 32-bit integer value at the given {@code offset} in this {@link RowBuffer}.
*
* @param offset offset of a 32-bit unsigned integer value in this {@link RowBuffer}.
* @param increment the increment value.
*/
public void incrementUInt32(final int offset, final long increment) {
final long value = this.buffer.getUnsignedIntLE(offset);
this.buffer.setIntLE(offset, (int) (value + increment));
@@ -320,6 +334,8 @@ public final class RowBuffer {
/**
* The length of this {@link RowBuffer} in bytes.
*
* @return The length of this {@link RowBuffer} in bytes.
*/
public int length() {
return this.buffer.writerIndex();
@@ -378,21 +394,13 @@ public final class RowBuffer {
return dstEdit;
}
public long read7BitEncodedInt(int offset) {
Item<Long> item = this.read(this::read7BitEncodedInt, offset);
return item.value();
}
public long read7BitEncodedUInt(int offset) {
Item<Long> item = this.read(this::read7BitEncodedUInt, offset);
return item.value();
}
// TODO: DANOBLE: resurrect this method
// public MongoDbObjectId ReadMongoDbObjectId(int offset) {
// return MemoryMarshal.<MongoDbObjectId>Read(this.buffer.Slice(offset));
// }
/**
* Read the value of a bit within the bit field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a bit field within this {@link RowBuffer}.
* @param bit the bit to read.
* @return {@code true} if the {@code bit} is set, otherwise {@code false}.
*/
public boolean readBit(final int offset, @Nonnull final LayoutBit bit) {
checkNotNull(bit, "expected non-null bit");
@@ -405,31 +413,89 @@ public final class RowBuffer {
return item.value();
}
/**
* Read the value of the {@code DateTime} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code DateTime} field within this {@link RowBuffer}.
* @return the {@code DateTime} value read.
*/
public OffsetDateTime readDateTime(int offset) {
Item<OffsetDateTime> item = this.read(() -> DateTimeCodec.decode(this.buffer), offset);
return item.value();
}
// TODO: DANOBLE: resurrect this method
// public MongoDbObjectId ReadMongoDbObjectId(int offset) {
// return MemoryMarshal.<MongoDbObjectId>Read(this.buffer.Slice(offset));
// }
/**
* Read the value of the {@code Decimal} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code Decimal} field within this {@link RowBuffer}.
* @return the {@code Decimal} value read.
*/
public BigDecimal readDecimal(int offset) {
Item<BigDecimal> item = this.read(() -> DecimalCodec.decode(this.buffer), offset);
return item.value();
}
/**
* Read the value of a {@code FixedBinary} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code FixedBinary} field within this {@link RowBuffer}.
* @return the {@code FixedBinary} value read.
*/
public ByteBuf readFixedBinary(int offset, int length) {
Item<ByteBuf> item = this.read(() -> this.buffer.readSlice(length), offset);
return item.value();
}
/**
* Read the value of a {@code FixedString} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code FixedString} field within this {@link RowBuffer}.
* @param length number of bytes in the {@code FixedString} field.
* @return the {@code FixedString} value read.
*/
public Utf8String readFixedString(int offset, int length) {
Item<Utf8String> item = this.read(this::readFixedString, offset, length);
return item.value();
}
/**
* Read the value of a {@code Float128} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code Float128} field within this {@link RowBuffer}.
* @return the {@code Float128} value read.
*/
public Float128 readFloat128(int offset) {
Item<Float128> item = this.read(this::readFloat128, offset);
return item.value();
}
/**
* Read the value of a {@code Float32} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code Float32} field within this {@link RowBuffer}.
* @return the {@code Float32} value read.
*/
public float readFloat32(int offset) {
Item<Float> item = this.read(this.buffer::readFloatLE, offset);
return item.value();
}
/**
* Read the value of a {@code Float64} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code Float64} field within this {@link RowBuffer}.
* @return the {@code Float64} value read.
*/
public double readFloat64(int offset) {
Item<Double> item = this.read(this.buffer::readDoubleLE, offset);
return item.value();
}
// TODO: DANOBLE: resurrect this method
// public MongoDbObjectId ReadSparseMongoDbObjectId(Reference<RowCursor> edit) {
// this.readSparsePrimitiveTypeCode(edit, MongoDbObjectId);
@@ -437,16 +503,6 @@ public final class RowBuffer {
// return this.ReadMongoDbObjectId(edit.valueOffset()).clone();
// }
public float readFloat32(int offset) {
Item<Float> item = this.read(this.buffer::readFloatLE, offset);
return item.value();
}
public double readFloat64(int offset) {
Item<Double> item = this.read(this.buffer::readDoubleLE, offset);
return item.value();
}
/**
* Reads in the contents of the current {@link RowBuffer} from an {@link InputStream}.
* <p>
@@ -513,104 +569,218 @@ public final class RowBuffer {
return this.validateHeader(version);
}
/**
* Read the value of a {@code Guid} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code Guid} field within this {@link RowBuffer}.
* @return the {@code Guid} value read.
*/
public UUID readGuid(int offset) {
return this.read(() -> GuidCodec.decode(this.buffer), offset).value();
}
/**
* Read the value of a {@code Header} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code Header} field within this {@link RowBuffer}.
* @return the {@code Header} value read.
*/
public HybridRowHeader readHeader(int offset) {
return this.read(this::readHeader, offset).value();
}
/**
* Read the value of a {@code Int16} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code Int16} field within this {@link RowBuffer}.
* @return the {@code Int16} value read.
*/
public short readInt16(int offset) {
return this.read(this.buffer::readShortLE, offset).value();
}
/**
* Read the value of a {@code Int32} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code Int32} field within this {@link RowBuffer}.
* @return the {@code Int32} value read.
*/
public int readInt32(int offset) {
Item<Integer> item = this.read(this.buffer::readIntLE, offset);
return item.value();
}
/**
* Read the value of a {@code Int64} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code Int64} field within this {@link RowBuffer}.
* @return the {@code Int64} value read.
*/
public long readInt64(int offset) {
Item<Long> item = this.read(this.buffer::readLongLE, offset);
return item.value();
}
/**
* Read the value of a {@code Int8} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code Int8} field within this {@link RowBuffer}.
* @return the {@code Int8} value read.
*/
public byte readInt8(int offset) {
Item<Byte> item = this.read(this.buffer::readByte, offset);
return item.value();
}
/**
* Read the value of a {@code SchemaId} field at the given {@code offset} within this {@link RowBuffer}.
*
* @param offset offset of a {@code SchemaId} field within this {@link RowBuffer}.
* @return the {@code SchemaId} value read.
*/
public SchemaId readSchemaId(int offset) {
Item<SchemaId> item = this.read(() -> SchemaId.from(this.buffer.readIntLE()), offset);
return item.value();
}
/**
* Read the value of a {@code SparseBinary} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseBinary} field within this {@link RowBuffer}.
* @return the {@code SparseBinary} value read.
*/
public ByteBuf readSparseBinary(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.BINARY);
Item<ByteBuf> item = this.read(this::readVariableBinary, edit);
return item.value();
}
/**
* Read the value of a {@code SparseBoolean} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseBoolean} field within this {@link RowBuffer}.
* @return the {@code SparseBoolean} value read.
*/
public boolean readSparseBoolean(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.BOOLEAN);
edit.endOffset(edit.valueOffset());
return edit.cellType() == LayoutTypes.BOOLEAN;
}
/**
* Read the value of a {@code SparseDateTime} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseDateTime} field within this {@link RowBuffer}.
* @return the {@code SparseDateTime} value read.
*/
public OffsetDateTime readSparseDateTime(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.DATE_TIME);
edit.endOffset(edit.valueOffset() + Long.SIZE);
return this.readDateTime(edit.valueOffset());
}
/**
* Read the value of a {@code SparseDecimal} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseDecimal} field within this {@link RowBuffer}.
* @return the {@code SparseDecimal} value read.
*/
public BigDecimal readSparseDecimal(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.DECIMAL);
Item<BigDecimal> item = this.read(this::readDecimal, edit);
return item.value();
}
/**
* Read the value of a {@code SparseFloat128} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseFloat128} field within this {@link RowBuffer}.
* @return the {@code SparseFloat128} value read.
*/
public Float128 readSparseFloat128(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.FLOAT_128);
Item<Float128> item = this.read(this::readFloat128, edit);
return item.value();
}
/**
* Read the value of a {@code SparseFloat32} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseFloat32} field within this {@link RowBuffer}.
* @return the {@code SparseFloat32} value read.
*/
public float readSparseFloat32(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.FLOAT_32);
Item<Float> item = this.read(this.buffer::readFloatLE, edit);
return item.value();
}
/**
* Read the value of a {@code SparseFloat64} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseFloat64} field within this {@link RowBuffer}.
* @return the {@code SparseFloat64} value read.
*/
public double readSparseFloat64(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.FLOAT_64);
Item<Double> item = this.read(this.buffer::readDoubleLE, edit);
return item.value();
}
/**
* Read the value of a {@code SparseGuid} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseGuid} field within this {@link RowBuffer}.
* @return the {@code SparseGuid} value read.
*/
public UUID readSparseGuid(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.GUID);
Item<UUID> item = this.read(this::readGuid, edit);
return item.value();
}
/**
* Read the value of a {@code SparseInt16} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseInt16} field within this {@link RowBuffer}.
* @return the {@code SparseInt16} value read.
*/
public short readSparseInt16(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.INT_16);
Item<Short> item = this.read(this.buffer::readShortLE, edit);
return item.value();
}
/**
* Read the value of a {@code SparseInt32} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseInt32} field within this {@link RowBuffer}.
* @return the {@code SparseInt32} value read.
*/
public int readSparseInt32(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.INT_32);
Item<Integer> item = this.read(this.buffer::readIntLE, edit);
return item.value();
}
/**
* Read the value of a {@code SparseInt64} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseInt64} field within this {@link RowBuffer}.
* @return the {@code SparseInt64} value read.
*/
public long readSparseInt64(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.INT_64);
Item<Long> item = this.read(this.buffer::readLongLE, edit);
return item.value();
}
/**
* Read the value of a {@code SparseInt8} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseInt8} field within this {@link RowBuffer}.
* @return the {@code SparseInt8} value read.
*/
public byte readSparseInt8(RowCursor edit) {
// TODO: Remove calls to readSparsePrimitiveTypeCode once moved to V2 read.
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.INT_8);
@@ -618,6 +788,12 @@ public final class RowBuffer {
return item.value();
}
/**
* Read the value of a {@code SparseNull} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseNull} field within this {@link RowBuffer}.
* @return the {@code SparseNull} value read.
*/
public NullValue readSparseNull(@Nonnull RowCursor edit) {
checkNotNull(edit, "expected non-null edit");
@@ -628,6 +804,12 @@ public final class RowBuffer {
return NullValue.DEFAULT;
}
/**
* Read the value of a {@code SparsePath} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparsePath} field within this {@link RowBuffer}.
* @return the {@code SparsePath} value read.
*/
public Utf8String readSparsePath(@Nonnull final RowCursor edit) {
checkNotNull(edit, "expected non-null edit");
@@ -645,6 +827,15 @@ public final class RowBuffer {
return item.value();
}
/**
* Read the value of a {@code SparseLen} field at the given {@code offset} position.
*
* @param layout
* @param offset position of a {@code SparseLen} field within this {@link RowBuffer}.
* @param pathLenInBytes
* @param pathOffset
* @return the {@code SparseLen} value read.
*/
public int readSparsePathLen(
@Nonnull final Layout layout, final int offset, @Nonnull final Out<Integer> pathLenInBytes,
@Nonnull final Out<Integer> pathOffset) {
@@ -668,103 +859,218 @@ public final class RowBuffer {
return token;
}
/**
* Read the value of a {@code SparseString} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseString} field within this {@link RowBuffer}.
* @return the {@code SparseString} value read.
*/
public Utf8String readSparseString(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.UTF_8);
Item<Utf8String> item = this.read(this::readUtf8String, edit);
return item.value();
}
/**
* Read the value of a {@code SparseTypeCode} field at the given {@code offset} position.
*
* @param offset position of a {@code SparseTypeCode} field within this {@link RowBuffer}.
* @return the {@code SparseTypeCode} value read.
*/
public LayoutType readSparseTypeCode(int offset) {
return LayoutType.fromCode(LayoutCode.from(this.readInt8(offset)));
}
/**
* Read the value of a {@code SparseUInt16} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseUInt16} field within this {@link RowBuffer}.
* @return the {@code SparseUInt16} value read.
*/
public int readSparseUInt16(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.UINT_16);
Item<Integer> item = this.read(this.buffer::readUnsignedShortLE, edit);
return item.value();
}
/**
* Read the value of a {@code SparseUInt32} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseUInt32} field within this {@link RowBuffer}.
* @return the {@code SparseUInt32} value read.
*/
public long readSparseUInt32(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.UINT_32);
Item<Long> item = this.read(this.buffer::readUnsignedIntLE, edit);
return item.value();
}
/**
* Read the value of a {@code SparseUInt64} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseUInt64} field within this {@link RowBuffer}.
* @return the {@code SparseUInt64} value read.
*/
public long readSparseUInt64(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.UINT_64);
Item<Long> item = this.read(this.buffer::readLongLE, edit);
return item.value;
}
/**
* Read the value of a {@code SparseUInt8} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseUInt8} field within this {@link RowBuffer}.
* @return the {@code SparseUInt8} value read.
*/
public short readSparseUInt8(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.UINT_8);
Item<Short> item = this.read(this.buffer::readUnsignedByte, edit);
return item.value;
}
/**
* Read the value of a {@code SparseUnixDateTime} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseUnixDateTime} field within this {@link RowBuffer}.
* @return the {@code SparseUnixDateTime} value read.
*/
public UnixDateTime readSparseUnixDateTime(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.UNIX_DATE_TIME);
Item<UnixDateTime> item = this.read(this::readUnixDateTime, edit);
return item.value();
}
/**
* Read the value of a {@code SparseVarInt} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseVarInt} field within this {@link RowBuffer}.
* @return the {@code SparseVarInt} value read.
*/
public long readSparseVarInt(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.VAR_INT);
Item<Long> item = this.read(this::read7BitEncodedInt, edit);
return item.value();
}
/**
* Read the value of a {@code SparseVarUInt} field at the given {@link RowCursor edit} position.
*
* @param edit {@link RowCursor edit} position of a {@code SparseVarUInt} field within this {@link RowBuffer}.
* @return the {@code SparseVarUInt} value read.
*/
public long readSparseVarUInt(RowCursor edit) {
this.readSparsePrimitiveTypeCode(edit, LayoutTypes.VAR_UINT);
Item<Long> item = this.read(this::read7BitEncodedUInt, edit);
return item.value();
}
/**
* Read the value of a {@code UInt16} field at the given {@code offset} position.
*
* @param offset position of a {@code UInt16} field within this {@link RowBuffer}.
* @return the {@code UInt16} value read.
*/
public int readUInt16(int offset) {
Item<Integer> item = this.read(this.buffer::readUnsignedShortLE, offset);
return item.value();
}
/**
* Read the value of a {@code UInt32} field at the given {@code offset} position.
*
* @param offset position of a {@code UInt32} field within this {@link RowBuffer}.
* @return the {@code UInt32} value read.
*/
public long readUInt32(int offset) {
Item<Long> item = this.read(this.buffer::readUnsignedIntLE, offset);
return item.value();
}
/**
* Read the value of a {@code UInt64} field at the given {@code offset} position.
*
* @param offset position of a {@code UInt64} field within this {@link RowBuffer}.
* @return the {@code UInt64} value read.
*/
public long readUInt64(int offset) {
Item<Long> item = this.read(this.buffer::readLongLE, offset);
return item.value();
}
/**
* Read the value of a {@code UInt8} field at the given {@code offset} position.
*
* @param offset position of a {@code UInt8} field within this {@link RowBuffer}.
* @return the {@code UInt8} value read.
*/
public short readUInt8(int offset) {
Item<Short> item = this.read(this.buffer::readUnsignedByte, offset);
return item.value();
}
/**
* Read the value of a {@code UnixDateTime} field at the given {@code offset} position.
*
* @param offset position of a {@code UnixDateTime} field within this {@link RowBuffer}.
* @return the {@code UnixDateTime} value read.
*/
public UnixDateTime readUnixDateTime(int offset) {
Item<UnixDateTime> item = this.read(this::readUnixDateTime, offset);
return item.value();
}
/**
* Read the value of a {@code VariableBinary} field at the given {@code offset} position.
*
* @param offset position of a {@code VariableBinary} field within this {@link RowBuffer}.
* @return the {@code VariableBinary} value read.
*/
public ByteBuf readVariableBinary(int offset) {
Item<ByteBuf> item = this.read(this::readVariableBinary, offset);
return item.value();
}
/**
* Read the value of a {@code VariableInt} field at the given {@code offset} position.
*
* @param offset position of a {@code VariableInt} field within this {@link RowBuffer}.
* @return the {@code VariableInt} value read.
*/
public long readVariableInt(int offset) {
Item<Long> item = this.read(this::read7BitEncodedInt, offset);
return item.value();
}
/**
* Read the value of a {@code VariableString} field at the given {@code offset} position.
*
* @param offset position of a {@code VariableString} field within this {@link RowBuffer}.
* @return the {@code VariableString} value read.
*/
public Utf8String readVariableString(final int offset) {
Item<Utf8String> item = this.read(this::readUtf8String, offset);
return item.value();
}
/**
* Read the value of a {@code VariableUInt} field at the given {@code offset} position.
*
* @param offset position of a {@code VariableUInt} field within this {@link RowBuffer}.
* @return the {@code VariableUInt} value read.
*/
public long readVariableUInt(final int offset) {
Item<Long> item = this.read(this::read7BitEncodedUInt, offset);
return item.value();
}
/**
* Read the value of a {@code VariableUInt} field at the given {@code offset} position.
*
* @param offset position of a {@code VariableUInt} field within this {@link RowBuffer}.
* @param length on return, the number of bytes read.
* @return the {@code VariableUInt} value read.
*/
public long readVariableUInt(final int offset, @Nonnull final Out<Integer> length) {
Item<Long> item = this.read(this::read7BitEncodedUInt, offset);
length.set(item.length());
@@ -786,14 +1092,6 @@ public final class RowBuffer {
return this.resolver;
}
// TODO: DANOBLE: Support MongoDbObjectId values
// public void WriteMongoDbObjectId(int offset, MongoDbObjectId value) {
// Reference<azure.data.cosmos.serialization.hybridrow.MongoDbObjectId> tempReference_value =
// new Reference<azure.data.cosmos.serialization.hybridrow.MongoDbObjectId>(value);
// MemoryMarshal.Write(this.buffer.Slice(offset), tempReference_value);
// value = tempReference_value.get();
// }
/**
* Rotates the sign bit of a two's complement value to the least significant bit.
*
@@ -801,15 +1099,11 @@ public final class RowBuffer {
* @return An unsigned value encoding the same value but with the sign bit in the LSB.
* <p>
* Moves the signed bit of a two's complement value to the least significant bit (LSB) by:
* <list type="number">
* <item>
* <description>If negative, take the two's complement.</description>
* </item><item>
* <description>Left shift the value by 1 bit.</description>
* </item><item>
* <description>If negative, set the LSB to 1.</description>
* </item>
* </list>
* <ol>
* <li>If negative, take the two's complement.
* <li>Left shift the value by 1 bit.
* <li>If negative, set the LSB to 1.
* </ol>
*/
public static long rotateSignToLsb(long value) {
boolean isNegative = value < 0;
@@ -829,6 +1123,14 @@ public final class RowBuffer {
return isNegative ? (~(unsignedValue >>> 1) + 1) | 0x8000000000000000L : unsignedValue >>> 1;
}
// TODO: DANOBLE: Support MongoDbObjectId values
// public void WriteMongoDbObjectId(int offset, MongoDbObjectId value) {
// Reference<azure.data.cosmos.serialization.hybridrow.MongoDbObjectId> tempReference_value =
// new Reference<azure.data.cosmos.serialization.hybridrow.MongoDbObjectId>(value);
// MemoryMarshal.Write(this.buffer.Slice(offset), tempReference_value);
// value = tempReference_value.get();
// }
public void setBit(final int offset, @Nonnull final LayoutBit bit) {
checkNotNull(bit, "expected non-null bit");
if (bit.isInvalid()) {
@@ -1065,28 +1367,20 @@ public final class RowBuffer {
* @param scope The sparse scope to rebuild an index for.
* @return Success if the index could be built, an error otherwise.
* <p>
* The <paramref name="scope" /> MUST be a set or map scope.
* The {@code scope} MUST be a set or map scope.
* <p>
* The scope may have been built (e.g. via RowWriter) with relaxed uniqueness constraint checking.
* This operation rebuilds an index to support verification of uniqueness constraints during
* subsequent partial updates. If the appropriate uniqueness constraints cannot be established (i.e.
* a duplicate exists), this operation fails. Before continuing, the resulting scope should either:
* <list type="number">
* <item>
* <description>
* Be repaired (e.g. by deleting duplicates) and the index rebuild operation should be
* run again.
* </description>
* </item> <item>
* <description>Be deleted. The entire scope should be removed including its items.</description>
* </item>
* </list> Failure to perform one of these actions will leave the row is potentially in a corrupted
* state where partial updates may subsequent fail.
* </p>
* <ol>
* <li>Be repaired (e.g. by deleting duplicates) and the index rebuild operation should be run again.
* <li>Be deleted. The entire scope should be removed including its items.
* </ol>
* Failure to perform one of these actions will leave the row is potentially in a corrupted state where partial
* updates may subsequent fail.
* <p>
* The target <paramref name="scope" /> may or may not have already been indexed. This
* operation is idempotent.
* </p>
* The target {@code scope} may or may not have already been indexed. This operation is idempotent.
*/
@Nonnull
public Result typedCollectionUniqueIndexRebuild(@Nonnull final RowCursor scope) {
@@ -2762,10 +3056,20 @@ public final class RowBuffer {
return Item.of(value, offset, actualLength);
}
private long read7BitEncodedInt(int offset) {
Item<Long> item = this.read(this::read7BitEncodedInt, offset);
return item.value();
}
private long read7BitEncodedInt() {
return RowBuffer.rotateSignToMsb(this.read7BitEncodedUInt());
}
private long read7BitEncodedUInt(int offset) {
Item<Long> item = this.read(this::read7BitEncodedUInt, offset);
return item.value();
}
private long read7BitEncodedUInt() {
long b = this.buffer.readByte() & 0xFFL;

View File

@@ -79,23 +79,39 @@ public final class RowCursor implements Cloneable {
/**
* If existing, the layout code of the existing field, otherwise undefined.
*
* @return layout code.
*/
public LayoutType cellType() {
return this.cellType;
}
public RowCursor cellType(LayoutType cellType) {
this.cellType = cellType;
/**
* Sets the layout type of an existing field.
*
* @param value a {@link LayoutType layout type}.
* @return a reference to this {@link RowCursor}.
*/
public RowCursor cellType(LayoutType value) {
this.cellType = value;
return this;
}
/**
* For types with generic parameters (e.g. {@link LayoutTuple}, the type parameters.
*
* @return a {@link TypeArgumentList type argument argument list} or {@code null}.
*/
public TypeArgumentList cellTypeArgs() {
return this.cellTypeArgs;
}
/**
* Sets the layout type arguments of an existing field.
*
* @param value a {@link TypeArgumentList type argument argument list}.
* @return a reference to this {@link RowCursor}.
*/
public RowCursor cellTypeArgs(TypeArgumentList value) {
this.cellTypeArgs = value;
return this;
@@ -103,48 +119,81 @@ public final class RowCursor implements Cloneable {
/**
* For sized scopes (e.g. Typed Array), the number of elements.
*
* @return the number of elements or zero.
*/
public int count() {
return this.count;
}
/**
* Sets the number of elements for a sized scope.
*
* @param count the number of elements for a sized scope.
* @return a reference to this {@link RowCursor}.
*/
public RowCursor count(int count) {
this.count = count;
return this;
}
/**
* If true, this scope is an unique index scope whose index will be built after its items are written.
* If true, this scope is a unique index scope whose index will be built after its items are written.
*
* @return {@code true}, if this cursor identifies a unique index scope, otherwise {@code false}.
*/
public boolean deferUniqueIndex() {
return this.deferUniqueIndex;
}
/**
* Sets a value that indicates whether this cursor identifies a unique index scope.
*
* @param value {@code true}, if this cursor identifies a unique index scope, otherwise {@code false}.
* @return a reference to this {@link RowCursor}.
*/
public RowCursor deferUniqueIndex(boolean value) {
this.deferUniqueIndex = value;
return this;
}
/**
* If existing, the offset to the end of the existing field. Used as a hint when skipping.
* forward.
* If existing, the offset to the end of the existing field.
* <p>
* This value is used as a hint when skipping forward.
*
* @return offset of the end of an existing field.
*/
public int endOffset() {
return this.endOffset;
}
/**
* Sets a value that indicates whether this cursor identifies a unique index scope.
*
* @param value {@code true}, if this cursor identifies a unique index scope, otherwise {@code false}.
* @return a reference to this {@link RowCursor}.
*/
public RowCursor endOffset(int value) {
this.endOffset = value;
return this;
}
/**
* True if an existing field matching the search criteria was found.
* {@code true} if an existing field matching the search criteria was found.
*
* @return {@code true} if an existing field matching the search criteria was found, otherwise {@code false}.
*/
public boolean exists() {
return this.exists;
}
/**
* Sets a value that indicates whether this cursor identifies a field matching search criteria.
*
* @param value {@code true}, if this cursor identifies a field matching search criteria, otherwise {@code false}.
* @return a reference to this {@link RowCursor}.
*/
public RowCursor exists(boolean value) {
this.exists = value;
return this;

View File

@@ -39,7 +39,7 @@ public final class SchemaId implements Comparable<SchemaId> {
private final int value;
/**
* Initializes a new instance of the {@link SchemaId} struct.
* Initializes a new instance of the {@link SchemaId} class.
*
* @param value The underlying globally unique identifier of the schema.
*/
@@ -78,9 +78,10 @@ public final class SchemaId implements Comparable<SchemaId> {
}
/**
* Returns a {@link SchemaId} from a specified underlying integer value.
* Returns a {@link SchemaId} with the given underlying integer value.
*
* @return The integer value of this {@link SchemaId}
* @param value an integer.
* @return a {@link SchemaId} with the given underlying integer {@code value}.
*/
public static SchemaId from(int value) {
return cache.computeIfAbsent(value, SchemaId::new);

View File

@@ -24,23 +24,23 @@ public final class UnixDateTime {
private long milliseconds;
/**
* Initializes a new instance of the {@link UnixDateTime} struct.
*
* @param milliseconds The number of milliseconds since {@link EPOCH}.
*/
private UnixDateTime() {
}
/**
* Initializes a new instance of the {@link UnixDateTime} class.
*
* @param milliseconds The number of milliseconds since {@link #EPOCH}.
*/
public UnixDateTime(long milliseconds) {
this.milliseconds = milliseconds;
}
/**
* {@code> true} if this value is the same as another value
* {@code> true} if this value is the same as another value.
*
* @param other value to compare
* @return {code true} if this value is the same as the {code other}
* @param other value to compare.
* @return {code true} if this value is the same as the {code other}, {@code false} otherwise.
*/
public boolean equals(UnixDateTime other) {
if (other == null) {
@@ -66,9 +66,11 @@ public final class UnixDateTime {
}
/**
* The number of milliseconds since {@link #EPOCH}
* The number of milliseconds since {@link #EPOCH}.
* <p>
* This value may be negative
* This value may be negative.
*
* @return the number of milliseconds since {@link #EPOCH}.
*/
public long milliseconds() {
return this.milliseconds;

View File

@@ -19,7 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
*
* {@link OffsetDateTime} values are serialized as unsigned 64-bit integers:
*
* <table>
* <table summary="Layout of field value">
* <tbody>
* <tr><td>
* Bits 01-62

View File

@@ -18,7 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
* {@link UUID}s are serialized like {@code System.Guid}s read and written by {@code MemoryMarshal.Read} and
* {@code MemoryMarshal.Write}.
*
* <table>
* <table summary="Layout of field value">
* <tbody>
* <tr><td>
* Bits 00-31

View File

@@ -3,7 +3,6 @@
package com.azure.data.cosmos.serialization.hybridrow.io;
import com.azure.data.cosmos.core.Reference;
import com.azure.data.cosmos.serialization.hybridrow.Result;
import com.azure.data.cosmos.serialization.hybridrow.layouts.TypeArgument;
@@ -18,5 +17,5 @@ public interface IRowSerializable {
* @param typeArg The schematized layout type, if a schema is available
* @return Success if the write is successful, the error code otherwise
*/
Result write(Reference<RowWriter> writer, TypeArgument typeArg);
Result write(RowWriter writer, TypeArgument typeArg);
}

View File

@@ -156,6 +156,8 @@ public final class RowReader {
* If the current field is a Nullable scope, this method return true if the value is not null. If the current field
* is a nullable Null primitive value, this method return true if the value is set (even though its values is set
* to null).
*
* @return {@code true} if field has a value, {@code false} otherwise.
*/
public boolean hasValue() {
@@ -181,6 +183,7 @@ public final class RowReader {
* <p>
* When enumerating a non-indexed scope, this value is always zero.
*
* @return zero-based index of the field relative to the scope, if positioned on a field; otherwise undefined.
* @see #path
*/
public int index() {
@@ -189,6 +192,8 @@ public final class RowReader {
/**
* The length of row in bytes.
*
* @return length of the current row in bytes.
*/
public int length() {
return this.row.length();
@@ -197,8 +202,9 @@ public final class RowReader {
/**
* The path, relative to the scope, of the field--if positioned on a field--undefined otherwise.
* <p>
* When enumerating an indexed scope, this value is always null.
* When enumerating an indexed scope, this value is always {@code null}.
*
* @return path of the field relative to the scope, if positioned on a field; otherwise undefined.
* @see #index
*/
public UtfAnyString path() {
@@ -228,6 +234,7 @@ public final class RowReader {
* <p>
* When enumerating an indexed scope, this value is always null.
*
* @return path of the field relative to the scope, if positioned on a field; otherwise undefined.
* @see #index
*/
public Utf8String pathSpan() {
@@ -244,7 +251,7 @@ public final class RowReader {
/**
* Advances the reader to the next field.
*
* @return {@code true}, if there is another field to be read; {@code false} otherwise
* @return {@code true}, if there is another field to be read; {@code false} otherwise.
*/
public boolean read() {
@@ -505,7 +512,7 @@ public final class RowReader {
}
/**
* Read the current field as a fixed length GUID value
* Read the current field as a fixed length GUID value.
*
* @param value On success, receives the value, undefined otherwise.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
@@ -533,7 +540,7 @@ public final class RowReader {
}
/**
* Read the current field as a fixed length, 16-bit, signed integer
* Read the current field as a fixed length, 16-bit, signed integer.
*
* @param value On success, receives the value, undefined otherwise.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
@@ -560,7 +567,7 @@ public final class RowReader {
}
/**
* Read the current field as a fixed length, 32-bit, signed integer
* Read the current field as a fixed length, 32-bit, signed integer.
*
* @param value On success, receives the value, undefined otherwise.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
@@ -587,7 +594,7 @@ public final class RowReader {
}
/**
* Read the current field as a fixed length, 64-bit, signed integer
* Read the current field as a fixed length, 64-bit, signed integer.
*
* @param value On success, receives the value, undefined otherwise.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
@@ -614,7 +621,7 @@ public final class RowReader {
}
/**
* Read the current field as a fixed length, 8-bit, signed integer
* Read the current field as a fixed length, 8-bit, signed integer.
*
* @param value On success, receives the value, undefined otherwise.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
@@ -641,7 +648,7 @@ public final class RowReader {
}
/**
* Read the current field as a null
* Read the current field as a null.
*
* @param value On success, receives the value, undefined otherwise.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
@@ -672,6 +679,11 @@ public final class RowReader {
* <p>
* Child readers can be used to read all sparse scope types including typed and untyped objects, arrays, tuples,
* set, and maps.
*
* @param <TContext> a reader context type.
* @param context a reader context.
* @param func a reader function.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
*/
@Nonnull
public <TContext> Result readScope(@Nullable final TContext context, @Nullable final ReaderFunc<TContext> func) {
@@ -689,10 +701,12 @@ public final class RowReader {
}
/**
* Read the current field as a nested, structured, sparse scope
* Read the current field as a nested, structured, sparse scope.
* <p>
* Child readers can be used to read all sparse scope types including typed and untyped objects, arrays, tuples,
* set, and maps. Nested child readers are independent of their parent.
*
* @return a new {@link RowReader}.
*/
public @Nonnull RowReader readScope() {
RowCursor newScope = this.row.sparseIteratorReadScope(this.cursor, true);
@@ -700,9 +714,9 @@ public final class RowReader {
}
/**
* Read the current field as a variable length, UTF-8 encoded string value
* Read the current field as a variable length, UTF-8 encoded string value.
*
* @param value On success, receives the value, undefined otherwise
* @param value On success, receives the value, undefined otherwise.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
*/
public Result readString(Out<String> value) {
@@ -770,9 +784,9 @@ public final class RowReader {
}
/**
* Read the current field as a fixed length, 32-bit, unsigned integer
* Read the current field as a fixed length, 32-bit, unsigned integer.
*
* @param value On success, receives the value, undefined otherwise
* @param value On success, receives the value, undefined otherwise.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
*/
public Result readUInt32(Out<Long> value) {
@@ -798,9 +812,9 @@ public final class RowReader {
}
/**
* Read the current field as a fixed length, 64-bit, unsigned integer
* Read the current field as a fixed length, 64-bit, unsigned integer.
*
* @param value On success, receives the value, undefined otherwise
* @param value On success, receives the value, undefined otherwise.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
*/
public Result readUInt64(Out<Long> value) {
@@ -825,9 +839,9 @@ public final class RowReader {
}
/**
* Read the current field as a fixed length, 8-bit, unsigned integer
* Read the current field as a fixed length, 8-bit, unsigned integer.
*
* @param value On success, receives the value, undefined otherwise
* @param value On success, receives the value, undefined otherwise.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
*/
public Result readUInt8(Out<Short> value) {
@@ -852,9 +866,9 @@ public final class RowReader {
}
/**
* Read the current field as a fixed length {@link UnixDateTime} value
* Read the current field as a fixed length {@link UnixDateTime} value.
*
* @param value On success, receives the value, undefined otherwise
* @param value On success, receives the value, undefined otherwise.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
*/
public Result readUnixDateTime(Out<UnixDateTime> value) {
@@ -879,9 +893,9 @@ public final class RowReader {
}
/**
* Read the current field as a variable length, 7-bit encoded, signed integer
* Read the current field as a variable length, 7-bit encoded, signed integer.
*
* @param value On success, receives the value, undefined otherwise
* @param value On success, receives the value, undefined otherwise.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
*/
public Result readVarInt(Out<Long> value) {
@@ -906,9 +920,9 @@ public final class RowReader {
}
/**
* Read the current field as a variable length, 7-bit encoded, unsigned integer
* Read the current field as a variable length, 7-bit encoded, unsigned integer.
*
* @param value On success, receives the value, undefined otherwise
* @param value On success, receives the value, undefined otherwise.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
*/
public Result readVarUInt(Out<Long> value) {
@@ -937,13 +951,14 @@ public final class RowReader {
}
/**
* Advance a reader to the end of a child reader
* Advance a reader to the end of a child reader.
* <p>
* The child reader is also advanced to the end of its scope. The reader must not have been advanced since the child
* reader was created with {@link #readScope}. This method can be used when the overload of {@link #readScope} that
* takes a {@link ReaderFunc{TContext} is not an option.
* takes a {@link ReaderFunc} is not an option.
*
* @param nestedReader nested (child) reader to be advanced
* @param nestedReader nested (child) reader to be advanced.
* @return {@link Result#SUCCESS} if the read is successful, an error {@link Result} otherwise.
*/
public Result skipScope(@Nonnull final RowReader nestedReader) {
if (nestedReader.cursor.start() != this.cursor.valueOffset()) {
@@ -954,7 +969,9 @@ public final class RowReader {
}
/**
* The storage placement of the field--if positioned on a field--undefined otherwise
* The storage placement of the field--if positioned on a field--undefined otherwise.
*
* @return storage kind.
*/
public StorageKind storage() {
switch (this.state) {
@@ -968,7 +985,9 @@ public final class RowReader {
}
/**
* The type of the field--if positioned on a field--undefined otherwise
* The type of the field--if positioned on a field--undefined otherwise.
*
* @return layout type.
*/
public LayoutType type() {
@@ -983,7 +1002,9 @@ public final class RowReader {
}
/**
* The type arguments of the field (if positioned on a field, undefined otherwise)
* The type arguments of the field, if positioned on a field, undefined otherwise.
*
* @return type argument list.
*/
public TypeArgumentList typeArgs() {

View File

@@ -72,6 +72,8 @@ public final class RowWriter {
/**
* The active layout of the current writer scope.
*
* @return layout of the current writer scope.
*/
public Layout layout() {
return this.cursor.layout();
@@ -79,6 +81,8 @@ public final class RowWriter {
/**
* The length of row in bytes.
*
* @return length of the row in bytes.
*/
public int length() {
return this.row.length();
@@ -86,6 +90,8 @@ public final class RowWriter {
/**
* The resolver for UDTs.
*
* @return the resolver of UDTs.
*/
public LayoutResolver resolver() {
return this.row.resolver();

View File

@@ -20,7 +20,7 @@ public final class RowReaderJsonExtensions {
* Project a JSON document from a HybridRow {@link RowReader}.
*
* @param reader The reader to project to JSON.
* @param string If {@link Result#SUCCESS}, the JSON document that corresponds to the {@code reader).
* @param string If {@link Result#SUCCESS}, the JSON document that corresponds to the {@code reader}.
* @return The result.
*/
@Nonnull
@@ -33,7 +33,7 @@ public final class RowReaderJsonExtensions {
*
* @param reader The reader to project to JSON.
* @param settings Settings that control how the JSON document is formatted.
* @param string If {@link Result#SUCCESS}, the JSON document that corresponds to the {@code reader).
* @param string If {@link Result#SUCCESS}, the JSON document that corresponds to the {@code reader}.
* @return The result.
*/
@Nonnull

View File

@@ -4,11 +4,10 @@
package com.azure.data.cosmos.serialization.hybridrow.json;
public final class RowReaderJsonSettings {
private String indentChars;
private char quoteChar;
public RowReaderJsonSettings(String indentChars) {
this(indentChars, '"');
}
@@ -24,14 +23,19 @@ public final class RowReaderJsonSettings {
/**
* If non-null then child objects are indented by one copy of this string per level.
*
* @return indentation characters.
*/
public String indentChars() {
return this.indentChars;
}
/**
* The quote character to use.
* May be <see cref="lang:\""/> or {@link '}.
* The current quote character.
* <p>
* May be double or single quote.
*
* @return quote character.
*/
public char quoteChar() {
return this.quoteChar;

View File

@@ -34,7 +34,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
public final class Layout {
public static final Layout EMPTY = SystemSchema.layoutResolver.resolve(SystemSchema.EMPTY_SCHEMA_ID);
public static final Layout EMPTY = SystemSchema.layoutResolver().resolve(SystemSchema.EMPTY_SCHEMA_ID);
private final String name;
private final int numBitmaskBytes;

View File

@@ -5,6 +5,7 @@ package com.azure.data.cosmos.serialization.hybridrow.layouts;
import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
import com.azure.data.cosmos.serialization.hybridrow.schemas.Namespace;
import com.google.common.base.Suppliers;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@@ -12,8 +13,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.function.Supplier;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Strings.lenientFormat;
public final class SystemSchema {
@@ -27,45 +30,36 @@ public final class SystemSchema {
* SchemaId of HybridRow RecordIO Record Headers.
*/
public static final SchemaId RECORD_SCHEMA_ID = SchemaId.from(2147473649);
/**
* SchemaId of HybridRow RecordIO Segments.
*/
public static final SchemaId SEGMENT_SCHEMA_ID = SchemaId.from(2147473648);
public static final LayoutResolver layoutResolver = SystemSchema.loadSchema();
@SuppressWarnings("StatementWithEmptyBody")
private static final Supplier<LayoutResolver> layoutResolver = Suppliers.memoize(() -> {
final String json;
try (final InputStream stream = SystemSchema.class.getResourceAsStream("SystemSchema.json")) {
ByteBuf buffer = Unpooled.buffer();
while (buffer.writeBytes(stream, 8192) == 8192) { }
json = buffer.readCharSequence(buffer.readableBytes(), StandardCharsets.UTF_8).toString();
} catch (IOException cause) {
String message = lenientFormat("failed to load SystemSchema.json due to %s", cause);
throw new IllegalStateException(message, cause);
}
Optional<Namespace> namespace = Namespace.parse(json);
checkState(namespace.isPresent(), "failed to load SystemSchema.json");
return new LayoutResolverNamespace(namespace.get());
});
private SystemSchema() {
}
/*
private static String FormatResourceName(Assembly assembly, String resourceName) {
return assembly.GetName().Name + "." + resourceName.replace(" ", "_").replace("\\", ".").replace("/", ".");
}
*/
static LayoutResolver loadSchema() {
final String json;
try {
json = SystemSchema.readFromResourceFile("system-schema.json");
} catch (IOException cause) {
throw new IllegalStateException("failed to load system-schema.json", cause);
}
Optional<Namespace> ns = Namespace.parse(json);
checkState(ns.isPresent(), "failed to load system-schema.json");
return new LayoutResolverNamespace(ns.get());
}
@SuppressWarnings("StatementWithEmptyBody")
private static String readFromResourceFile(String name) throws IOException {
try (final InputStream stream = SystemSchema.class.getResourceAsStream(name)) {
ByteBuf buffer = Unpooled.buffer();
while (buffer.writeBytes(stream, 8192) == 8192) {
}
return buffer.readCharSequence(buffer.readableBytes(), StandardCharsets.UTF_8).toString();
}
public static LayoutResolver layoutResolver() {
return layoutResolver.get();
}
}

View File

@@ -10,6 +10,7 @@ import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Optional;
@@ -52,7 +53,7 @@ public class Utf8StringTest {
}
@Test(dataProvider = "unicodeTextDataProvider")
public void testCodePoints(UnicodeTextItem item) {
public void testCodePoints(UnicodeText item) {
Utf8String value = Utf8String.transcodeUtf16(item.value());
assertEquals(value.codePoints().iterator(), item.value().codePoints().iterator());
}
@@ -71,7 +72,7 @@ public class Utf8StringTest {
@SuppressWarnings("EqualsWithItself")
@Test(dataProvider = "unicodeTextDataProvider")
public void testCompareTo(UnicodeTextItem item) {
public void testCompareTo(UnicodeText item) {
Utf8String value = Utf8String.transcodeUtf16(item.value());
assertEquals(value.compareTo(value), 0);
@@ -100,7 +101,7 @@ public class Utf8StringTest {
}
@Test(dataProvider = "unicodeTextDataProvider")
public void testEncodedLength(UnicodeTextItem item) {
public void testEncodedLength(UnicodeText item) {
final int encodedLength = item.buffer.length;
assertEquals(Utf8String.from(item.byteBuf()).orElseThrow(AssertionError::new).encodedLength(), encodedLength);
assertEquals(Utf8String.fromUnsafe(item.byteBuf()).encodedLength(), encodedLength);
@@ -108,7 +109,7 @@ public class Utf8StringTest {
}
@Test(dataProvider = "unicodeTextDataProvider")
public void testTestEquals(UnicodeTextItem item) {
public void testTestEquals(UnicodeText item) {
TestEquals testEquals = new TestEquals(item);
@@ -136,7 +137,7 @@ public class Utf8StringTest {
}
@Test(dataProvider = "unicodeTextDataProvider")
public void testFrom(UnicodeTextItem item) {
public void testFrom(UnicodeText item) {
Optional<Utf8String> value = Utf8String.from(item.byteBuf());
assertTrue(value.isPresent());
assertTrue(value.get().equals(value.get()));
@@ -145,7 +146,7 @@ public class Utf8StringTest {
}
@Test(dataProvider = "unicodeTextDataProvider")
public void testFromUnsafe(UnicodeTextItem item) {
public void testFromUnsafe(UnicodeText item) {
Utf8String value = Utf8String.fromUnsafe(item.byteBuf());
assertTrue(value.equals(value));
assertTrue(value.equals(item.value()));
@@ -153,13 +154,13 @@ public class Utf8StringTest {
}
@Test(dataProvider = "unicodeTextDataProvider")
public void testHashCode(UnicodeTextItem item) {
public void testHashCode(UnicodeText item) {
Utf8String value = Utf8String.fromUnsafe(item.byteBuf());
assertEquals(value.hashCode(), item.byteBuf().hashCode());
}
@Test(dataProvider = "unicodeTextDataProvider")
public void testLength(UnicodeTextItem item) {
public void testLength(UnicodeText item) {
assertEquals(Utf8String.fromUnsafe(item.byteBuf()).length(), item.value().length());
}
@@ -168,12 +169,12 @@ public class Utf8StringTest {
}
@Test(dataProvider = "unicodeTextDataProvider")
public void testToUtf16(UnicodeTextItem item) {
public void testToUtf16(UnicodeText item) {
assertEquals(Utf8String.fromUnsafe(item.byteBuf()).toUtf16(), item.value());
}
@Test(dataProvider = "unicodeTextDataProvider")
public void testTranscodeUtf16(UnicodeTextItem item) {
public void testTranscodeUtf16(UnicodeText item) {
assertEquals(Utf8String.transcodeUtf16(item.value()).toUtf16(), item.value());
}
@@ -203,31 +204,31 @@ public class Utf8StringTest {
@DataProvider(name = "unicodeTextDataProvider")
private static Iterator<Object[]> unicodeTextData() {
ImmutableList<UnicodeTextItem> items = ImmutableList.of(
ImmutableList<UnicodeText> items = ImmutableList.of(
// US ASCII (7-bit encoding)
// ..English
new UnicodeTextItem("The quick brown fox jumps over the lazy dog."),
new UnicodeText("The quick brown fox jumps over the lazy dog."),
// ISO-8859-1 (8-bit encoding)
// ..German
new UnicodeTextItem("Der schnelle braune Fuchs springt über den faulen Hund."),
new UnicodeText("Der schnelle braune Fuchs springt über den faulen Hund."),
// ..Icelandic
new UnicodeTextItem("Skjótur brúni refurinn hoppar yfir lata hundinn."),
new UnicodeText("Skjótur brúni refurinn hoppar yfir lata hundinn."),
// ..Spanish
new UnicodeTextItem("El rápido zorro marrón salta sobre el perro perezoso."),
new UnicodeText("El rápido zorro marrón salta sobre el perro perezoso."),
// ISO 8859-7 (11-bit encoding)
// ..Greek
new UnicodeTextItem("Η γρήγορη καφέ αλεπού πηδάει πάνω από το τεμπέλικο σκυλί."),
new UnicodeText("Η γρήγορη καφέ αλεπού πηδάει πάνω από το τεμπέλικο σκυλί."),
// Katakana code block (16-bit encoding)
// ..Japanese
new UnicodeTextItem("速い茶色のキツネは怠laな犬を飛び越えます。"),
new UnicodeText("速い茶色のキツネは怠laな犬を飛び越えます。"),
// Deseret code block (21-bit encoding containing an English alphabet invented by the LDS Church)
// ..Deseret
new UnicodeTextItem("\uD801\uDC10\uD801\uDC2F\uD801\uDC4A\uD801\uDC2C, \uD801\uDC38\uD801\uDC35 \uD801\uDC2A\uD801\uDC49 \uD801\uDC4F?")
new UnicodeText("\uD801\uDC10\uD801\uDC2F\uD801\uDC4A\uD801\uDC2C, \uD801\uDC38\uD801\uDC35 \uD801\uDC2A\uD801\uDC49 \uD801\uDC4F?")
);
return items.stream().map(item -> new Object[] { item }).iterator();
@@ -235,10 +236,10 @@ public class Utf8StringTest {
private static class TestEquals {
private final UnicodeTextItem item;
private final UnicodeText item;
private final Utf8String[] variants;
public TestEquals(UnicodeTextItem item) {
public TestEquals(UnicodeText item) {
this.item = item;
@@ -276,10 +277,10 @@ public class Utf8StringTest {
private static class TestNotEquals {
private final UnicodeTextItem item;
private final UnicodeText item;
private final Utf8String[] variants;
public TestNotEquals(UnicodeTextItem item) {
public TestNotEquals(UnicodeText item) {
this.item = item;
@@ -384,6 +385,30 @@ public class Utf8StringTest {
assertEquals(
normalize(ej.compareTo(Utf8String.transcodeUtf16(lj))),
normalize(lj.compareTo(lj)));
// Compare multi-character strings
String word1 = Arrays.stream(this.letters).skip(i).limit(j - i).reduce("", (w, c) -> w + c);
String word2 = Arrays.stream(this.letters).skip(j).limit(this.letters.length - j).reduce("", (w, c) -> w + c);
assertEquals(
normalize(Utf8String.transcodeUtf16(word1).compareTo(word1)),
normalize(word1.compareTo(word1)));
assertEquals(
normalize(Utf8String.transcodeUtf16(word1).compareTo(word2)),
normalize(word1.compareTo(word2)));
assertEquals(
normalize(Utf8String.transcodeUtf16(word2).compareTo(word1)),
normalize(word2.compareTo(word1)));
assertEquals(
normalize(Utf8String.transcodeUtf16(word1).compareTo(Utf8String.transcodeUtf16(word1))),
normalize(word1.compareTo(word1)));
assertEquals(
normalize(Utf8String.transcodeUtf16(word1).compareTo(Utf8String.transcodeUtf16(word2))),
normalize(word1.compareTo(word2)));
assertEquals(
normalize(Utf8String.transcodeUtf16(word2).compareTo(Utf8String.transcodeUtf16(word1))),
normalize(word2.compareTo(word1)));
}
@Override
@@ -396,12 +421,12 @@ public class Utf8StringTest {
}
}
private static class UnicodeTextItem {
private static class UnicodeText {
private final byte[] buffer;
private final String value;
UnicodeTextItem(String value) {
UnicodeText(String value) {
this.buffer = value.getBytes(StandardCharsets.UTF_8);
this.value = value;
}
@@ -416,7 +441,7 @@ public class Utf8StringTest {
@Override
public String toString() {
return this.value.toString();
return this.value;
}
public String value() {

View File

@@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.data.cosmos.serialization.hybridrow.layouts;
import org.testng.annotations.Test;
import java.nio.file.Path;
import java.nio.file.Paths;
import static org.testng.Assert.*;
public class SystemSchemaTest {
private static final Path SchemaFile = Paths.get("data", "CustomerSchema.json");
@Test
public void testLoadSchema() {
final LayoutResolver layoutResolver = SystemSchema.layoutResolver();
final Layout recordLayout = layoutResolver.resolve(SystemSchema.RECORD_SCHEMA_ID);
assertEquals(recordLayout.name(), "Record");
assertEquals(recordLayout.schemaId(), SystemSchema.RECORD_SCHEMA_ID);
final Layout segmentLayout = layoutResolver.resolve(SystemSchema.SEGMENT_SCHEMA_ID);
assertEquals(segmentLayout.name(), "Segment");
assertEquals(segmentLayout.schemaId(), SystemSchema.SEGMENT_SCHEMA_ID);
}
}