diff --git a/java/src/main/java/com/azure/data/cosmos/core/Json.java b/java/src/main/java/com/azure/data/cosmos/core/Json.java index 6b51eee..65b30c9 100644 --- a/java/src/main/java/com/azure/data/cosmos/core/Json.java +++ b/java/src/main/java/com/azure/data/cosmos/core/Json.java @@ -5,18 +5,31 @@ package com.azure.data.cosmos.core; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; import com.fasterxml.jackson.databind.ObjectWriter; +import java.io.IOException; +import java.util.Optional; + import static com.google.common.base.Strings.lenientFormat; public final class Json { private static final ObjectMapper mapper = new ObjectMapper(); + private static final ObjectReader reader = mapper.reader(); private static final ObjectWriter writer = mapper.writer(); private Json() { } + public static Optional parse(String value) { + try { + return Optional.of(reader.readValue(value)); + } catch (IOException e) { + return Optional.empty(); + } + } + public static String toString(Object object) { try { return writer.writeValueAsString(object); diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/Float128.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/Float128.java index b0038f3..19d1eb2 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/Float128.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/Float128.java @@ -27,6 +27,7 @@ public final class Float128 { * The size (in bytes) of a {@link Float128}. */ public static final int BYTES = 2 * Long.BYTES; + public static final Float128 ZERO = new Float128(0L, 0L); private final long high; private final long low; diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/RowBuffer.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/RowBuffer.java index e3b65a0..a843abd 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/RowBuffer.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/RowBuffer.java @@ -6,7 +6,6 @@ package com.azure.data.cosmos.serialization.hybridrow; import com.azure.data.cosmos.core.Out; -import com.azure.data.cosmos.core.Reference; import com.azure.data.cosmos.core.Utf8String; import com.azure.data.cosmos.serialization.hybridrow.codecs.DateTimeCodec; import com.azure.data.cosmos.serialization.hybridrow.codecs.DecimalCodec; @@ -70,6 +69,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.math.BigDecimal; import java.time.OffsetDateTime; +import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Optional; @@ -83,6 +83,8 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Strings.lenientFormat; +// import com.azure.data.cosmos.serialization.hybridrow.RowBuffer.UniqueIndexItem; + //import static com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutTypes.MongoDbObjectId; /** @@ -152,256 +154,6 @@ public final class RowBuffer { checkState(HybridRowHeader.BYTES + layout.size() <= this.length()); } - public void TypedCollectionMoveField(RowCursor dstEdit, RowCursor srcEdit, RowOptions options) { - - int encodedSize = this.sparseComputeSize(srcEdit); - int numBytes = encodedSize - (srcEdit.valueOffset() - srcEdit.metaOffset()); - - // Insert the field metadata into its new location. - int metaBytes; - Out tempOut_metaBytes = new Out(); - int spaceNeeded; - Out tempOut_spaceNeeded = new Out(); - int shiftInsert; - Out tempOut_shiftInsert = new Out(); - this.ensureSparse(numBytes, dstEdit, srcEdit.cellType(), srcEdit.cellTypeArgs(), - options, tempOut_metaBytes, tempOut_spaceNeeded, tempOut_shiftInsert); - shiftInsert = tempOut_shiftInsert.get(); - spaceNeeded = tempOut_spaceNeeded.get(); - metaBytes = tempOut_metaBytes.get(); - - this.writeSparseMetadata(dstEdit, srcEdit.cellType(), srcEdit.cellTypeArgs(), metaBytes); - checkState(spaceNeeded == metaBytes + numBytes); - if (srcEdit.metaOffset() >= dstEdit.metaOffset()) { - srcEdit.metaOffset(srcEdit.metaOffset() + shiftInsert); - srcEdit.valueOffset(srcEdit.valueOffset() + shiftInsert); - } - - // Copy the value bits from the old location. - this.buffer.Slice(srcEdit.valueOffset(), numBytes).CopyTo(this.buffer.Slice(dstEdit.valueOffset())); - this.length(this.length() + shiftInsert); - - // Delete the old location. - Out tempOut_metaBytes2 = new Out(); - Out tempOut_spaceNeeded2 = new Out(); - int shiftDelete; - Out tempOut_shiftDelete = new Out(); - this.ensureSparse(numBytes, srcEdit, srcEdit.cellType(), srcEdit.cellTypeArgs(), - RowOptions.DELETE, tempOut_metaBytes2, tempOut_spaceNeeded2, tempOut_shiftDelete); - shiftDelete = tempOut_shiftDelete.get(); - spaceNeeded = tempOut_spaceNeeded2.get(); - metaBytes = tempOut_metaBytes2.get(); - - checkState(shiftDelete < 0); - - // TODO: DANOBLE: Do not change writerIndex here (?) - this.buffer.writerIndex(this.length() + shiftDelete); - } - - /** - * Rebuild the unique index for a set/map scope. - * - * @param scope The sparse scope to rebuild an index for. - * @return Success if the index could be built, an error otherwise. - *

- * The MUST be a set or map scope. - *

- * 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: - * - * - * - * Be repaired (e.g. by deleting duplicates) and the index rebuild operation should be - * run again. - * - * - * Be deleted. The entire scope should be removed including its items. - * - * Failure to perform one of these actions will leave the row is potentially in a corrupted - * state where partial updates may subsequent fail. - *

- *

- * The target may or may not have already been indexed. This - * operation is idempotent. - *

- */ - public Result TypedCollectionUniqueIndexRebuild(@Nonnull final RowCursor scope) { - - checkNotNull(scope, "expected non-null scope"); - checkArgument(scope.scopeType().isUniqueScope()); - checkArgument(scope.index() == 0); - - RowCursor edit = scope.clone(); - - if (edit.count() <= 1) { - return Result.SUCCESS; - } - - // Compute Index Elements. - // TODO: C# TO JAVA CONVERTER: There is no equivalent to 'stackalloc' in Java: - UniqueIndexItem item; - Span uniqueIndex = edit.count() < 100 ? stackalloc UniqueIndexItem[edit.count()] : - new UniqueIndexItem[edit.count()]; - edit.metaOffset(scope.valueOffset()); - for (; edit.index() < edit.count(); edit.index(edit.index() + 1)) { - Reference tempReference_dstEdit = - new Reference(edit); - this.readSparseMetadata(tempReference_dstEdit); - edit = tempReference_dstEdit; - Contract.Assert(edit.pathOffset() == - default) - Reference tempReference_dstEdit2 = - new Reference(edit); - int elmSize = this.sparseComputeSize(tempReference_dstEdit2); - edit = tempReference_dstEdit2.get(); - - UniqueIndexItem tempVar = new UniqueIndexItem(); - tempVar.code(edit.cellType().LayoutCode); - tempVar.metaOffset(edit.metaOffset()); - tempVar.valueOffset(edit.valueOffset()); - tempVar.size(elmSize); - uniqueIndex[edit.index()] = tempVar.clone(); - - edit.metaOffset(edit.metaOffset() + elmSize); - } - - // Create scratch space equal to the sum of the sizes of the scope's values. - // Implementation Note: theoretically this scratch space could be eliminated by - // performing the item move operations directly during the Insertion Sort, however, - // doing so might result in moving the same item multiple times. Under the assumption - // that items are relatively large, using scratch space requires each item to be moved - // AT MOST once. Given that row buffer memory is likely reused, scratch space is - // relatively memory efficient. - int shift = edit.metaOffset() - scope.valueOffset(); - - // Sort and check for duplicates. - // TODO: C# TO JAVA CONVERTER: C# 'unsafe' code is not converted by C# to Java Converter: - Span p = new Span(Unsafe.AsPointer(ref uniqueIndex - .GetPinnableReference()), uniqueIndex.Length); - if (!this.insertionSort(scope, edit, p)) - { - return Result.Exists; - } - - // Move elements. - int metaOffset = scope.valueOffset(); - this.ensure(this.length() + shift); - this.buffer.Slice(metaOffset, this.length() - metaOffset).CopyTo(this.buffer.Slice(metaOffset + shift)); - for (UniqueIndexItem x : uniqueIndex) { - this.buffer.Slice(x.metaOffset() + shift, x.size()).CopyTo(this.buffer.Slice(metaOffset)); - metaOffset += x.size(); - } - - // Delete the scratch space (if necessary - if it doesn't just fall off the end of the row). - if (metaOffset != this.length()) { - this.buffer.Slice(metaOffset + shift, this.length() - metaOffset).CopyTo(this.buffer.Slice(metaOffset)); - } - - // TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java: - //#if DEBUG - // Fill deleted bits (in debug builds) to detect overflow/alignment errors. - this.buffer.Slice(this.length(), shift).Fill(0xFF); - //#endif - - return Result.SUCCESS; - } - - public void WriteSparseUDT(@Nonnull final RowCursor edit, LayoutScope scopeType, Layout udt, - UpdateOptions options, Out newScope) { - - TypeArgumentList typeArgs = new TypeArgumentList(udt.schemaId().clone()); - int numBytes = udt.size() + LayoutCode.BYTES; - int metaBytes; - final Out metaBytes = new Out<>(); - int spaceNeeded; - final Out spaceNeeded = new Out<>(); - int shift; - final Out shift = new Out<>(); - - final int priorLength = this.length(); - - this.ensureSparse(numBytes, edit, scopeType, typeArgs, options, metaBytes, - spaceNeeded, shift); - this.writeSparseMetadata(edit, scopeType, typeArgs, metaBytes); - - // Clear all presence bits. - this.buffer.Slice(edit.valueOffset(), udt.size()).Fill(0); - - // Write scope terminator. - int valueOffset = edit.valueOffset() + udt.size(); - this.writeSparseTypeCode(valueOffset, LayoutCode.END_SCOPE); - checkState(spaceNeeded == metaBytes + numBytes); - newScope.setAndGet(new RowCursor()); - newScope.get().scopeType(scopeType); - newScope.get().scopeTypeArgs(typeArgs); - newScope.get().start(edit.valueOffset()); - newScope.get().valueOffset(valueOffset); - newScope.get().metaOffset(valueOffset); - newScope.get().layout(udt); - - checkState(this.length() == priorLength + shift.get()); - } - - public void WriteTypedArray(@Nonnull final RowCursor edit, LayoutScope scopeType, TypeArgumentList typeArgs, - UpdateOptions options, Out newScope) { - int numBytes = Integer.BYTES; - int metaBytes; - final Out metaBytes = new Out<>(); - int spaceNeeded; - final Out spaceNeeded = new Out<>(); - int shift; - final Out shift = new Out<>(); - - final int priorLength = this.length(); - - this.ensureSparse(numBytes, edit, scopeType, typeArgs, options, metaBytes, - spaceNeeded, shift); - this.writeSparseMetadata(edit, scopeType, typeArgs, metaBytes); - checkState(spaceNeeded == metaBytes + numBytes); - this.writeUInt32(edit.valueOffset(), 0); - int valueOffset = edit.valueOffset() + (Integer.SIZE / Byte.SIZE); // Point after the Size - newScope.setAndGet(new RowCursor()); - newScope.get().scopeType(scopeType); - newScope.get().scopeTypeArgs(typeArgs); - newScope.get().start(edit.valueOffset()); - newScope.get().valueOffset(valueOffset); - newScope.get().metaOffset(valueOffset); - newScope.get().layout(edit.layout()); - - checkState(this.length() == priorLength + shift.get()); - } - - public void WriteTypedMap(@Nonnull final RowCursor edit, LayoutScope scopeType, TypeArgumentList typeArgs, - UpdateOptions options, Out newScope) { - int numBytes = Integer.BYTES; // Sized scope. - int metaBytes; - final Out metaBytes = new Out<>(); - int spaceNeeded; - final Out spaceNeeded = new Out<>(); - int shift; - final Out shift = new Out<>(); - - final int priorLength = this.length(); - - this.ensureSparse(numBytes, edit, scopeType, typeArgs, options, metaBytes, - spaceNeeded, shift); - this.writeSparseMetadata(edit, scopeType, typeArgs, metaBytes); - checkState(spaceNeeded == metaBytes + numBytes); - this.writeUInt32(edit.valueOffset(), 0); - int valueOffset = edit.valueOffset() + (Integer.SIZE / Byte.SIZE); // Point after the Size - newScope.setAndGet(new RowCursor()); - newScope.get().scopeType(scopeType); - newScope.get().scopeTypeArgs(typeArgs); - newScope.get().start(edit.valueOffset()); - newScope.get().valueOffset(valueOffset); - newScope.get().metaOffset(valueOffset); - newScope.get().layout(edit.layout()); - - checkState(this.length() == priorLength + shift.get()); - } - /** * Compute the byte offset from the beginning of the row for a given variable's value * @@ -442,25 +194,6 @@ public final class RowBuffer { return offset; } - // TODO: DANOBLE: ressurrect this method - // public void WriteSparseMongoDbObjectId(@Nonnull final RowCursor edit, MongoDbObjectId value, - // UpdateOptions options) { - // int numBytes = MongoDbObjectId.Size; - // int metaBytes; - // final Out metaBytes = new Out<>(); - // int spaceNeeded; - // final Out spaceNeeded = new Out<>(); - // int shift; - // final Out shift = new Out<>(); - // this.ensureSparse(numBytes, edit, MongoDbObjectId, TypeArgumentList.EMPTY, options, - // metaBytes, spaceNeeded, shift); - // this.writeSparseMetadata(edit, MongoDbObjectId, TypeArgumentList.EMPTY, metaBytes); - // this.WriteMongoDbObjectId(edit.valueOffset(), value.clone()); - // checkState(spaceNeeded == metaBytes + MongoDbObjectId.Size); - // edit.endOffset(edit.metaOffset() + spaceNeeded.get()); - // this.buffer.writerIndex(this.length() + shift); - // } - /** * Compute the number of bytes necessary to store the unsigned 32-bit integer value using the varuint encoding * @@ -538,16 +271,30 @@ public final class RowBuffer { return this.readHeader(); } + // TODO: DANOBLE: ressurrect this method + // public void WriteSparseMongoDbObjectId(@Nonnull final RowCursor edit, MongoDbObjectId value, + // UpdateOptions options) { + // int numBytes = MongoDbObjectId.Size; + // int metaBytes; + // final Out metaBytes = new Out<>(); + // int spaceNeeded; + // final Out spaceNeeded = new Out<>(); + // int shift; + // final Out shift = new Out<>(); + // this.ensureSparse(numBytes, edit, MongoDbObjectId, TypeArgumentList.EMPTY, options, + // metaBytes, spaceNeeded, shift); + // this.writeSparseMetadata(edit, MongoDbObjectId, TypeArgumentList.EMPTY, metaBytes); + // this.WriteMongoDbObjectId(edit.valueOffset(), value.clone()); + // checkState(spaceNeeded == metaBytes + MongoDbObjectId.Size); + // edit.endOffset(edit.metaOffset() + spaceNeeded.get()); + // this.buffer.writerIndex(this.length() + shift); + // } + public void incrementUInt32(final int offset, final long increment) { final long value = this.buffer.getUnsignedIntLE(offset); this.buffer.setIntLE(offset, (int) (value + increment)); } - // TODO: DANOBLE: resurrect this method - // public MongoDbObjectId ReadMongoDbObjectId(int offset) { - // return MemoryMarshal.Read(this.buffer.Slice(offset)); - // } - /** * Initializes a row to the minimal size for the given layout. * @@ -640,6 +387,11 @@ public final class RowBuffer { return item.value(); } + // TODO: DANOBLE: resurrect this method + // public MongoDbObjectId ReadMongoDbObjectId(int offset) { + // return MemoryMarshal.Read(this.buffer.Slice(offset)); + // } + public boolean readBit(final int offset, @Nonnull final LayoutBit bit) { checkNotNull(bit, "expected non-null bit"); @@ -652,13 +404,6 @@ public final class RowBuffer { return item.value(); } - // TODO: DANOBLE: resurrect this method - // public MongoDbObjectId ReadSparseMongoDbObjectId(Reference edit) { - // this.readSparsePrimitiveTypeCode(edit, MongoDbObjectId); - // edit.endOffset = edit.valueOffset() + MongoDbObjectId.Size; - // return this.ReadMongoDbObjectId(edit.valueOffset()).clone(); - // } - public OffsetDateTime readDateTime(int offset) { Item item = this.read(() -> DateTimeCodec.decode(this.buffer), offset); return item.value(); @@ -684,6 +429,13 @@ public final class RowBuffer { return item.value(); } + // TODO: DANOBLE: resurrect this method + // public MongoDbObjectId ReadSparseMongoDbObjectId(Reference edit) { + // this.readSparsePrimitiveTypeCode(edit, MongoDbObjectId); + // edit.endOffset = edit.valueOffset() + MongoDbObjectId.Size; + // return this.ReadMongoDbObjectId(edit.valueOffset()).clone(); + // } + public float readFloat32(int offset) { Item item = this.read(this.buffer::readFloatLE, offset); return item.value(); @@ -997,14 +749,6 @@ public final class RowBuffer { return item.value(); } - // TODO: DANOBLE: Support MongoDbObjectId values - // public void WriteMongoDbObjectId(int offset, MongoDbObjectId value) { - // Reference tempReference_value = - // new Reference(value); - // MemoryMarshal.Write(this.buffer.Slice(offset), tempReference_value); - // value = tempReference_value.get(); - // } - public long readVariableInt(int offset) { Item item = this.read(this::read7BitEncodedInt, offset); return item.value(); @@ -1035,6 +779,14 @@ public final class RowBuffer { return this.resolver; } + // TODO: DANOBLE: Support MongoDbObjectId values + // public void WriteMongoDbObjectId(int offset, MongoDbObjectId value) { + // Reference tempReference_value = + // new Reference(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 * @@ -1168,7 +920,7 @@ public final class RowBuffer { if (scopeType instanceof LayoutTypedArray || scopeType instanceof LayoutTypedSet || scopeType instanceof LayoutTypedMap) { - final int valueOffset = edit.valueOffset() + (Integer.SIZE / Byte.SIZE); // Point after the Size + final int valueOffset = edit.valueOffset() + Integer.BYTES; // Point after the Size return new RowCursor() .scopeType(scopeType) @@ -1257,6 +1009,150 @@ public final class RowBuffer { return content; } + public void typedCollectionMoveField( + @Nonnull final RowCursor dstEdit, + @Nonnull final RowCursor srcEdit, + @Nonnull final RowOptions options) { + + final int length = this.sparseComputeSize(srcEdit) - (srcEdit.valueOffset() - srcEdit.metaOffset()); + + // Insert the field metadata into its new location + + Out metaBytes = new Out<>(); + Out spaceNeeded = new Out<>(); + Out shiftInsert = new Out<>(); + Out shiftDelete = new Out<>(); + + final int priorLength = this.length(); + + this.ensureSparse( + length, dstEdit, srcEdit.cellType(), srcEdit.cellTypeArgs(), options, metaBytes, spaceNeeded, shiftInsert); + this.writeSparseMetadata(dstEdit, srcEdit.cellType(), srcEdit.cellTypeArgs(), metaBytes.get()); + + if (srcEdit.metaOffset() >= dstEdit.metaOffset()) { + srcEdit.metaOffset(srcEdit.metaOffset() + shiftInsert.get()); + srcEdit.valueOffset(srcEdit.valueOffset() + shiftInsert.get()); + } + + // Copy the value bits from the old location + + this.writeFixedBinary(dstEdit.valueOffset(), this.buffer, srcEdit.valueOffset(), length); + + checkState(spaceNeeded.get() == metaBytes.get() + length); + checkState(this.length() == priorLength + shiftInsert.get()); + + // Delete the old location + + this.ensureSparse( + length, srcEdit, srcEdit.cellType(), srcEdit.cellTypeArgs(), RowOptions.DELETE, metaBytes, spaceNeeded, + shiftDelete); + + checkState(shiftDelete.get() < 0); + checkState(spaceNeeded.get() == metaBytes.get() + length); + checkState(this.length() == priorLength + shiftDelete.get()); + } + + /** + * Rebuild the unique index for a set/map scope. + * + * @param scope The sparse scope to rebuild an index for. + * @return Success if the index could be built, an error otherwise. + *

+ * The MUST be a set or map scope. + *

+ * 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: + * + * + * + * Be repaired (e.g. by deleting duplicates) and the index rebuild operation should be + * run again. + * + * + * Be deleted. The entire scope should be removed including its items. + * + * Failure to perform one of these actions will leave the row is potentially in a corrupted + * state where partial updates may subsequent fail. + *

+ *

+ * The target may or may not have already been indexed. This + * operation is idempotent. + *

+ */ + @Nonnull + public Result typedCollectionUniqueIndexRebuild(@Nonnull final RowCursor scope) { + + checkNotNull(scope, "expected non-null scope"); + checkArgument(scope.scopeType().isUniqueScope(), "expected unique scope type"); + checkArgument(scope.index() == 0, "expected scope index of zero"); + + RowCursor edit = scope.clone(); + + if (edit.count() <= 1) { + return Result.SUCCESS; + } + + // Compute index elements + + UniqueIndexItem[] uniqueIndex = new UniqueIndexItem[edit.count()]; + edit.metaOffset(scope.valueOffset()); + + for (; edit.index() < edit.count(); edit.index(edit.index() + 1)) { + + final RowCursor dstEdit = new RowCursor(); + this.readSparseMetadata(dstEdit); + + checkState(edit.pathOffset() == 0); + + final int elementSize = this.sparseComputeSize(edit); + + uniqueIndex[edit.index()] = new UniqueIndexItem() + .code(edit.cellType().layoutCode()) + .metaOffset(edit.metaOffset()) + .valueOffset(edit.valueOffset()) + .size(elementSize); + + edit.metaOffset(edit.metaOffset() + elementSize); + } + + // Create scratch space equal to the sum of the sizes of the scope's values. + // Implementation Note: theoretically this scratch space could be eliminated by + // performing the item move operations directly during the Insertion Sort, however, + // doing so might result in moving the same item multiple times. Under the assumption + // that items are relatively large, using scratch space requires each item to be moved + // AT MOST once. Given that row buffer memory is likely reused, scratch space is + // relatively memory efficient. + + int shift = edit.metaOffset() - scope.valueOffset(); + + // Sort and check for duplicates + + if (!this.insertionSort(scope, edit, Arrays.asList(uniqueIndex))) { + return Result.EXISTS; + } + + // Move elements + + int metaOffset = scope.valueOffset(); + this.ensure(this.length() + shift); + this.writeFixedBinary(metaOffset + shift, this.buffer, metaOffset, this.length() - metaOffset); + + for (UniqueIndexItem item : uniqueIndex) { + this.writeFixedBinary(metaOffset, this.buffer, item.metaOffset() + shift, item.size()); + metaOffset += item.size(); + } + + // Delete the scratch space (if necessary - if it doesn't just fall off the end of the row) + + if (metaOffset != this.length()) { + this.writeFixedBinary(metaOffset, this.buffer, metaOffset + shift, this.length() - metaOffset); + } + + return Result.SUCCESS; + } + public void unsetBit(final int offset, @Nonnull final LayoutBit bit) { checkNotNull(bit, "expected non-null bit"); checkArgument(!bit.isInvalid()); @@ -1299,7 +1195,6 @@ public final class RowBuffer { } public void writeFixedBinary(final int offset, @Nonnull final ByteBuf value, final int length) { - checkNotNull(value, "expected non-null value"); checkArgument(offset >= 0, "expected offset >= 0, not %s", offset); checkArgument(length >= 0, "expected length >= 0, not %s", length); @@ -1313,6 +1208,13 @@ public final class RowBuffer { }, offset, value); } + public void writeFixedBinary(final int offset, @Nonnull final ByteBuf value, final int index, final int length) { + checkArgument(index >= 0, "expected index >= 0, not %s", index); + value.markReaderIndex().readerIndex(index); + this.writeFixedBinary(offset, value, length); + value.resetReaderIndex(); + } + public void writeFixedBinary(final int offset, @Nonnull final byte[] value, final int index, final int length) { checkNotNull(value, "expected non-null value"); @@ -1888,6 +1790,43 @@ public final class RowBuffer { this.writeUInt8(offset, code.value()); } + @Nonnull + public RowCursor writeSparseUDT( + @Nonnull final RowCursor edit, + @Nonnull final LayoutScope scope, + @Nonnull final Layout udt, + @Nonnull final UpdateOptions options) { + + TypeArgumentList typeArgs = new TypeArgumentList(udt.schemaId()); + int length = udt.size() + LayoutCode.BYTES; + + final Out metaBytes = new Out<>(); + final Out spaceNeeded = new Out<>(); + final Out shift = new Out<>(); + + final int priorLength = this.length(); + + this.ensureSparse(length, edit, scope, typeArgs, options, metaBytes, spaceNeeded, shift); + this.writeSparseMetadata(edit, scope, typeArgs, metaBytes.get()); + this.write(this.buffer::writeZero, edit.valueOffset(), udt.size()); // clear all presence bits + + // Write scope terminator + + int valueOffset = edit.valueOffset() + udt.size(); + this.writeSparseTypeCode(valueOffset, LayoutCode.END_SCOPE); + + checkState(spaceNeeded.get() == metaBytes.get() + length); + checkState(this.length() == priorLength + shift.get()); + + return new RowCursor() + .scopeType(scope) + .scopeTypeArgs(typeArgs) + .start(edit.valueOffset()) + .valueOffset(valueOffset) + .metaOffset(valueOffset) + .layout(udt); + } + public void writeSparseUInt16( @Nonnull final RowCursor edit, final short value, @Nonnull final UpdateOptions options) { @@ -2074,6 +2013,71 @@ public final class RowBuffer { this.buffer.getBytes(0, stream, this.length()); } + @Nonnull + public RowCursor writeTypedArray( + @Nonnull final RowCursor edit, + @Nonnull final LayoutScope scope, + @Nonnull final TypeArgumentList typeArgs, + @Nonnull final UpdateOptions options) { + + final int length = Integer.BYTES; + final Out metaBytes = new Out<>(); + final Out spaceNeeded = new Out<>(); + final Out shift = new Out<>(); + + final int priorLength = this.length(); + + this.ensureSparse(length, edit, scope, typeArgs, options, metaBytes, spaceNeeded, shift); + this.writeSparseMetadata(edit, scope, typeArgs, metaBytes.get()); + this.writeUInt32(edit.valueOffset(), 0); + + checkState(spaceNeeded.get() == metaBytes.get() + length); + checkState(this.length() == priorLength + shift.get()); + + int valueOffset = edit.valueOffset() + Integer.BYTES; // point after the size + + return new RowCursor() + .scopeType(scope) + .scopeTypeArgs(typeArgs) + .start(edit.valueOffset()) + .valueOffset(valueOffset) + .metaOffset(valueOffset) + .layout(edit.layout()); + } + + @Nonnull + public RowCursor writeTypedMap( + @Nonnull final RowCursor edit, + @Nonnull final LayoutScope scope, + @Nonnull final TypeArgumentList typeArgs, + @Nonnull final UpdateOptions options) { + + final int length = Integer.BYTES; // sized scope + + final Out metaBytes = new Out<>(); + final Out spaceNeeded = new Out<>(); + final Out shift = new Out<>(); + + final int priorLength = this.length(); + + this.ensureSparse(length, edit, scope, typeArgs, options, metaBytes, spaceNeeded, shift); + this.writeSparseMetadata(edit, scope, typeArgs, metaBytes.get()); + this.writeUInt32(edit.valueOffset(), 0); + + checkState(spaceNeeded.get() == metaBytes.get() + length); + checkState(this.length() == priorLength + shift.get()); + + int valueOffset = edit.valueOffset() + Integer.BYTES; // point after the size + + return new RowCursor() + .scopeType(scope) + .scopeTypeArgs(typeArgs) + .start(edit.valueOffset()) + .valueOffset(valueOffset) + .metaOffset(valueOffset) + .layout(edit.layout()); + } + @Nonnull public RowCursor writeTypedSet( @Nonnull final RowCursor edit, @@ -2423,7 +2427,7 @@ public final class RowBuffer { } if (code instanceof LayoutTypedArray || code instanceof LayoutTypedSet || code instanceof LayoutTypedMap) { // Variable length typed collection scopes preceded by their scope size take sizeof(uint) for a size of 0. - return (Integer.SIZE / Byte.SIZE); + return Integer.BYTES; } if (code instanceof LayoutTuple) { // Fixed arity sparse collections take 1 byte for end-of-scope plus a null for each element. @@ -2874,7 +2878,7 @@ public final class RowBuffer { checkState(edit.pathOffset() == 0); checkState(edit.pathToken() == 0); } else { - int offset = edit.metaOffset() + LayoutCode.SIZE; + int offset = edit.metaOffset() + LayoutCode.BYTES; Out pathLenInBytes = new Out<>(); Out pathOffset = new Out<>(); int token = this.readSparsePathLen(edit.layout(), offset, pathLenInBytes, pathOffset); @@ -3147,7 +3151,7 @@ public final class RowBuffer { } if (code == LayoutTypes.FLOAT_128) { - this.writeFloat128(offset, null); + this.writeFloat128(offset, Float128.ZERO); return LayoutTypes.FLOAT_128.size(); } @@ -3162,12 +3166,12 @@ public final class RowBuffer { } if (code == LayoutTypes.UNIX_DATE_TIME) { - this.writeUnixDateTime(offset, null); + this.writeUnixDateTime(offset, UnixDateTime.EPOCH); return LayoutTypes.UNIX_DATE_TIME.size(); } if (code == LayoutTypes.GUID) { - this.writeGuid(offset, null); + this.writeGuid(offset, GuidCodec.EMPTY); return LayoutTypes.GUID.size(); } @@ -3179,8 +3183,8 @@ public final class RowBuffer { } if (code == LayoutTypes.UTF_8 || code == LayoutTypes.BINARY || code == LayoutTypes.VAR_INT || code == LayoutTypes.VAR_UINT) { - // Variable length types preceded by their varuint size take 1 byte for a size of 0. - return this.write7BitEncodedUInt(offset, 0); + // Variable length types preceded by their varuint size take 1 byte for a size of 0 + return this.write(this::write7BitEncodedUInt, offset, 0L).length(); } if (code == LayoutTypes.OBJECT || code == LayoutTypes.ARRAY) { @@ -3192,7 +3196,7 @@ public final class RowBuffer { if (code == LayoutTypes.TYPED_ARRAY || code == LayoutTypes.TypedSet || code == LayoutTypes.TypedMap) { // Variable length typed collection scopes preceded by their scope size take sizeof(uint) for a size of 0. this.writeUInt32(offset, 0); - return (Integer.SIZE / Byte.SIZE); + return Integer.BYTES; } if (code == LayoutTypes.TUPLE) { @@ -3223,14 +3227,15 @@ public final class RowBuffer { if (code == LayoutTypes.UDT) { - // Clear all presence bits. + // Clear all presence bits Layout udt = this.resolver.resolve(typeArgs.schemaId()); - this.buffer.Slice(offset, udt.size()).Fill(0); + this.write(this.buffer::writeZero, offset, udt.size()); - // Write scope terminator. + // Write scope terminator this.writeSparseTypeCode(offset + udt.size(), LayoutCode.END_SCOPE); return udt.size() + LayoutCode.BYTES; } + throw new IllegalStateException(lenientFormat("Not Implemented: %s", code)); } @@ -3291,6 +3296,7 @@ public final class RowBuffer { } } + private void writeUInt16(Short value) { this.buffer.writeShortLE(value); } @@ -3361,20 +3367,20 @@ public final class RowBuffer { */ static final class UniqueIndexItem { - private LayoutCode Code = LayoutCode.values()[0]; - private int MetaOffset; - private int Size; - private int ValueOffset; + private LayoutCode code = LayoutCode.values()[0]; + private int metaOffset; + private int size; + private int valueOffset; /** * The layout code of the value. */ public LayoutCode code() { - return this.Code; + return this.code; } public UniqueIndexItem code(LayoutCode code) { - this.Code = code; + this.code = code; return this; } @@ -3382,11 +3388,11 @@ public final class RowBuffer { * If existing, the offset to the metadata of the existing field, otherwise the location to insert a new field */ public int metaOffset() { - return this.MetaOffset; + return this.metaOffset; } public UniqueIndexItem metaOffset(int metaOffset) { - this.MetaOffset = metaOffset; + this.metaOffset = metaOffset; return this; } @@ -3394,11 +3400,11 @@ public final class RowBuffer { * Size of the target element */ public int size() { - return this.Size; + return this.size; } public UniqueIndexItem size(int size) { - this.Size = size; + this.size = size; return this; } @@ -3406,11 +3412,11 @@ public final class RowBuffer { * If existing, the offset to the value of the existing field, otherwise undefined */ public int valueOffset() { - return this.ValueOffset; + return this.valueOffset; } public UniqueIndexItem valueOffset(int valueOffset) { - this.ValueOffset = valueOffset; + this.valueOffset = valueOffset; return this; } } diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/codecs/GuidCodec.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/codecs/GuidCodec.java index e163b49..5de77d6 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/codecs/GuidCodec.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/codecs/GuidCodec.java @@ -15,6 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull; public final class GuidCodec { public static final int BYTES = 2 * Long.BYTES; + public static final UUID EMPTY = new UUID(0L, 0L); private GuidCodec() { } diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/io/RowWriter.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/io/RowWriter.java index f444e88..6c99c00 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/io/RowWriter.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/io/RowWriter.java @@ -410,7 +410,7 @@ public final class RowWriter { new Reference(this.cursor); Out tempOut_nestedScope3 = new Out(); - this.row.WriteTypedArray(tempRef_cursor3, scopeType, typeArg.typeArgs().clone(), + this.row.writeTypedArray(tempRef_cursor3, scopeType, typeArg.typeArgs().clone(), UpdateOptions.Upsert, tempOut_nestedScope3); nestedScope = tempOut_nestedScope3.get(); this.cursor = tempRef_cursor3.argValue; @@ -495,7 +495,7 @@ public final class RowWriter { new Reference(this.cursor); Out tempOut_nestedScope9 = new Out(); - this.row.WriteSparseUDT(tempReference_cursor9, scopeType, udt, UpdateOptions.Upsert, tempOut_nestedScope9); + this.row.writeSparseUDT(tempReference_cursor9, scopeType, udt, UpdateOptions.Upsert, tempOut_nestedScope9); nestedScope = tempOut_nestedScope9.get(); this.cursor = tempReference_cursor9.get(); break; @@ -522,8 +522,8 @@ public final class RowWriter { new Reference(this.cursor); Out tempOut_nestedScope11 = new Out(); - this.row.WriteTypedMap(tempRef_cursor11, scopeType, typeArg.typeArgs().clone(), - UpdateOptions.Upsert, tempOut_nestedScope11); + this.row.writeTypedMap(tempRef_cursor11, scopeType, typeArg.typeArgs().clone(), + UpdateOptions.Upsert); nestedScope = tempOut_nestedScope11.get(); this.cursor = tempRef_cursor11.argValue; @@ -556,7 +556,7 @@ public final class RowWriter { if (type instanceof LayoutUniqueScope) { Reference tempReference_nestedScope2 = new Reference(nestedScope); - result = this.row.TypedCollectionUniqueIndexRebuild(tempReference_nestedScope2); + result = this.row.typedCollectionUniqueIndexRebuild(tempReference_nestedScope2); nestedScope = tempReference_nestedScope2.get(); if (result != Result.SUCCESS) { // TODO: If the index rebuild fails then the row is corrupted. Should we automatically clean up here? diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/Layout.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/Layout.java index c06e4ec..047aab4 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/Layout.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/Layout.java @@ -13,12 +13,9 @@ import com.google.common.collect.ImmutableList; import javax.annotation.Nonnull; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Optional; -import java.util.stream.Stream; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -30,7 +27,7 @@ import static com.google.common.base.Preconditions.checkNotNull; * order and type of columns defines the physical ordering of bytes used to encode the row and impacts the cost of * updating the row. *

- * A layout is created by compiling a {@link Schema} through {@link Schema#Compile(Namespace)} or by constructor through + * A layout is created by compiling a {@link Schema} through {@link Schema#compile(Namespace)} or by constructor through * a {@link LayoutBuilder}. * * {@link Layout} is immutable. diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutCompiler.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutCompiler.java index 386ed12..ee2364d 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutCompiler.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutCompiler.java @@ -38,12 +38,12 @@ public final class LayoutCompiler { public static Layout Compile(Namespace ns, Schema schema) { checkArgument(ns != null); checkArgument(schema != null); - checkArgument(schema.getType() == TypeKind.Schema); - checkArgument(!tangible.StringHelper.isNullOrWhiteSpace(schema.getName())); - checkArgument(ns.getSchemas().contains(schema)); + checkArgument(schema.type() == TypeKind.Schema); + checkArgument(!tangible.StringHelper.isNullOrWhiteSpace(schema.name())); + checkArgument(ns.schemas().contains(schema)); - LayoutBuilder builder = new LayoutBuilder(schema.getName(), schema.getSchemaId().clone()); - LayoutCompiler.AddProperties(builder, ns, LayoutCode.SCHEMA, schema.getProperties()); + LayoutBuilder builder = new LayoutBuilder(schema.name(), schema.schemaId().clone()); + LayoutCompiler.AddProperties(builder, ns, LayoutCode.SCHEMA, schema.properties()); return builder.build(); } @@ -54,17 +54,17 @@ public final class LayoutCompiler { TypeArgumentList typeArgs = new TypeArgumentList(); Out tempOut_typeArgs = new Out(); - LayoutType type = LayoutCompiler.LogicalToPhysicalType(ns, p.getPropertyType(), tempOut_typeArgs); + LayoutType type = LayoutCompiler.LogicalToPhysicalType(ns, p.propertyType(), tempOut_typeArgs); typeArgs = tempOut_typeArgs.get(); switch (LayoutCodeTraits.ClearImmutableBit(type.LayoutCode)) { case OBJECT_SCOPE: { - if (!p.getPropertyType().getNullable()) { + if (!p.propertyType().nullable()) { throw new LayoutCompilationException("Non-nullable sparse column are not supported."); } - ObjectPropertyType op = (ObjectPropertyType)p.getPropertyType(); - builder.addObjectScope(p.getPath(), type); - LayoutCompiler.AddProperties(builder, ns, type.LayoutCode, op.getProperties()); + ObjectPropertyType op = (ObjectPropertyType)p.propertyType(); + builder.addObjectScope(p.path(), type); + LayoutCompiler.AddProperties(builder, ns, type.LayoutCode, op.properties()); builder.EndObjectScope(); break; } @@ -80,11 +80,11 @@ public final class LayoutCompiler { case TAGGED_SCOPE: case TAGGED2_SCOPE: case SCHEMA: { - if (!p.getPropertyType().getNullable()) { + if (!p.propertyType().nullable()) { throw new LayoutCompilationException("Non-nullable sparse column are not supported."); } - builder.addTypedScope(p.getPath(), type, typeArgs.clone()); + builder.addTypedScope(p.path(), type, typeArgs.clone()); break; } @@ -93,23 +93,23 @@ public final class LayoutCompiler { } default: { - PropertyType tempVar = p.getPropertyType(); + PropertyType tempVar = p.propertyType(); PrimitivePropertyType pp = tempVar instanceof PrimitivePropertyType ? (PrimitivePropertyType)tempVar : null; if (pp != null) { - switch (pp.getStorage()) { + switch (pp.storage()) { case Fixed: if (LayoutCodeTraits.ClearImmutableBit(scope) != LayoutCode.SCHEMA) { throw new LayoutCompilationException("Cannot have fixed storage within a sparse " + "scope."); } - if (type.getIsNull() && !pp.getNullable()) { + if (type.getIsNull() && !pp.nullable()) { throw new LayoutCompilationException("Non-nullable null columns are not supported" + "."); } - builder.addFixedColumn(p.getPath(), type, pp.getNullable(), pp.getLength()); + builder.addFixedColumn(p.path(), type, pp.nullable(), pp.length()); break; case Variable: if (LayoutCodeTraits.ClearImmutableBit(scope) != LayoutCode.SCHEMA) { @@ -117,24 +117,24 @@ public final class LayoutCompiler { "sparse scope."); } - if (!pp.getNullable()) { + if (!pp.nullable()) { throw new LayoutCompilationException("Non-nullable variable columns are not " + "supported."); } - builder.addVariableColumn(p.getPath(), type, pp.getLength()); + builder.addVariableColumn(p.path(), type, pp.length()); break; case Sparse: - if (!pp.getNullable()) { + if (!pp.nullable()) { throw new LayoutCompilationException("Non-nullable sparse columns are not " + "supported."); } - builder.addSparseColumn(p.getPath(), type); + builder.addSparseColumn(p.path(), type); break; default: throw new LayoutCompilationException(String.format("Unknown storage specification: " + - "%1$s", pp.getStorage())); + "%1$s", pp.storage())); } } else { throw new LayoutCompilationException(String.format("Unknown property type: %1$s", @@ -151,12 +151,12 @@ public final class LayoutCompiler { Out typeArgs) { typeArgs.setAndGet(TypeArgumentList.EMPTY); boolean tempVar = - (logicalType instanceof ScopePropertyType ? (ScopePropertyType)logicalType : null).getImmutable(); + (logicalType instanceof ScopePropertyType ? (ScopePropertyType)logicalType : null).immutable(); boolean immutable = (logicalType instanceof ScopePropertyType ? (ScopePropertyType)logicalType : null) == null ? null : tempVar != null && tempVar; - switch (logicalType.getType()) { + switch (logicalType.type()) { case Null: return LayoutType.Null; case Boolean: @@ -206,12 +206,12 @@ public final class LayoutCompiler { return immutable ? LayoutType.ImmutableObject : LayoutType.Object; case Array: ArrayPropertyType ap = (ArrayPropertyType)logicalType; - if ((ap.getItems() != null) && (ap.getItems().getType() != TypeKind.Any)) { + if ((ap.items() != null) && (ap.items().type() != TypeKind.Any)) { TypeArgumentList itemTypeArgs = new TypeArgumentList(); Out tempOut_itemTypeArgs = new Out(); - LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, ap.getItems(), tempOut_itemTypeArgs); + LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, ap.items(), tempOut_itemTypeArgs); itemTypeArgs = tempOut_itemTypeArgs.get(); - if (ap.getItems().getNullable()) { + if (ap.items().nullable()) { itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType, itemTypeArgs.clone()) }); itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable; @@ -225,13 +225,13 @@ public final class LayoutCompiler { return immutable ? LayoutType.ImmutableArray : LayoutType.Array; case Set: SetPropertyType sp = (SetPropertyType)logicalType; - if ((sp.getItems() != null) && (sp.getItems().getType() != TypeKind.Any)) { + if ((sp.items() != null) && (sp.items().type() != TypeKind.Any)) { TypeArgumentList itemTypeArgs = new TypeArgumentList(); Out tempOut_itemTypeArgs2 = new Out(); - LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, sp.getItems(), + LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, sp.items(), tempOut_itemTypeArgs2); itemTypeArgs = tempOut_itemTypeArgs2.get(); - if (sp.getItems().getNullable()) { + if (sp.items().nullable()) { itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType, itemTypeArgs.clone()) }); itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable; @@ -244,16 +244,16 @@ public final class LayoutCompiler { // TODO(283638): implement sparse set. throw new LayoutCompilationException(String.format("Unknown property type: %1$s", - logicalType.getType())); + logicalType.type())); case Map: MapPropertyType mp = (MapPropertyType)logicalType; - if ((mp.getKeys() != null) && (mp.getKeys().getType() != TypeKind.Any) && (mp.getValues() != null) && (mp.getValues().getType() != TypeKind.Any)) { + if ((mp.keys() != null) && (mp.keys().type() != TypeKind.Any) && (mp.values() != null) && (mp.values().type() != TypeKind.Any)) { TypeArgumentList keyTypeArgs = new TypeArgumentList(); Out tempOut_keyTypeArgs = new Out(); - LayoutType keyType = LayoutCompiler.LogicalToPhysicalType(ns, mp.getKeys(), tempOut_keyTypeArgs); + LayoutType keyType = LayoutCompiler.LogicalToPhysicalType(ns, mp.keys(), tempOut_keyTypeArgs); keyTypeArgs = tempOut_keyTypeArgs.get(); - if (mp.getKeys().getNullable()) { + if (mp.keys().nullable()) { keyTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(keyType, keyTypeArgs.clone()) }); keyType = keyType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable; @@ -261,10 +261,10 @@ public final class LayoutCompiler { TypeArgumentList valueTypeArgs = new TypeArgumentList(); Out tempOut_valueTypeArgs = new Out(); - LayoutType valueType = LayoutCompiler.LogicalToPhysicalType(ns, mp.getValues(), + LayoutType valueType = LayoutCompiler.LogicalToPhysicalType(ns, mp.values(), tempOut_valueTypeArgs); valueTypeArgs = tempOut_valueTypeArgs.get(); - if (mp.getValues().getNullable()) { + if (mp.values().nullable()) { valueTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(valueType, valueTypeArgs.clone()) }); valueType = valueType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable; @@ -280,18 +280,18 @@ public final class LayoutCompiler { // TODO(283638): implement sparse map. throw new LayoutCompilationException(String.format("Unknown property type: %1$s", - logicalType.getType())); + logicalType.type())); case Tuple: TuplePropertyType tp = (TuplePropertyType)logicalType; - TypeArgument[] args = new TypeArgument[tp.getItems().size()]; - for (int i = 0; i < tp.getItems().size(); i++) { + TypeArgument[] args = new TypeArgument[tp.items().size()]; + for (int i = 0; i < tp.items().size(); i++) { TypeArgumentList itemTypeArgs = new TypeArgumentList(); Out tempOut_itemTypeArgs3 = new Out(); - LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, tp.getItems().get(i), + LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, tp.items().get(i), tempOut_itemTypeArgs3); itemTypeArgs = tempOut_itemTypeArgs3.get(); - if (tp.getItems().get(i).getNullable()) { + if (tp.items().get(i).nullable()) { itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType, itemTypeArgs.clone()) }); itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable; @@ -305,21 +305,21 @@ public final class LayoutCompiler { case Tagged: TaggedPropertyType tg = (TaggedPropertyType)logicalType; - if ((tg.getItems().size() < TaggedPropertyType.MinTaggedArguments) || (tg.getItems().size() > TaggedPropertyType.MaxTaggedArguments)) { + if ((tg.items().size() < TaggedPropertyType.MinTaggedArguments) || (tg.items().size() > TaggedPropertyType.MaxTaggedArguments)) { throw new LayoutCompilationException(String.format("Invalid number of arguments in Tagged: %1$s " + - "<= %2$s <= %3$s", TaggedPropertyType.MinTaggedArguments, tg.getItems().size(), + "<= %2$s <= %3$s", TaggedPropertyType.MinTaggedArguments, tg.items().size(), TaggedPropertyType.MaxTaggedArguments)); } - TypeArgument[] tgArgs = new TypeArgument[tg.getItems().size() + 1]; + TypeArgument[] tgArgs = new TypeArgument[tg.items().size() + 1]; tgArgs[0] = new TypeArgument(LayoutType.UInt8, TypeArgumentList.EMPTY); - for (int i = 0; i < tg.getItems().size(); i++) { + for (int i = 0; i < tg.items().size(); i++) { TypeArgumentList itemTypeArgs = new TypeArgumentList(); Out tempOut_itemTypeArgs4 = new Out(); - LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, tg.getItems().get(i), + LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, tg.items().get(i), tempOut_itemTypeArgs4); itemTypeArgs = tempOut_itemTypeArgs4.get(); - if (tg.getItems().get(i).getNullable()) { + if (tg.items().get(i).nullable()) { itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType, itemTypeArgs.clone()) }); itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable; @@ -329,7 +329,7 @@ public final class LayoutCompiler { } typeArgs.setAndGet(new TypeArgumentList(tgArgs)); - switch (tg.getItems().size()) { + switch (tg.items().size()) { case 1: return immutable ? LayoutType.ImmutableTagged : LayoutType.Tagged; case 2: @@ -341,28 +341,28 @@ public final class LayoutCompiler { case Schema: UdtPropertyType up = (UdtPropertyType)logicalType; Schema udtSchema; - if (SchemaId.opEquals(up.getSchemaId().clone(), SchemaId.INVALID)) { - udtSchema = tangible.ListHelper.find(ns.getSchemas(), s = up.getName().equals( > s.Name)) + if (SchemaId.opEquals(up.schemaId().clone(), SchemaId.INVALID)) { + udtSchema = tangible.ListHelper.find(ns.schemas(), s = up.name().equals( > s.Name)) } else { - udtSchema = tangible.ListHelper.find(ns.getSchemas(), s = - SchemaId.opEquals( > s.SchemaId, up.getSchemaId().clone())) - if (!udtSchema.getName().equals(up.getName())) { + udtSchema = tangible.ListHelper.find(ns.schemas(), s = + SchemaId.opEquals( > s.SchemaId, up.schemaId().clone())) + if (!udtSchema.name().equals(up.name())) { throw new LayoutCompilationException(String.format("Ambiguous schema reference: '%1$s:%2$s'", - up.getName(), up.getSchemaId().clone())); + up.name(), up.schemaId().clone())); } } if (udtSchema == null) { throw new LayoutCompilationException(String.format("Cannot resolve schema reference '%1$s:%2$s'", - up.getName(), up.getSchemaId().clone())); + up.name(), up.schemaId().clone())); } - typeArgs.setAndGet(new TypeArgumentList(udtSchema.getSchemaId().clone())); + typeArgs.setAndGet(new TypeArgumentList(udtSchema.schemaId().clone())); return immutable ? LayoutType.ImmutableUDT : LayoutType.UDT; default: throw new LayoutCompilationException(String.format("Unknown property type: %1$s", - logicalType.getType())); + logicalType.type())); } } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutResolverNamespace.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutResolverNamespace.java index eb4fadf..7825d67 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutResolverNamespace.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutResolverNamespace.java @@ -53,10 +53,10 @@ public final class LayoutResolverNamespace extends LayoutResolver { return layout; } - for (Schema s : this.schemaNamespace.getSchemas()) { - if (SchemaId.opEquals(s.getSchemaId().clone(), + for (Schema s : this.schemaNamespace.schemas()) { + if (SchemaId.opEquals(s.schemaId().clone(), schemaId.clone())) { - layout = s.Compile(this.schemaNamespace); + layout = s.compile(this.schemaNamespace); layout = this.layoutCache.putIfAbsent(schemaId.value(), layout); return layout; } diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutType.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutType.java index 8650ed4..0f8d735 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutType.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutType.java @@ -91,7 +91,7 @@ public abstract class LayoutType implements ILayoutType { } public int countTypeArgument(TypeArgumentList value) { - return (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE); + return LayoutCode.BYTES; } public final Result deleteFixed(RowBuffer b, RowCursor scope, LayoutColumn column) { @@ -311,7 +311,9 @@ public abstract class LayoutType implements ILayoutType { * @return Success if the write is permitted, the error code otherwise. */ public static Result prepareSparseWrite( - @Nonnull final RowBuffer b, @Nonnull final RowCursor edit, @Nonnull final TypeArgument typeArg, + @Nonnull final RowBuffer b, + @Nonnull final RowCursor edit, + @Nonnull final TypeArgument typeArg, @Nonnull final UpdateOptions options) { if (edit.immutable() || (edit.scopeType().isUniqueScope() && !edit.deferUniqueIndex())) { @@ -356,10 +358,10 @@ public abstract class LayoutType implements ILayoutType { public static TypeArgument readTypeArgument(RowBuffer row, int offset, Out lenInBytes) { LayoutType itemCode = row.readSparseTypeCode(offset); int argsLenInBytes; - Out tempOut_argsLenInBytes = new Out(); - TypeArgumentList itemTypeArgs = itemCode.readTypeArgumentList(row, offset + (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE), tempOut_argsLenInBytes); + Out tempOut_argsLenInBytes = new Out<>(); + TypeArgumentList itemTypeArgs = itemCode.readTypeArgumentList(row, offset + LayoutCode.BYTES, tempOut_argsLenInBytes); argsLenInBytes = tempOut_argsLenInBytes.get(); - lenInBytes.setAndGet((com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE) + argsLenInBytes); + lenInBytes.setAndGet(LayoutCode.BYTES + argsLenInBytes); return new TypeArgument(itemCode, itemTypeArgs); } @@ -396,7 +398,7 @@ public abstract class LayoutType implements ILayoutType { public int writeTypeArgument(RowBuffer row, int offset, TypeArgumentList value) { row.writeSparseTypeCode(offset, this.layoutCode()); - return com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE; + return LayoutCode.BYTES; } public Result writeVariable(Reference b, Reference scope, LayoutColumn col, T value) { diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUniqueScope.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUniqueScope.java index 68c7fa6..45f8ea1 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUniqueScope.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUniqueScope.java @@ -67,7 +67,7 @@ public abstract class LayoutUniqueScope extends LayoutIndexedScope { // Perform the move. Reference tempReference_dstEdit = new Reference(dstEdit); - b.get().TypedCollectionMoveField(tempReference_dstEdit, sourceEdit, RowOptions.from(options)); + b.get().typedCollectionMoveField(tempReference_dstEdit, sourceEdit, RowOptions.from(options)); dstEdit = tempReference_dstEdit.get(); // TODO: it would be "better" if the destinationScope were updated to point to the diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordIOFormatter.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordIOFormatter.java index 6d03ec1..c60af27 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordIOFormatter.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordIOFormatter.java @@ -9,10 +9,12 @@ import com.azure.data.cosmos.serialization.hybridrow.HybridRowVersion; import com.azure.data.cosmos.serialization.hybridrow.ISpanResizer; import com.azure.data.cosmos.serialization.hybridrow.Result; import com.azure.data.cosmos.serialization.hybridrow.RowBuffer; +import com.azure.data.cosmos.serialization.hybridrow.layouts.Layout; +import com.azure.data.cosmos.serialization.hybridrow.layouts.SystemSchema; public final class RecordIOFormatter { - public static final Layout RecordLayout = SystemSchema.LayoutResolver.Resolve(SystemSchema.RecordSchemaId); - public static final Layout SegmentLayout = SystemSchema.LayoutResolver.Resolve(SystemSchema.SegmentSchemaId); + public static final Layout RecordLayout = SystemSchema.LayoutResolver.resolve(SystemSchema.RecordSchemaId); + public static final Layout SegmentLayout = SystemSchema.LayoutResolver.resolve(SystemSchema.SegmentSchemaId); public static Result FormatRecord(ReadOnlyMemory body, Out row) { return FormatRecord(body, row, null); diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/ArrayPropertyType.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/ArrayPropertyType.java index 0e3321e..42ef572 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/ArrayPropertyType.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/ArrayPropertyType.java @@ -6,24 +6,23 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; /** * Array properties represent an unbounded set of zero or more items. *

- * Arrays may be typed or untyped. Within typed arrays, all items MUST be the same type. The - * type of items is specified via {@link Items}. Typed arrays may be stored more efficiently - * than untyped arrays. When {@link Items} is unspecified, the array is untyped and its items - * may be heterogeneous. + * Arrays may be typed or untyped. Within typed arrays, all items MUST be the same type. The type of items is specified + * via {@link #items}. Typed arrays may be stored more efficiently than untyped arrays. When {@link #items} is + * unspecified, the array is untyped and its items may be heterogeneous. */ public class ArrayPropertyType extends ScopePropertyType { + + private PropertyType items; + /** * (Optional) type of the elements of the array, if a typed array, otherwise null. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "items")] public PropertyType Items {get;set;} - private PropertyType Items; - - public final PropertyType getItems() { - return Items; + public final PropertyType items() { + return this.items; } - public final void setItems(PropertyType value) { - Items = value; + public final ArrayPropertyType items(PropertyType value) { + this.items = value; + return this; } -} \ No newline at end of file +} diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/MapPropertyType.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/MapPropertyType.java index 20540ae..2065596 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/MapPropertyType.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/MapPropertyType.java @@ -4,43 +4,39 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; /** - * Map properties represent an unbounded set of zero or more key-value pairs with unique - * keys. + * Map properties represent an unbounded set of zero or more key-value pairs with unique keys *

- *

- * Maps are typed or untyped. Within typed maps, all key MUST be the same type, and all - * values MUST be the same type. The type of both key and values is specified via {@link Keys} - * and {@link Values} respectively. Typed maps may be stored more efficiently than untyped - * maps. When {@link Keys} or {@link Values} is unspecified or marked - * {@link TypeKind.Any}, the map is untyped and its key and/or values may be heterogeneous. + * Maps are typed or untyped. Within typed maps, all key MUST be the same type, and all values MUST be the same type. + * The type of both key and values is specified via {@link #keys} and {@link #values} respectively. Typed maps may be + * stored more efficiently than untyped maps. When {@link #keys} or {@link #values} is unspecified or marked + * {@link TypeKind#Any}, the map is untyped and its key and/or values may be heterogeneous. */ public class MapPropertyType extends ScopePropertyType { + + private PropertyType keys; + private PropertyType values; + /** - * (Optional) type of the keys of the map, if a typed map, otherwise null. + * (Optional) type of the keys of the map, if a typed map, otherwise {@code null} */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "keys")] public PropertyType Keys {get;set;} - private PropertyType Keys; + public final PropertyType keys() { + return this.keys; + } + + public final MapPropertyType keys(PropertyType value) { + this.keys = value; + return this; + } + /** - * (Optional) type of the values of the map, if a typed map, otherwise null. + * (Optional) type of the values of the map, if a typed map, otherwise {@code null} */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "values")] public PropertyType Values {get;set;} - private PropertyType Values; - - public final PropertyType getKeys() { - return Keys; + public final PropertyType values() { + return this.values; } - public final void setKeys(PropertyType value) { - Keys = value; - } - - public final PropertyType getValues() { - return Values; - } - - public final void setValues(PropertyType value) { - Values = value; + public final MapPropertyType values(PropertyType value) { + this.values = value; + return this; } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Namespace.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Namespace.java index 7834588..021b4ca 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Namespace.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Namespace.java @@ -3,39 +3,15 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; -import Newtonsoft.Json.*; +import com.azure.data.cosmos.core.Json; import java.util.ArrayList; +import java.util.Optional; -// TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java: -///#pragma warning disable CA1716 // Identifiers should not match keywords - - -// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: -//ORIGINAL LINE: [JsonObject] public class Namespace public class Namespace { - /** - * The standard settings used by the JSON parser for interpreting {@link Namespace} - * documents. - */ - private static final JsonSerializerSettings NamespaceParseSettings = new JsonSerializerSettings() { - CheckAdditionalContent =true - }; - /** - * The fully qualified identifier of the namespace. - */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "name")] public string Name {get;set;} - private String Name; - /** - * The version of the HybridRow Schema Definition Language used to encode this namespace. - */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "version")] public SchemaLanguageVersion Version {get;set;} - private SchemaLanguageVersion Version = SchemaLanguageVersion.values()[0]; - /** - * The set of schemas that make up the {@link Namespace}. - */ + + private String name; + private SchemaLanguageVersion version = SchemaLanguageVersion.values()[0]; private ArrayList schemas; /** @@ -45,12 +21,15 @@ public class Namespace { this.setSchemas(new ArrayList()); } + /** + * The fully qualified identifier of the namespace. + */ public final String getName() { - return Name; + return this.name; } public final void setName(String value) { - Name = value; + this.name = value; } /** @@ -60,9 +39,7 @@ public class Namespace { * Table schemas can only reference UDT schemas defined in the same namespace. UDT schemas can * contain nested UDTs whose schemas are defined within the same namespace. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "schemas")] public List Schemas - public final ArrayList getSchemas() { + public final ArrayList schemas() { return this.schemas; } @@ -70,23 +47,26 @@ public class Namespace { this.schemas = value != null ? value : new ArrayList(); } + /** + * The version of the HybridRow Schema Definition Language used to encode this namespace. + */ public final SchemaLanguageVersion getVersion() { - return Version; + return this.version; } public final void setVersion(SchemaLanguageVersion value) { - Version = value; + this.version = value; } /** * Parse a JSON document and return a full namespace. * - * @param json The JSON text to parse. + * @param value The JSON text to parse * @return A namespace containing a set of logical schemas. */ - public static Namespace Parse(String json) { - Namespace ns = JsonConvert.DeserializeObject(json, Namespace.NamespaceParseSettings); - SchemaValidator.Validate(ns); + public static Optional parse(String value) { + Optional ns = Json.parse(value); + ns.ifPresent(SchemaValidator::Validate); return ns; } -} \ No newline at end of file +} diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/ObjectPropertyType.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/ObjectPropertyType.java index b53fbc4..4f587f2 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/ObjectPropertyType.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/ObjectPropertyType.java @@ -3,39 +3,36 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; -import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** * Object properties represent nested structures. *

- * Object properties map to multiple columns depending on the number of internal properties - * within the defined object structure. Object properties are provided as a convince in schema - * design. They are effectively equivalent to defining the same properties explicitly via - * {@link PrimitivePropertyType} with nested property paths. + * Object properties map to multiple columns depending on the number of internal properties within the defined object + * structure. Object properties are provided as a convince in schema design. They are effectively equivalent to + * defining the same properties explicitly via {@link PrimitivePropertyType} with nested property paths. */ public class ObjectPropertyType extends ScopePropertyType { - /** - * A list of zero or more property definitions that define the columns within the schema. - */ - private ArrayList properties; + + private List properties; /** * Initializes a new instance of the {@link ObjectPropertyType} class. */ public ObjectPropertyType() { - this.properties = new ArrayList(); + this.properties = Collections.emptyList(); } /** - * A list of zero or more property definitions that define the columns within the schema. + * A list of zero or more property definitions that define the columns within the schema */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "properties")] public List Properties - public final ArrayList getProperties() { + public final List properties() { return this.properties; } - public final void setProperties(ArrayList value) { - this.properties = value != null ? value : new ArrayList(); + public final ObjectPropertyType properties(List value) { + this.properties = value != null ? value : Collections.emptyList(); + return this; } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PartitionKey.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PartitionKey.java index 468868f..d500479 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PartitionKey.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PartitionKey.java @@ -11,15 +11,14 @@ public class PartitionKey { * The logical path of the referenced property. * Partition keys MUST refer to properties defined within the same {@link Schema}. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "path", Required = Required.Always)] public string Path {get;set;} - private String Path; + private String path; - public final String getPath() { - return Path; + public final String path() { + return this.path; } - public final void setPath(String value) { - Path = value; + public final PartitionKey path(String value) { + this.path = value; + return this; } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PrimarySortKey.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PrimarySortKey.java index 7a13ab5..b667785 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PrimarySortKey.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PrimarySortKey.java @@ -8,35 +8,33 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; * partition. */ public class PrimarySortKey { + + private SortDirection direction = SortDirection.values()[0]; + private String path; + /** * The logical path of the referenced property. * Primary keys MUST refer to properties defined within the same {@link Schema}. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "direction", Required = Required.DisallowNull)] public - // SortDirection Direction {get;set;} - private SortDirection Direction = SortDirection.values()[0]; + public final SortDirection direction() { + return this.direction; + } + + public final PrimarySortKey direction(SortDirection value) { + this.direction = value; + return this; + } + /** * The logical path of the referenced property. * Primary keys MUST refer to properties defined within the same {@link Schema}. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "path", Required = Required.Always)] public string Path {get;set;} - private String Path; - - public final SortDirection getDirection() { - return Direction; + public final String path() { + return this.path; } - public final void setDirection(SortDirection value) { - Direction = value; - } - - public final String getPath() { - return Path; - } - - public final void setPath(String value) { - Path = value; + public final PrimarySortKey path(String value) { + this.path = value; + return this; } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PrimitivePropertyType.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PrimitivePropertyType.java index 7752977..1682543 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PrimitivePropertyType.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PrimitivePropertyType.java @@ -10,36 +10,34 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; * column should be represented within the row. */ public class PrimitivePropertyType extends PropertyType { + + private int length; + private StorageKind storage = StorageKind.values()[0]; + /** * The maximum allowable length in bytes. *

* This annotation is only valid for non-fixed length types. A value of 0 means the maximum * allowable length. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "length")][JsonConverter(typeof(StrictIntegerConverter))] public - // int Length {get;set;} - private int Length; + public final int length() { + return this.length; + } + + public final PrimitivePropertyType length(int value) { + this.length = value; + return this; + } + /** * Storage requirements of the property. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "storage")] public StorageKind Storage {get;set;} - private StorageKind Storage = StorageKind.values()[0]; - - public final int getLength() { - return Length; + public final StorageKind storage() { + return this.storage; } - public final void setLength(int value) { - Length = value; - } - - public final StorageKind getStorage() { - return Storage; - } - - public final void setStorage(StorageKind value) { - Storage = value; + public final PrimitivePropertyType storage(StorageKind value) { + this.storage = value; + return this; } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Property.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Property.java index f8f9f11..3eb8040 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Property.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Property.java @@ -3,65 +3,56 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; -// TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java: -///#pragma warning disable CA1716 // Identifiers should not match keywords - - /** * Describes a single property definition. */ public class Property { + + private String comment; + private String path; + private PropertyType propertyType; + /** - * An (optional) comment describing the purpose of this property. + * An (optional) comment describing the purpose of this property + *

* Comments are for documentary purpose only and do not affect the property at runtime. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "comment", DefaultValueHandling = DefaultValueHandling - // .IgnoreAndPopulate)] public string Comment {get;set;} - private String Comment; + public final String comment() { + return this.comment; + } + + public final Property comment(String value) { + this.comment = value; + return this; + } + /** * The logical path of this property. *

- * For complex properties (e.g. objects) the logical path forms a prefix to relative paths of - * properties defined within nested structures. - * + * For complex properties (e.g. objects) the logical path forms a prefix to relative paths of properties defined + * within nested structures. + *

* See the logical path specification for full details on both relative and absolute paths. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "path", Required = Required.Always)] public string Path {get;set;} - private String Path; - /** - * The type of the property. - *

- * Types may be simple (e.g. int8) or complex (e.g. object). Simple types always define a - * single column. Complex types may define one or more columns depending on their structure. - */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "type", Required = Required.Always)] public PropertyType - // PropertyType {get;set;} - private PropertyType PropertyType; - - public final String getComment() { - return Comment; - } - - public final void setComment(String value) { - Comment = value; - } - - public final String getPath() { - return Path; + public final String path() { + return this.path; } public final void setPath(String value) { - Path = value; + this.path = value; } - public final PropertyType getPropertyType() { - return PropertyType; + /** + * The type of the property. + *

+ * Types may be simple (e.g. int8) or complex (e.g. object). Simple types always define a single column. Complex + * types may define one or more columns depending on their structure. + */ + public final PropertyType propertyType() { + return this.propertyType; } public final void setPropertyType(PropertyType value) { - PropertyType = value; + this.propertyType = value; } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PropertyType.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PropertyType.java index 8e15cba..c2f8b16 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PropertyType.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PropertyType.java @@ -6,56 +6,51 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; /** * The base class for property types both primitive and complex. */ -// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: -//ORIGINAL LINE: [JsonConverter(typeof(PropertySchemaConverter))] public abstract class PropertyType public abstract class PropertyType { + + private String apiType; + private boolean nullable; + private TypeKind type = TypeKind.values()[0]; + + protected PropertyType() { + this.nullable(true); + } + /** * Api-specific type annotations for the property. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "apitype")] public string ApiType {get;set;} - private String ApiType; + public final String apiType() { + return this.apiType; + } + + public final PropertyType apiType(String value) { + this.apiType = value; + return this; + } + /** - * True if the property can be null. - * Default: true. + * {@code true} if the property can be {@code null} + *

+ * Default: {@code true} */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [DefaultValue(true)][JsonProperty(PropertyName = "nullable", DefaultValueHandling = - // DefaultValueHandling.IgnoreAndPopulate)][JsonConverter(typeof(StrictBooleanConverter))] public bool Nullable - // {get;set;} - private boolean Nullable; + public final boolean nullable() { + return this.nullable; + } + + public final PropertyType nullable(boolean value) { + this.nullable = value; + return this; + } + /** - * The logical type of the property. + * The logical type of the property */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "type")] public TypeKind Type {get;set;} - private TypeKind Type = TypeKind.values()[0]; - - protected PropertyType() { - this.setNullable(true); + public final TypeKind type() { + return this.type; } - public final String getApiType() { - return ApiType; - } - - public final void setApiType(String value) { - ApiType = value; - } - - public final boolean getNullable() { - return Nullable; - } - - public final void setNullable(boolean value) { - Nullable = value; - } - - public final TypeKind getType() { - return Type; - } - - public final void setType(TypeKind value) { - Type = value; + public final PropertyType type(TypeKind value) { + this.type = value; + return this; } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Schema.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Schema.java index 453b27d..4d89e36 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Schema.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Schema.java @@ -3,32 +3,79 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; -import Newtonsoft.Json.*; +import com.azure.data.cosmos.core.Json; import com.azure.data.cosmos.serialization.hybridrow.SchemaId; import com.azure.data.cosmos.serialization.hybridrow.layouts.Layout; import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCompiler; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; /** - * A schema describes either table or UDT metadata. + * A schema describes either table or UDT metadata *

- * The schema of a table or UDT describes the structure of row (i.e. which columns and the - * types of those columns). A table schema represents the description of the contents of a collection - * level row directly. UDTs described nested structured objects that may appear either within a table - * column or within another UDT (i.e. nested UDTs). + * The schema of a table or UDT describes the structure of row (i.e. which columns and the types of those columns). A + * table schema represents the description of the contents of a collection level row directly. UDTs described nested + * structured objects that may appear either within a table column or within another UDT (i.e. nested UDTs). */ public class Schema { + + private String comment; + private String name; + private SchemaOptions options; + private List partitionKeys; + private List primaryKeys; + private List properties; + private SchemaId schemaId = SchemaId.NONE; + private List staticKeys; + private TypeKind type = TypeKind.values()[0]; + private SchemaLanguageVersion version = SchemaLanguageVersion.values()[0]; + + /** + * Initializes a new instance of the {@link Schema} class. + */ + public Schema() { + this.type(TypeKind.Schema); + this.properties = Collections.emptyList(); + this.partitionKeys = Collections.emptyList(); + this.primaryKeys = Collections.emptyList(); + this.staticKeys = Collections.emptyList(); + } + /** * An (optional) comment describing the purpose of this schema. * Comments are for documentary purpose only and do not affect the schema at runtime. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "comment", DefaultValueHandling = DefaultValueHandling - // .IgnoreAndPopulate)] public string Comment {get;set;} - private String Comment; + public final String comment() { + return this.comment; + } + + public final Schema comment(String value) { + this.comment = value; + return this; + } + + /** + * Compiles this logical schema into a physical layout that can be used to read and write rows + * + * @param ns The namespace within which this schema is defined. + * @return The layout for the schema. + */ + public final Layout compile(Namespace ns) { + + checkNotNull(ns, "expected non-null ns"); + checkArgument(ns.schemas().contains(this)); + + return LayoutCompiler.Compile(ns, this); + } + /** * The name of the schema. *

@@ -37,140 +84,99 @@ public class Schema { * Names must begin with an alpha-numeric character and can only contain alpha-numeric characters and * underscores. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "name", Required = Required.Always)] public string Name {get;set;} - private String Name; + public final String name() { + return this.name; + } + + public final Schema name(String value) { + this.name = value; + return this; + } + /** * Schema-wide operations. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "options")] public SchemaOptions Options {get;set;} - private SchemaOptions Options; - /** - * The unique identifier for a schema. - * Identifiers must be unique within the scope of the database in which they are used. - */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "id", Required = Required.Always)] public SchemaId SchemaId {get;set;} - private com.azure.data.cosmos.serialization.hybridrow.SchemaId SchemaId = new SchemaId(); - /** - * The type of this schema. This value MUST be {@link TypeKind.Schema}. - */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [DefaultValue(TypeKind.Schema)][JsonProperty(PropertyName = "type", Required = Required - // .DisallowNull, DefaultValueHandling = DefaultValueHandling.Populate)] public TypeKind Type {get;set;} - private TypeKind Type = TypeKind.values()[0]; - /** - * The version of the HybridRow Schema Definition Language used to encode this schema. - */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "version")] public SchemaLanguageVersion Version {get;set;} - private SchemaLanguageVersion Version = SchemaLanguageVersion.values()[0]; - /** - * An (optional) list of zero or more logical paths that form the partition key. - */ - private ArrayList partitionKeys; - /** - * An (optional) list of zero or more logical paths that form the primary sort key. - */ - private ArrayList primaryKeys; - /** - * A list of zero or more property definitions that define the columns within the schema. - */ - private ArrayList properties; - /** - * An (optional) list of zero or more logical paths that hold data shared by all documents that have the same - * partition key. - */ - private ArrayList staticKeys; - - /** - * Initializes a new instance of the {@link Schema} class. - */ - public Schema() { - this.setType(TypeKind.Schema); - this.properties = new ArrayList(); - this.partitionKeys = new ArrayList(); - this.primaryKeys = new ArrayList(); - this.staticKeys = new ArrayList(); + public final SchemaOptions options() { + return this.options; } - public final String getComment() { - return Comment; - } - - public final void setComment(String value) { - Comment = value; - } - - public final String getName() { - return Name; - } - - public final void setName(String value) { - Name = value; - } - - public final SchemaOptions getOptions() { - return Options; - } - - public final void setOptions(SchemaOptions value) { - Options = value; + public final Schema options(SchemaOptions value) { + this.options = value; + return this; } /** - * An (optional) list of zero or more logical paths that form the partition key. - * All paths referenced MUST map to a property within the schema. - * - * This field is never null. + * Parse a JSON fragment and return a schema. + * + * @param value The JSON string value to parse + * @return A logical schema, if the value parses. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "partitionkeys")] public List PartitionKeys - public final ArrayList getPartitionKeys() { + public static Optional parse(String value) { + return Json.parse(value); // TODO: DANOBLE: perform structural validation on the Schema after JSON + // parsing + } + + /** + * An (optional) list of zero or more logical paths that form the partition key + *

+ * All paths referenced MUST map to a property within the schema. This field is never null. + * + * @return list of zero or more logical paths that form the partition key + */ + @Nonnull + public final List partitionKeys() { return this.partitionKeys; } - public final void setPartitionKeys(ArrayList value) { - this.partitionKeys = value != null ? value : new ArrayList(); + public final Schema partitionKeys(@Nullable List value) { + this.partitionKeys = value != null ? value : Collections.emptyList(); + return this; } /** - * An (optional) list of zero or more logical paths that form the primary sort key. - * All paths referenced MUST map to a property within the schema. - * - * This field is never null. + * An (optional) list of zero or more logical paths that form the primary sort key + *

+ * All paths referenced MUST map to a property within the schema. This field is never null. + * + * @return list of zero or more logical paths that form the partition key */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "primarykeys")] public List PrimarySortKeys - public final ArrayList getPrimarySortKeys() { + public final List primarySortKeys() { return this.primaryKeys; } - public final void setPrimarySortKeys(ArrayList value) { - this.primaryKeys = value != null ? value : new ArrayList(); + public final Schema primarySortKeys(ArrayList value) { + this.primaryKeys = value != null ? value : Collections.emptyList(); + return this; } /** - * A list of zero or more property definitions that define the columns within the schema. + * A list of zero or more property definitions that define the columns within the schema + *

* This field is never null. + * + * @return list of zero or more property definitions that define the columns within the schema */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "properties")] public List Properties - public final ArrayList getProperties() { + public final List properties() { return this.properties; } - public final void setProperties(ArrayList value) { - this.properties = value != null ? value : new ArrayList(); + public final Schema properties(List value) { + this.properties = value != null ? value : Collections.emptyList(); + return this; } - public final SchemaId getSchemaId() { - return SchemaId; + /** + * The unique identifier for a schema + *

+ * Identifiers must be unique within the scope of the database in which they are used. + */ + public final SchemaId schemaId() { + return this.schemaId; } - public final void setSchemaId(SchemaId value) { - SchemaId = value.clone(); + public final Schema schemaId(SchemaId value) { + this.schemaId = value; + return this; } /** @@ -178,57 +184,51 @@ public class Schema { * All paths referenced MUST map to a property within the schema. * * This field is never null. + * + * @return */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "statickeys", DefaultValueHandling = DefaultValueHandling - // .IgnoreAndPopulate)] public List StaticKeys - public final ArrayList getStaticKeys() { + public final List staticKeys() { return this.staticKeys; } - public final void setStaticKeys(ArrayList value) { - this.staticKeys = value != null ? value : new ArrayList(); - } - - public final TypeKind getType() { - return Type; - } - - public final void setType(TypeKind value) { - Type = value; - } - - public final SchemaLanguageVersion getVersion() { - return Version; - } - - public final void setVersion(SchemaLanguageVersion value) { - Version = value; + public final Schema staticKeys(List value) { + this.staticKeys = value != null ? value : Collections.emptyList(); + return this; } /** - * Compiles this logical schema into a physical layout that can be used to read and write - * rows. + * Returns a JSON string representation of the current {@link Schema} * - * @param ns The namespace within which this schema is defined. - * @return The layout for the schema. + * @return a JSON string representation of the current {@link Schema} */ - public final Layout Compile(Namespace ns) { - checkArgument(ns != null); - checkArgument(ns.getSchemas().contains(this)); - - return LayoutCompiler.Compile(ns, this); + @Override + public String toString() { + return Json.toString(this); } /** - * Parse a JSON fragment and return a schema. - * - * @param json The JSON text to parse. - * @return A logical schema. + * The type of this schema + *

+ * This value MUST be {@link TypeKind#Schema}. */ - public static Schema Parse(String json) { - return JsonConvert.DeserializeObject(json); + public final TypeKind type() { + return this.type; + } - // TODO: perform structural validation on the Schema after JSON parsing. + public final Schema type(TypeKind value) { + this.type = value; + return this; + } + + /** + * The version of the HybridRow Schema Definition Language used to encode this schema + */ + public final SchemaLanguageVersion version() { + return this.version; + } + + public final Schema version(SchemaLanguageVersion value) { + this.version = value; + return this; } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaException.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaException.java index 7d5a139..6d53066 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaException.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaException.java @@ -5,9 +5,8 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; import java.io.Serializable; -// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: -//ORIGINAL LINE: [Serializable][ExcludeFromCodeCoverage] public sealed class SchemaException : Exception public final class SchemaException extends RuntimeException implements Serializable { + public SchemaException() { } @@ -18,8 +17,4 @@ public final class SchemaException extends RuntimeException implements Serializa public SchemaException(String message, RuntimeException innerException) { super(message, innerException); } - - private SchemaException(SerializationInfo info, StreamingContext context) { - super(info, context); - } -} \ No newline at end of file +} diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaLanguageVersion.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaLanguageVersion.java index fac5508..ed11e87 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaLanguageVersion.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaLanguageVersion.java @@ -3,45 +3,40 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; -// TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java: -///#pragma warning disable CA1028 // Enum Storage should be Int32 - +import java.util.HashMap; /** * Versions of the HybridRow Schema Description Language. */ -// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: -//ORIGINAL LINE: [JsonConverter(typeof(StringEnumConverter), true)] public enum SchemaLanguageVersion : byte -//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java: -//ORIGINAL LINE: [JsonConverter(typeof(StringEnumConverter), true)] public enum SchemaLanguageVersion : byte public enum SchemaLanguageVersion { /** * Initial version of the HybridRow Schema Description Lanauge. */ V1((byte)0); - public static final int SIZE = java.lang.Byte.SIZE; - private static java.util.HashMap mappings; - private byte byteValue; + public static final int BYTES = Byte.BYTES; + + private static HashMap mappings; + private byte value; SchemaLanguageVersion(byte value) { - byteValue = value; - getMappings().put(value, this); + this.value = value; + mappings().put(value, this); } public byte getValue() { - return byteValue; + return this.value; } public static SchemaLanguageVersion forValue(byte value) { - return getMappings().get(value); + return mappings().get(value); } - private static java.util.HashMap getMappings() { + private static HashMap mappings() { if (mappings == null) { synchronized (SchemaLanguageVersion.class) { if (mappings == null) { - mappings = new java.util.HashMap(); + mappings = new HashMap<>(); } } } diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaOptions.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaOptions.java index 95b87a5..7dbe4db 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaOptions.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaOptions.java @@ -7,14 +7,23 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; * Describes the set of options that apply to the entire schema and the way it is validated. */ public class SchemaOptions { + + private boolean disableSystemPrefix; + private boolean disallowUnschematized; + private boolean enablePropertyLevelTimestamp; + /** * If the is value true, then disables prefixing the system properties with a prefix __sys_ * for reserved properties owned by the store layer. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "disableSystemPrefix", DefaultValueHandling = DefaultValueHandling - // .IgnoreAndPopulate)][JsonConverter(typeof(StrictBooleanConverter))] public bool DisableSystemPrefix {get;set;} - private boolean DisableSystemPrefix; + public final boolean disableSystemPrefix() { + return this.disableSystemPrefix; + } + + public final void disableSystemPrefix(boolean value) { + this.disableSystemPrefix = value; + } + /** * If true then structural schema validation is enabled. *

@@ -25,42 +34,25 @@ public class SchemaOptions { * column override of the path. The value will be stored (and any existing value at that path will be * overwritten). No error will be given. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "disallowUnschematized")][JsonConverter(typeof - // (StrictBooleanConverter))] public bool DisallowUnschematized {get;set;} - private boolean DisallowUnschematized; + public final boolean disallowUnschematized() { + return this.disallowUnschematized; + } + + public final void disallowUnschematized(boolean value) { + this.disallowUnschematized = value; + } + /** * If set and has the value true, then triggers behavior in the Schema that acts based on property * level timestamps. In Cassandra, this means that new columns are added for each top level property * that has values of the client side timestamp. This is then used in conflict resolution to independently * resolve each property based on the timestamp value of that property. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "enablePropertyLevelTimestamp")][JsonConverter(typeof - // (StrictBooleanConverter))] public bool EnablePropertyLevelTimestamp {get;set;} - private boolean EnablePropertyLevelTimestamp; - - public final boolean getDisableSystemPrefix() { - return DisableSystemPrefix; + public final boolean enablePropertyLevelTimestamp() { + return this.enablePropertyLevelTimestamp; } - public final void setDisableSystemPrefix(boolean value) { - DisableSystemPrefix = value; - } - - public final boolean getDisallowUnschematized() { - return DisallowUnschematized; - } - - public final void setDisallowUnschematized(boolean value) { - DisallowUnschematized = value; - } - - public final boolean getEnablePropertyLevelTimestamp() { - return EnablePropertyLevelTimestamp; - } - - public final void setEnablePropertyLevelTimestamp(boolean value) { - EnablePropertyLevelTimestamp = value; + public final void enablePropertyLevelTimestamp(boolean value) { + this.enablePropertyLevelTimestamp = value; } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaValidator.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaValidator.java index d13da96..4431dab 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaValidator.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaValidator.java @@ -24,19 +24,19 @@ HashMap ids , TypeKind.Schema, s.getType())); HashMap pathDupCheck = new HashMap(s.getProperties().size()); for (Property p : s.getProperties()) { - ValidateAssert.DuplicateCheck(p.getPath(), p, pathDupCheck, "Property path", "Schema"); + ValidateAssert.DuplicateCheck(p.path(), p, pathDupCheck, "Property path", "Schema"); } for (PartitionKey pk : s.getPartitionKeys()) { - ValidateAssert.Exists(pk.getPath(), pathDupCheck, "Partition key column", "Schema"); + ValidateAssert.Exists(pk.path(), pathDupCheck, "Partition key column", "Schema"); } for (PrimarySortKey ps : s.getPrimarySortKeys()) { - ValidateAssert.Exists(ps.getPath(), pathDupCheck, "Primary sort key column", "Schema"); + ValidateAssert.Exists(ps.path(), pathDupCheck, "Primary sort key column", "Schema"); } for (StaticKey sk : s.getStaticKeys()) { - ValidateAssert.Exists(sk.getPath(), pathDupCheck, "Static key column", "Schema"); + ValidateAssert.Exists(sk.path(), pathDupCheck, "Static key column", "Schema"); } for (Property p : s.getProperties()) { @@ -108,8 +108,8 @@ HashMap ids op: HashMap pathDupCheck = new HashMap(op.Properties.Count); for (Property nested : op.Properties) { - ValidateAssert.DuplicateCheck(nested.getPath(), nested, pathDupCheck, "Property path", "Object"); - SchemaValidator.Visit(nested.getPropertyType(), p, schemas, ids); + ValidateAssert.DuplicateCheck(nested.path(), nested, pathDupCheck, "Property path", "Object"); + SchemaValidator.Visit(nested.propertyType(), p, schemas, ids); } break; @@ -121,8 +121,8 @@ HashMap ids if (SchemaId.opNotEquals(up.SchemaId, SchemaId.INVALID)) { Schema s = ValidateAssert.Exists(up.SchemaId, ids, "Schema id", "Namespace"); - ValidateAssert.AreEqual(up.Name, s.getName(), String.format("Schema name '%1$s' does not match " + - "the name of schema with id '%2$s': %3$s", up.Name, up.SchemaId, s.getName())); + ValidateAssert.AreEqual(up.Name, s.name(), String.format("Schema name '%1$s' does not match " + + "the name of schema with id '%2$s': %3$s", up.Name, up.SchemaId, s.name())); } break; @@ -133,27 +133,27 @@ HashMap ids }>schemas, public static void Validate(Namespace ns) { - HashMap nameVersioningCheck = new HashMap(ns.getSchemas().size()); + HashMap nameVersioningCheck = new HashMap(ns.schemas().size()); HashMap< (String, SchemaId), - Schema > nameDupCheck = new HashMap<(String, SchemaId), Schema > (ns.getSchemas().size()); - HashMap idDupCheck = new HashMap(ns.getSchemas().size()); - for (Schema s : ns.getSchemas()) { - ValidateAssert.IsValidSchemaId(s.getSchemaId().clone(), "Schema id"); - ValidateAssert.IsValidIdentifier(s.getName(), "Schema name"); - ValidateAssert.DuplicateCheck(s.getSchemaId().clone(), s, idDupCheck, "Schema id", "Namespace"); - ValidateAssert.DuplicateCheck((s.getName(), s.getSchemaId().clone()), s, nameDupCheck, "Schema reference" + Schema > nameDupCheck = new HashMap<(String, SchemaId), Schema > (ns.schemas().size()); + HashMap idDupCheck = new HashMap(ns.schemas().size()); + for (Schema s : ns.schemas()) { + ValidateAssert.IsValidSchemaId(s.schemaId().clone(), "Schema id"); + ValidateAssert.IsValidIdentifier(s.name(), "Schema name"); + ValidateAssert.DuplicateCheck(s.schemaId().clone(), s, idDupCheck, "Schema id", "Namespace"); + ValidateAssert.DuplicateCheck((s.name(), s.schemaId().clone()), s, nameDupCheck, "Schema reference" , "Namespace") // Count the versions of each schema by name. int count; - count = nameVersioningCheck.get(s.getName()); - nameVersioningCheck.put(s.getName(), count + 1); + count = nameVersioningCheck.get(s.name()); + nameVersioningCheck.put(s.name(), count + 1); } // Enable id-less Schema references for all types with a unique version in the namespace. - for (Schema s : ns.getSchemas()) { - if (nameVersioningCheck.get(s.getName()).equals(1)) { - ValidateAssert.DuplicateCheck((s.getName(), SchemaId.INVALID), s, nameDupCheck, "Schema reference", + for (Schema s : ns.schemas()) { + if (nameVersioningCheck.get(s.name()).equals(1)) { + ValidateAssert.DuplicateCheck((s.name(), SchemaId.INVALID), s, nameDupCheck, "Schema reference", "Namespace") } } diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/ScopePropertyType.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/ScopePropertyType.java index 2cb0eef..e05754f 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/ScopePropertyType.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/ScopePropertyType.java @@ -4,20 +4,18 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; public abstract class ScopePropertyType extends PropertyType { + + private boolean immutable; + /** * True if the property's child elements cannot be mutated in place. * Immutable properties can still be replaced in their entirety. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "immutable")][JsonConverter(typeof(StrictBooleanConverter))] public - // bool Immutable {get;set;} - private boolean Immutable; - - public final boolean getImmutable() { - return Immutable; + public final boolean immutable() { + return this.immutable; } - public final void setImmutable(boolean value) { - Immutable = value; + public final void immutable(boolean value) { + this.immutable = value; } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SetPropertyType.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SetPropertyType.java index ef9f992..2af1d31 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SetPropertyType.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SetPropertyType.java @@ -4,11 +4,11 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; /** - * Set properties represent an unbounded set of zero or more unique items. + * Set properties represent an unbounded set of zero or more unique items *

* Sets may be typed or untyped. Within typed sets, all items MUST be the same type. The - * type of items is specified via {@link Items}. Typed sets may be stored more efficiently - * than untyped sets. When {@link Items} is unspecified, the set is untyped and its items + * type of items is specified via {@link #items}. Typed sets may be stored more efficiently + * than untyped sets. When {@link #items} is unspecified, the set is untyped and its items * may be heterogeneous. *

* Each item within a set must be unique. Uniqueness is defined by the HybridRow encoded sequence @@ -18,15 +18,14 @@ public class SetPropertyType extends ScopePropertyType { /** * (Optional) type of the elements of the set, if a typed set, otherwise null. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "items")] public PropertyType Items {get;set;} - private PropertyType Items; + private PropertyType items; - public final PropertyType getItems() { - return Items; + public final PropertyType items() { + return this.items; } - public final void setItems(PropertyType value) { - Items = value; + public final SetPropertyType items(PropertyType value) { + this.items = value; + return this; } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SortDirection.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SortDirection.java index a0b2f1c..24ab024 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SortDirection.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SortDirection.java @@ -6,45 +6,39 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; /** * Describes the sort order direction. */ -// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: -//ORIGINAL LINE: [JsonConverter(typeof(StringEnumConverter), true)] public enum SortDirection public enum SortDirection { /** * Sorts from the lowest to the highest value. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [EnumMember(Value = "asc")] Ascending = 0, Ascending(0), /** * Sorts from the highests to the lowest value. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [EnumMember(Value = "desc")] Descending, Descending(1); public static final int SIZE = java.lang.Integer.SIZE; private static java.util.HashMap mappings; - private int intValue; + private int value; SortDirection(int value) { - intValue = value; - getMappings().put(value, this); + this.value = value; + mappings().put(value, this); } - public int getValue() { - return intValue; + public int value() { + return this.value; } public static SortDirection forValue(int value) { - return getMappings().get(value); + return mappings().get(value); } - private static java.util.HashMap getMappings() { + private static java.util.HashMap mappings() { if (mappings == null) { synchronized (SortDirection.class) { if (mappings == null) { - mappings = new java.util.HashMap(); + mappings = new java.util.HashMap<>(); } } } diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StaticKey.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StaticKey.java index cadb801..8357f0f 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StaticKey.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StaticKey.java @@ -4,23 +4,23 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; /** - * Describes a property or set of properties whose values MUST be the same for all rows that share the same partition - * key. + * Describes a property or property set whose values MUST be the same for all rows that share the same partition key */ public class StaticKey { + + private String path; + /** - * The logical path of the referenced property. + * The logical path of the referenced property + *

* Static path MUST refer to properties defined within the same {@link Schema}. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "path", Required = Required.Always)] public string Path {get;set;} - private String Path; - - public final String getPath() { - return Path; + public final String path() { + return this.path; } - public final void setPath(String value) { - Path = value; + public final StaticKey path(String value) { + this.path = value; + return this; } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StorageKind.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StorageKind.java index 325845b..294d41b 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StorageKind.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StorageKind.java @@ -6,63 +6,56 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; /** * Describes the storage placement for primitive properties. */ -// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: -//ORIGINAL LINE: [JsonConverter(typeof(StringEnumConverter), true)] public enum StorageKind public enum StorageKind { /** - * The property defines a sparse column. + * The property defines a sparse column *

- * Columns marked {@link Sparse} consume no space in the row when not present. When - * present they appear in an unordered linked list at the end of the row. Access time for - * {@link Sparse} columns is proportional to the number of {@link Sparse} columns in the - * row. + * Columns marked as sparse consume no space in the row when not present. When present they appear in an unordered + * linked list at the end of the row. Access time for sparse columns is proportional to the number of sparse columns + * in the row. */ Sparse(0), /** - * The property is a fixed-length, space-reserved column. + * The property is a fixed-length, space-reserved column *

- * The column will consume 1 null-bit, and its byte-width regardless of whether the value is - * present in the row. + * The column will consume 1 null-bit, and its byte-width regardless of whether the value is present in the row. */ Fixed(1), /** * The property is a variable-length column. *

- * The column will consume 1 null-bit regardless of whether the value is present. When the value is - * present it will also consume a variable number of bytes to encode the length preceding the actual - * value. + * The column will consume 1 null-bit regardless of whether the value is present. When the value is present it will + * also consume a variable number of bytes to encode the length preceding the actual value. *

- * When a long value is marked {@link Variable} then a null-bit is reserved and - * the value is optionally encoded as {@link Variable} if small enough to fit, otherwise the - * null-bit is set and the value is encoded as {@link Sparse}. - *

+ * When a long value is marked variable then a null-bit is reserved and the value is optionally encoded as + * variable if small enough to fit, otherwise the null-bit is set and the value is encoded as sparse. */ Variable(2); public static final int SIZE = java.lang.Integer.SIZE; private static java.util.HashMap mappings; - private int intValue; + private int value; StorageKind(int value) { - intValue = value; - getMappings().put(value, this); + this.value = value; + mappings().put(value, this); } - public int getValue() { - return intValue; + public int value() { + return this.value; } public static StorageKind forValue(int value) { - return getMappings().get(value); + return mappings().get(value); } - private static java.util.HashMap getMappings() { + private static java.util.HashMap mappings() { if (mappings == null) { synchronized (StorageKind.class) { if (mappings == null) { - mappings = new java.util.HashMap(); + mappings = new java.util.HashMap<>(); } } } diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/TaggedPropertyType.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/TaggedPropertyType.java index 41eb40b..89cba60 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/TaggedPropertyType.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/TaggedPropertyType.java @@ -4,20 +4,22 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; import java.util.ArrayList; +import java.util.List; /** * Tagged properties pair one or more typed values with an API-specific uint8 type code. *

- * The uint8 type code is implicitly in position 0 within the resulting tagged and should not - * be specified in {@link Items}. + * The {@code UInt8} type code is implicitly in position 0 within the resulting tagged and should not be specified in + * {@link #items}. */ public class TaggedPropertyType extends ScopePropertyType { + public static final int MaxTaggedArguments = 2; public static final int MinTaggedArguments = 1; /** * Types of the elements of the tagged in element order. */ - private ArrayList items; + private List items; /** * Initializes a new instance of the {@link TaggedPropertyType} class. @@ -28,14 +30,14 @@ public class TaggedPropertyType extends ScopePropertyType { /** * Types of the elements of the tagged in element order. + * @return */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "items")] public List Items - public final ArrayList getItems() { + public final List items() { return this.items; } - public final void setItems(ArrayList value) { - this.items = value != null ? value : new ArrayList(); + public final TaggedPropertyType items(List value) { + this.items = value != null ? value : new ArrayList<>(); + return this; } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/TuplePropertyType.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/TuplePropertyType.java index 4fb46d8..edd08d5 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/TuplePropertyType.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/TuplePropertyType.java @@ -4,6 +4,7 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; import java.util.ArrayList; +import java.util.List; /** * Tuple properties represent a typed, finite, ordered set of two or more items. @@ -12,7 +13,7 @@ public class TuplePropertyType extends ScopePropertyType { /** * Types of the elements of the tuple in element order. */ - private ArrayList items; + private List items; /** * Initializes a new instance of the {@link TuplePropertyType} class. @@ -23,14 +24,15 @@ public class TuplePropertyType extends ScopePropertyType { /** * Types of the elements of the tuple in element order. + * @return */ // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: //ORIGINAL LINE: [JsonProperty(PropertyName = "items")] public List Items - public final ArrayList getItems() { + public final List items() { return this.items; } - public final void setItems(ArrayList value) { + public final void items(List value) { this.items = value != null ? value : new ArrayList(); } } \ No newline at end of file diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/UdtPropertyType.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/UdtPropertyType.java index 3980ff6..7494eee 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/UdtPropertyType.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/UdtPropertyType.java @@ -13,46 +13,46 @@ import com.azure.data.cosmos.serialization.hybridrow.SchemaId; * all outer schemas where the UDT is used. */ public class UdtPropertyType extends ScopePropertyType { + + private String name; + private SchemaId schemaId; + + /** + * Initializes a new {@link UdtPropertyType} + */ + public UdtPropertyType() { + this.schemaId(SchemaId.INVALID); + } + /** * The identifier of the UDT schema defining the structure for the nested row. *

* The UDT schema MUST be defined within the same {@link Namespace} as the schema that * references it. */ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "name", Required = Required.Always)] public string Name {get;set;} - private String Name; + public final String name() { + return this.name; + } + + public final void name(String value) { + this.name = value; + } + /** * The unique identifier for a schema. *

- * Optional uniquifier if multiple versions of {@link Name} appears within the Namespace. + * Optional uniquifier if multiple versions of {@link #name} appears within the Namespace. *

* If multiple versions of a UDT are defined within the {@link Namespace} then the globally * unique identifier of the specific version referenced MUST be provided. *

*/ - // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: - //ORIGINAL LINE: [JsonProperty(PropertyName = "id", Required = Required.DisallowNull, DefaultValueHandling = - // DefaultValueHandling.IgnoreAndPopulate)] public SchemaId SchemaId {get;set;} - private com.azure.data.cosmos.serialization.hybridrow.SchemaId SchemaId = new SchemaId(); - - public UdtPropertyType() { - this.setSchemaId(com.azure.data.cosmos.serialization.hybridrow.SchemaId.INVALID); + public final SchemaId schemaId() { + return this.schemaId; } - public final String getName() { - return Name; - } - - public final void setName(String value) { - Name = value; - } - - public final SchemaId getSchemaId() { - return SchemaId; - } - - public final void setSchemaId(SchemaId value) { - SchemaId = value.clone(); + public final UdtPropertyType schemaId(SchemaId value) { + this.schemaId = value; + return this; } } \ No newline at end of file