Progressed on port from dotnet to java

This commit is contained in:
David Noble
2019-09-06 16:47:45 -07:00
parent 56fb5163ca
commit be7544d966
33 changed files with 897 additions and 952 deletions

View File

@@ -5,18 +5,31 @@ package com.azure.data.cosmos.core;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.ObjectWriter;
import java.io.IOException;
import java.util.Optional;
import static com.google.common.base.Strings.lenientFormat; import static com.google.common.base.Strings.lenientFormat;
public final class Json { public final class Json {
private static final ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper mapper = new ObjectMapper();
private static final ObjectReader reader = mapper.reader();
private static final ObjectWriter writer = mapper.writer(); private static final ObjectWriter writer = mapper.writer();
private Json() { private Json() {
} }
public static <T> Optional<T> parse(String value) {
try {
return Optional.of(reader.<T>readValue(value));
} catch (IOException e) {
return Optional.empty();
}
}
public static String toString(Object object) { public static String toString(Object object) {
try { try {
return writer.writeValueAsString(object); return writer.writeValueAsString(object);

View File

@@ -27,6 +27,7 @@ public final class Float128 {
* The size (in bytes) of a {@link Float128}. * The size (in bytes) of a {@link Float128}.
*/ */
public static final int BYTES = 2 * Long.BYTES; public static final int BYTES = 2 * Long.BYTES;
public static final Float128 ZERO = new Float128(0L, 0L);
private final long high; private final long high;
private final long low; private final long low;

View File

@@ -6,7 +6,6 @@
package com.azure.data.cosmos.serialization.hybridrow; package com.azure.data.cosmos.serialization.hybridrow;
import com.azure.data.cosmos.core.Out; 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.core.Utf8String;
import com.azure.data.cosmos.serialization.hybridrow.codecs.DateTimeCodec; import com.azure.data.cosmos.serialization.hybridrow.codecs.DateTimeCodec;
import com.azure.data.cosmos.serialization.hybridrow.codecs.DecimalCodec; import com.azure.data.cosmos.serialization.hybridrow.codecs.DecimalCodec;
@@ -70,6 +69,7 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Optional; 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.Preconditions.checkState;
import static com.google.common.base.Strings.lenientFormat; 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; //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()); 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<Integer> tempOut_metaBytes = new Out<Integer>();
int spaceNeeded;
Out<Integer> tempOut_spaceNeeded = new Out<Integer>();
int shiftInsert;
Out<Integer> tempOut_shiftInsert = new Out<Integer>();
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<Integer> tempOut_metaBytes2 = new Out<Integer>();
Out<Integer> tempOut_spaceNeeded2 = new Out<Integer>();
int shiftDelete;
Out<Integer> tempOut_shiftDelete = new Out<Integer>();
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.
* <p>
* The <paramref name="scope" /> MUST be a set or map scope.
* <p>
* The scope may have been built (e.g. via RowWriter) with relaxed uniqueness constraint checking.
* This operation rebuilds an index to support verification of uniqueness constraints during
* subsequent partial updates. If the appropriate uniqueness constraints cannot be established (i.e.
* a duplicate exists), this operation fails. Before continuing, the resulting scope should either:
* <list type="number">
* <item>
* <description>
* Be repaired (e.g. by deleting duplicates) and the index rebuild operation should be
* run again.
* </description>
* </item> <item>
* <description>Be deleted. The entire scope should be removed including its items.</description>
* </item>
* </list> Failure to perform one of these actions will leave the row is potentially in a corrupted
* state where partial updates may subsequent fail.
* </p>
* <p>
* The target <paramref name="scope" /> may or may not have already been indexed. This
* operation is idempotent.
* </p>
*/
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<UniqueIndexItem> 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<RowCursor> tempReference_dstEdit =
new Reference<RowCursor>(edit);
this.readSparseMetadata(tempReference_dstEdit);
edit = tempReference_dstEdit;
Contract.Assert(edit.pathOffset() ==
default)
Reference<RowCursor> tempReference_dstEdit2 =
new Reference<RowCursor>(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<UniqueIndexItem> p = new Span<UniqueIndexItem>(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<RowCursor> newScope) {
TypeArgumentList typeArgs = new TypeArgumentList(udt.schemaId().clone());
int numBytes = udt.size() + LayoutCode.BYTES;
int metaBytes;
final Out<Integer> metaBytes = new Out<>();
int spaceNeeded;
final Out<Integer> spaceNeeded = new Out<>();
int shift;
final Out<Integer> 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<RowCursor> newScope) {
int numBytes = Integer.BYTES;
int metaBytes;
final Out<Integer> metaBytes = new Out<>();
int spaceNeeded;
final Out<Integer> spaceNeeded = new Out<>();
int shift;
final Out<Integer> 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<RowCursor> newScope) {
int numBytes = Integer.BYTES; // Sized scope.
int metaBytes;
final Out<Integer> metaBytes = new Out<>();
int spaceNeeded;
final Out<Integer> spaceNeeded = new Out<>();
int shift;
final Out<Integer> 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 * 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; 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<Integer> metaBytes = new Out<>();
// int spaceNeeded;
// final Out<Integer> spaceNeeded = new Out<>();
// int shift;
// final Out<Integer> 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 * 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(); 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<Integer> metaBytes = new Out<>();
// int spaceNeeded;
// final Out<Integer> spaceNeeded = new Out<>();
// int shift;
// final Out<Integer> 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) { public void incrementUInt32(final int offset, final long increment) {
final long value = this.buffer.getUnsignedIntLE(offset); final long value = this.buffer.getUnsignedIntLE(offset);
this.buffer.setIntLE(offset, (int) (value + increment)); this.buffer.setIntLE(offset, (int) (value + increment));
} }
// TODO: DANOBLE: resurrect this method
// public MongoDbObjectId ReadMongoDbObjectId(int offset) {
// return MemoryMarshal.<MongoDbObjectId>Read(this.buffer.Slice(offset));
// }
/** /**
* Initializes a row to the minimal size for the given layout. * Initializes a row to the minimal size for the given layout.
* *
@@ -640,6 +387,11 @@ public final class RowBuffer {
return item.value(); return item.value();
} }
// TODO: DANOBLE: resurrect this method
// public MongoDbObjectId ReadMongoDbObjectId(int offset) {
// return MemoryMarshal.<MongoDbObjectId>Read(this.buffer.Slice(offset));
// }
public boolean readBit(final int offset, @Nonnull final LayoutBit bit) { public boolean readBit(final int offset, @Nonnull final LayoutBit bit) {
checkNotNull(bit, "expected non-null bit"); checkNotNull(bit, "expected non-null bit");
@@ -652,13 +404,6 @@ public final class RowBuffer {
return item.value(); return item.value();
} }
// TODO: DANOBLE: resurrect this method
// public MongoDbObjectId ReadSparseMongoDbObjectId(Reference<RowCursor> edit) {
// this.readSparsePrimitiveTypeCode(edit, MongoDbObjectId);
// edit.endOffset = edit.valueOffset() + MongoDbObjectId.Size;
// return this.ReadMongoDbObjectId(edit.valueOffset()).clone();
// }
public OffsetDateTime readDateTime(int offset) { public OffsetDateTime readDateTime(int offset) {
Item<OffsetDateTime> item = this.read(() -> DateTimeCodec.decode(this.buffer), offset); Item<OffsetDateTime> item = this.read(() -> DateTimeCodec.decode(this.buffer), offset);
return item.value(); return item.value();
@@ -684,6 +429,13 @@ public final class RowBuffer {
return item.value(); return item.value();
} }
// TODO: DANOBLE: resurrect this method
// public MongoDbObjectId ReadSparseMongoDbObjectId(Reference<RowCursor> edit) {
// this.readSparsePrimitiveTypeCode(edit, MongoDbObjectId);
// edit.endOffset = edit.valueOffset() + MongoDbObjectId.Size;
// return this.ReadMongoDbObjectId(edit.valueOffset()).clone();
// }
public float readFloat32(int offset) { public float readFloat32(int offset) {
Item<Float> item = this.read(this.buffer::readFloatLE, offset); Item<Float> item = this.read(this.buffer::readFloatLE, offset);
return item.value(); return item.value();
@@ -997,14 +749,6 @@ public final class RowBuffer {
return item.value(); return item.value();
} }
// TODO: DANOBLE: Support MongoDbObjectId values
// public void WriteMongoDbObjectId(int offset, MongoDbObjectId value) {
// Reference<azure.data.cosmos.serialization.hybridrow.MongoDbObjectId> tempReference_value =
// new Reference<azure.data.cosmos.serialization.hybridrow.MongoDbObjectId>(value);
// MemoryMarshal.Write(this.buffer.Slice(offset), tempReference_value);
// value = tempReference_value.get();
// }
public long readVariableInt(int offset) { public long readVariableInt(int offset) {
Item<Long> item = this.read(this::read7BitEncodedInt, offset); Item<Long> item = this.read(this::read7BitEncodedInt, offset);
return item.value(); return item.value();
@@ -1035,6 +779,14 @@ public final class RowBuffer {
return this.resolver; return this.resolver;
} }
// TODO: DANOBLE: Support MongoDbObjectId values
// public void WriteMongoDbObjectId(int offset, MongoDbObjectId value) {
// Reference<azure.data.cosmos.serialization.hybridrow.MongoDbObjectId> tempReference_value =
// new Reference<azure.data.cosmos.serialization.hybridrow.MongoDbObjectId>(value);
// MemoryMarshal.Write(this.buffer.Slice(offset), tempReference_value);
// value = tempReference_value.get();
// }
/** /**
* Rotates the sign bit of a two's complement value to the least significant bit * 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) { 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() return new RowCursor()
.scopeType(scopeType) .scopeType(scopeType)
@@ -1257,6 +1009,150 @@ public final class RowBuffer {
return content; 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<Integer> metaBytes = new Out<>();
Out<Integer> spaceNeeded = new Out<>();
Out<Integer> shiftInsert = new Out<>();
Out<Integer> 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.
* <p>
* The <paramref name="scope" /> MUST be a set or map scope.
* <p>
* The scope may have been built (e.g. via RowWriter) with relaxed uniqueness constraint checking.
* This operation rebuilds an index to support verification of uniqueness constraints during
* subsequent partial updates. If the appropriate uniqueness constraints cannot be established (i.e.
* a duplicate exists), this operation fails. Before continuing, the resulting scope should either:
* <list type="number">
* <item>
* <description>
* Be repaired (e.g. by deleting duplicates) and the index rebuild operation should be
* run again.
* </description>
* </item> <item>
* <description>Be deleted. The entire scope should be removed including its items.</description>
* </item>
* </list> Failure to perform one of these actions will leave the row is potentially in a corrupted
* state where partial updates may subsequent fail.
* </p>
* <p>
* The target <paramref name="scope" /> may or may not have already been indexed. This
* operation is idempotent.
* </p>
*/
@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) { public void unsetBit(final int offset, @Nonnull final LayoutBit bit) {
checkNotNull(bit, "expected non-null bit"); checkNotNull(bit, "expected non-null bit");
checkArgument(!bit.isInvalid()); checkArgument(!bit.isInvalid());
@@ -1299,7 +1195,6 @@ public final class RowBuffer {
} }
public void writeFixedBinary(final int offset, @Nonnull final ByteBuf value, final int length) { public void writeFixedBinary(final int offset, @Nonnull final ByteBuf value, final int length) {
checkNotNull(value, "expected non-null value"); checkNotNull(value, "expected non-null value");
checkArgument(offset >= 0, "expected offset >= 0, not %s", offset); checkArgument(offset >= 0, "expected offset >= 0, not %s", offset);
checkArgument(length >= 0, "expected length >= 0, not %s", length); checkArgument(length >= 0, "expected length >= 0, not %s", length);
@@ -1313,6 +1208,13 @@ public final class RowBuffer {
}, offset, value); }, 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) { public void writeFixedBinary(final int offset, @Nonnull final byte[] value, final int index, final int length) {
checkNotNull(value, "expected non-null value"); checkNotNull(value, "expected non-null value");
@@ -1888,6 +1790,43 @@ public final class RowBuffer {
this.writeUInt8(offset, code.value()); 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<Integer> metaBytes = new Out<>();
final Out<Integer> spaceNeeded = new Out<>();
final Out<Integer> 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( public void writeSparseUInt16(
@Nonnull final RowCursor edit, final short value, @Nonnull final UpdateOptions options) { @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()); 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<Integer> metaBytes = new Out<>();
final Out<Integer> spaceNeeded = new Out<>();
final Out<Integer> 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<Integer> metaBytes = new Out<>();
final Out<Integer> spaceNeeded = new Out<>();
final Out<Integer> 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 @Nonnull
public RowCursor writeTypedSet( public RowCursor writeTypedSet(
@Nonnull final RowCursor edit, @Nonnull final RowCursor edit,
@@ -2423,7 +2427,7 @@ public final class RowBuffer {
} }
if (code instanceof LayoutTypedArray || code instanceof LayoutTypedSet || code instanceof LayoutTypedMap) { 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. // 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) { if (code instanceof LayoutTuple) {
// Fixed arity sparse collections take 1 byte for end-of-scope plus a null for each element. // 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.pathOffset() == 0);
checkState(edit.pathToken() == 0); checkState(edit.pathToken() == 0);
} else { } else {
int offset = edit.metaOffset() + LayoutCode.SIZE; int offset = edit.metaOffset() + LayoutCode.BYTES;
Out<Integer> pathLenInBytes = new Out<>(); Out<Integer> pathLenInBytes = new Out<>();
Out<Integer> pathOffset = new Out<>(); Out<Integer> pathOffset = new Out<>();
int token = this.readSparsePathLen(edit.layout(), offset, pathLenInBytes, pathOffset); int token = this.readSparsePathLen(edit.layout(), offset, pathLenInBytes, pathOffset);
@@ -3147,7 +3151,7 @@ public final class RowBuffer {
} }
if (code == LayoutTypes.FLOAT_128) { if (code == LayoutTypes.FLOAT_128) {
this.writeFloat128(offset, null); this.writeFloat128(offset, Float128.ZERO);
return LayoutTypes.FLOAT_128.size(); return LayoutTypes.FLOAT_128.size();
} }
@@ -3162,12 +3166,12 @@ public final class RowBuffer {
} }
if (code == LayoutTypes.UNIX_DATE_TIME) { if (code == LayoutTypes.UNIX_DATE_TIME) {
this.writeUnixDateTime(offset, null); this.writeUnixDateTime(offset, UnixDateTime.EPOCH);
return LayoutTypes.UNIX_DATE_TIME.size(); return LayoutTypes.UNIX_DATE_TIME.size();
} }
if (code == LayoutTypes.GUID) { if (code == LayoutTypes.GUID) {
this.writeGuid(offset, null); this.writeGuid(offset, GuidCodec.EMPTY);
return LayoutTypes.GUID.size(); 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) { 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. // Variable length types preceded by their varuint size take 1 byte for a size of 0
return this.write7BitEncodedUInt(offset, 0); return this.write(this::write7BitEncodedUInt, offset, 0L).length();
} }
if (code == LayoutTypes.OBJECT || code == LayoutTypes.ARRAY) { 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) { 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. // Variable length typed collection scopes preceded by their scope size take sizeof(uint) for a size of 0.
this.writeUInt32(offset, 0); this.writeUInt32(offset, 0);
return (Integer.SIZE / Byte.SIZE); return Integer.BYTES;
} }
if (code == LayoutTypes.TUPLE) { if (code == LayoutTypes.TUPLE) {
@@ -3223,14 +3227,15 @@ public final class RowBuffer {
if (code == LayoutTypes.UDT) { if (code == LayoutTypes.UDT) {
// Clear all presence bits. // Clear all presence bits
Layout udt = this.resolver.resolve(typeArgs.schemaId()); 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); this.writeSparseTypeCode(offset + udt.size(), LayoutCode.END_SCOPE);
return udt.size() + LayoutCode.BYTES; return udt.size() + LayoutCode.BYTES;
} }
throw new IllegalStateException(lenientFormat("Not Implemented: %s", code)); throw new IllegalStateException(lenientFormat("Not Implemented: %s", code));
} }
@@ -3291,6 +3296,7 @@ public final class RowBuffer {
} }
} }
private void writeUInt16(Short value) { private void writeUInt16(Short value) {
this.buffer.writeShortLE(value); this.buffer.writeShortLE(value);
} }
@@ -3361,20 +3367,20 @@ public final class RowBuffer {
*/ */
static final class UniqueIndexItem { static final class UniqueIndexItem {
private LayoutCode Code = LayoutCode.values()[0]; private LayoutCode code = LayoutCode.values()[0];
private int MetaOffset; private int metaOffset;
private int Size; private int size;
private int ValueOffset; private int valueOffset;
/** /**
* The layout code of the value. * The layout code of the value.
*/ */
public LayoutCode code() { public LayoutCode code() {
return this.Code; return this.code;
} }
public UniqueIndexItem code(LayoutCode code) { public UniqueIndexItem code(LayoutCode code) {
this.Code = code; this.code = code;
return this; 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 * If existing, the offset to the metadata of the existing field, otherwise the location to insert a new field
*/ */
public int metaOffset() { public int metaOffset() {
return this.MetaOffset; return this.metaOffset;
} }
public UniqueIndexItem metaOffset(int metaOffset) { public UniqueIndexItem metaOffset(int metaOffset) {
this.MetaOffset = metaOffset; this.metaOffset = metaOffset;
return this; return this;
} }
@@ -3394,11 +3400,11 @@ public final class RowBuffer {
* Size of the target element * Size of the target element
*/ */
public int size() { public int size() {
return this.Size; return this.size;
} }
public UniqueIndexItem size(int size) { public UniqueIndexItem size(int size) {
this.Size = size; this.size = size;
return this; return this;
} }
@@ -3406,11 +3412,11 @@ public final class RowBuffer {
* If existing, the offset to the value of the existing field, otherwise undefined * If existing, the offset to the value of the existing field, otherwise undefined
*/ */
public int valueOffset() { public int valueOffset() {
return this.ValueOffset; return this.valueOffset;
} }
public UniqueIndexItem valueOffset(int valueOffset) { public UniqueIndexItem valueOffset(int valueOffset) {
this.ValueOffset = valueOffset; this.valueOffset = valueOffset;
return this; return this;
} }
} }

View File

@@ -15,6 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
public final class GuidCodec { public final class GuidCodec {
public static final int BYTES = 2 * Long.BYTES; public static final int BYTES = 2 * Long.BYTES;
public static final UUID EMPTY = new UUID(0L, 0L);
private GuidCodec() { private GuidCodec() {
} }

View File

@@ -410,7 +410,7 @@ public final class RowWriter {
new Reference<RowCursor>(this.cursor); new Reference<RowCursor>(this.cursor);
Out<RowCursor> tempOut_nestedScope3 = Out<RowCursor> tempOut_nestedScope3 =
new Out<RowCursor>(); new Out<RowCursor>();
this.row.WriteTypedArray(tempRef_cursor3, scopeType, typeArg.typeArgs().clone(), this.row.writeTypedArray(tempRef_cursor3, scopeType, typeArg.typeArgs().clone(),
UpdateOptions.Upsert, tempOut_nestedScope3); UpdateOptions.Upsert, tempOut_nestedScope3);
nestedScope = tempOut_nestedScope3.get(); nestedScope = tempOut_nestedScope3.get();
this.cursor = tempRef_cursor3.argValue; this.cursor = tempRef_cursor3.argValue;
@@ -495,7 +495,7 @@ public final class RowWriter {
new Reference<RowCursor>(this.cursor); new Reference<RowCursor>(this.cursor);
Out<RowCursor> tempOut_nestedScope9 = Out<RowCursor> tempOut_nestedScope9 =
new Out<RowCursor>(); new Out<RowCursor>();
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(); nestedScope = tempOut_nestedScope9.get();
this.cursor = tempReference_cursor9.get(); this.cursor = tempReference_cursor9.get();
break; break;
@@ -522,8 +522,8 @@ public final class RowWriter {
new Reference<RowCursor>(this.cursor); new Reference<RowCursor>(this.cursor);
Out<RowCursor> tempOut_nestedScope11 = Out<RowCursor> tempOut_nestedScope11 =
new Out<RowCursor>(); new Out<RowCursor>();
this.row.WriteTypedMap(tempRef_cursor11, scopeType, typeArg.typeArgs().clone(), this.row.writeTypedMap(tempRef_cursor11, scopeType, typeArg.typeArgs().clone(),
UpdateOptions.Upsert, tempOut_nestedScope11); UpdateOptions.Upsert);
nestedScope = tempOut_nestedScope11.get(); nestedScope = tempOut_nestedScope11.get();
this.cursor = tempRef_cursor11.argValue; this.cursor = tempRef_cursor11.argValue;
@@ -556,7 +556,7 @@ public final class RowWriter {
if (type instanceof LayoutUniqueScope) { if (type instanceof LayoutUniqueScope) {
Reference<RowCursor> tempReference_nestedScope2 = Reference<RowCursor> tempReference_nestedScope2 =
new Reference<RowCursor>(nestedScope); new Reference<RowCursor>(nestedScope);
result = this.row.TypedCollectionUniqueIndexRebuild(tempReference_nestedScope2); result = this.row.typedCollectionUniqueIndexRebuild(tempReference_nestedScope2);
nestedScope = tempReference_nestedScope2.get(); nestedScope = tempReference_nestedScope2.get();
if (result != Result.SUCCESS) { if (result != Result.SUCCESS) {
// TODO: If the index rebuild fails then the row is corrupted. Should we automatically clean up here? // TODO: If the index rebuild fails then the row is corrupted. Should we automatically clean up here?

View File

@@ -13,12 +13,9 @@ import com.google.common.collect.ImmutableList;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Stream;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; 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 * order and type of columns defines the physical ordering of bytes used to encode the row and impacts the cost of
* updating the row. * updating the row.
* <p> * <p>
* 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}. * a {@link LayoutBuilder}.
* *
* {@link Layout} is immutable. * {@link Layout} is immutable.

View File

@@ -38,12 +38,12 @@ public final class LayoutCompiler {
public static Layout Compile(Namespace ns, Schema schema) { public static Layout Compile(Namespace ns, Schema schema) {
checkArgument(ns != null); checkArgument(ns != null);
checkArgument(schema != null); checkArgument(schema != null);
checkArgument(schema.getType() == TypeKind.Schema); checkArgument(schema.type() == TypeKind.Schema);
checkArgument(!tangible.StringHelper.isNullOrWhiteSpace(schema.getName())); checkArgument(!tangible.StringHelper.isNullOrWhiteSpace(schema.name()));
checkArgument(ns.getSchemas().contains(schema)); checkArgument(ns.schemas().contains(schema));
LayoutBuilder builder = new LayoutBuilder(schema.getName(), schema.getSchemaId().clone()); LayoutBuilder builder = new LayoutBuilder(schema.name(), schema.schemaId().clone());
LayoutCompiler.AddProperties(builder, ns, LayoutCode.SCHEMA, schema.getProperties()); LayoutCompiler.AddProperties(builder, ns, LayoutCode.SCHEMA, schema.properties());
return builder.build(); return builder.build();
} }
@@ -54,17 +54,17 @@ public final class LayoutCompiler {
TypeArgumentList typeArgs = new TypeArgumentList(); TypeArgumentList typeArgs = new TypeArgumentList();
Out<TypeArgumentList> tempOut_typeArgs = Out<TypeArgumentList> tempOut_typeArgs =
new Out<TypeArgumentList>(); new Out<TypeArgumentList>();
LayoutType type = LayoutCompiler.LogicalToPhysicalType(ns, p.getPropertyType(), tempOut_typeArgs); LayoutType type = LayoutCompiler.LogicalToPhysicalType(ns, p.propertyType(), tempOut_typeArgs);
typeArgs = tempOut_typeArgs.get(); typeArgs = tempOut_typeArgs.get();
switch (LayoutCodeTraits.ClearImmutableBit(type.LayoutCode)) { switch (LayoutCodeTraits.ClearImmutableBit(type.LayoutCode)) {
case OBJECT_SCOPE: { case OBJECT_SCOPE: {
if (!p.getPropertyType().getNullable()) { if (!p.propertyType().nullable()) {
throw new LayoutCompilationException("Non-nullable sparse column are not supported."); throw new LayoutCompilationException("Non-nullable sparse column are not supported.");
} }
ObjectPropertyType op = (ObjectPropertyType)p.getPropertyType(); ObjectPropertyType op = (ObjectPropertyType)p.propertyType();
builder.addObjectScope(p.getPath(), type); builder.addObjectScope(p.path(), type);
LayoutCompiler.AddProperties(builder, ns, type.LayoutCode, op.getProperties()); LayoutCompiler.AddProperties(builder, ns, type.LayoutCode, op.properties());
builder.EndObjectScope(); builder.EndObjectScope();
break; break;
} }
@@ -80,11 +80,11 @@ public final class LayoutCompiler {
case TAGGED_SCOPE: case TAGGED_SCOPE:
case TAGGED2_SCOPE: case TAGGED2_SCOPE:
case SCHEMA: { case SCHEMA: {
if (!p.getPropertyType().getNullable()) { if (!p.propertyType().nullable()) {
throw new LayoutCompilationException("Non-nullable sparse column are not supported."); 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; break;
} }
@@ -93,23 +93,23 @@ public final class LayoutCompiler {
} }
default: { default: {
PropertyType tempVar = p.getPropertyType(); PropertyType tempVar = p.propertyType();
PrimitivePropertyType pp = tempVar instanceof PrimitivePropertyType ? PrimitivePropertyType pp = tempVar instanceof PrimitivePropertyType ?
(PrimitivePropertyType)tempVar : null; (PrimitivePropertyType)tempVar : null;
if (pp != null) { if (pp != null) {
switch (pp.getStorage()) { switch (pp.storage()) {
case Fixed: case Fixed:
if (LayoutCodeTraits.ClearImmutableBit(scope) != LayoutCode.SCHEMA) { if (LayoutCodeTraits.ClearImmutableBit(scope) != LayoutCode.SCHEMA) {
throw new LayoutCompilationException("Cannot have fixed storage within a sparse " + throw new LayoutCompilationException("Cannot have fixed storage within a sparse " +
"scope."); "scope.");
} }
if (type.getIsNull() && !pp.getNullable()) { if (type.getIsNull() && !pp.nullable()) {
throw new LayoutCompilationException("Non-nullable null columns are not supported" + 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; break;
case Variable: case Variable:
if (LayoutCodeTraits.ClearImmutableBit(scope) != LayoutCode.SCHEMA) { if (LayoutCodeTraits.ClearImmutableBit(scope) != LayoutCode.SCHEMA) {
@@ -117,24 +117,24 @@ public final class LayoutCompiler {
"sparse scope."); "sparse scope.");
} }
if (!pp.getNullable()) { if (!pp.nullable()) {
throw new LayoutCompilationException("Non-nullable variable columns are not " + throw new LayoutCompilationException("Non-nullable variable columns are not " +
"supported."); "supported.");
} }
builder.addVariableColumn(p.getPath(), type, pp.getLength()); builder.addVariableColumn(p.path(), type, pp.length());
break; break;
case Sparse: case Sparse:
if (!pp.getNullable()) { if (!pp.nullable()) {
throw new LayoutCompilationException("Non-nullable sparse columns are not " + throw new LayoutCompilationException("Non-nullable sparse columns are not " +
"supported."); "supported.");
} }
builder.addSparseColumn(p.getPath(), type); builder.addSparseColumn(p.path(), type);
break; break;
default: default:
throw new LayoutCompilationException(String.format("Unknown storage specification: " + throw new LayoutCompilationException(String.format("Unknown storage specification: " +
"%1$s", pp.getStorage())); "%1$s", pp.storage()));
} }
} else { } else {
throw new LayoutCompilationException(String.format("Unknown property type: %1$s", throw new LayoutCompilationException(String.format("Unknown property type: %1$s",
@@ -151,12 +151,12 @@ public final class LayoutCompiler {
Out<TypeArgumentList> typeArgs) { Out<TypeArgumentList> typeArgs) {
typeArgs.setAndGet(TypeArgumentList.EMPTY); typeArgs.setAndGet(TypeArgumentList.EMPTY);
boolean tempVar = boolean tempVar =
(logicalType instanceof ScopePropertyType ? (ScopePropertyType)logicalType : null).getImmutable(); (logicalType instanceof ScopePropertyType ? (ScopePropertyType)logicalType : null).immutable();
boolean immutable = boolean immutable =
(logicalType instanceof ScopePropertyType ? (ScopePropertyType)logicalType : null) == null ? null : (logicalType instanceof ScopePropertyType ? (ScopePropertyType)logicalType : null) == null ? null :
tempVar != null && tempVar; tempVar != null && tempVar;
switch (logicalType.getType()) { switch (logicalType.type()) {
case Null: case Null:
return LayoutType.Null; return LayoutType.Null;
case Boolean: case Boolean:
@@ -206,12 +206,12 @@ public final class LayoutCompiler {
return immutable ? LayoutType.ImmutableObject : LayoutType.Object; return immutable ? LayoutType.ImmutableObject : LayoutType.Object;
case Array: case Array:
ArrayPropertyType ap = (ArrayPropertyType)logicalType; 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(); TypeArgumentList itemTypeArgs = new TypeArgumentList();
Out<TypeArgumentList> tempOut_itemTypeArgs = new Out<TypeArgumentList>(); Out<TypeArgumentList> tempOut_itemTypeArgs = new Out<TypeArgumentList>();
LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, ap.getItems(), tempOut_itemTypeArgs); LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, ap.items(), tempOut_itemTypeArgs);
itemTypeArgs = tempOut_itemTypeArgs.get(); itemTypeArgs = tempOut_itemTypeArgs.get();
if (ap.getItems().getNullable()) { if (ap.items().nullable()) {
itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType, itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
itemTypeArgs.clone()) }); itemTypeArgs.clone()) });
itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable; itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
@@ -225,13 +225,13 @@ public final class LayoutCompiler {
return immutable ? LayoutType.ImmutableArray : LayoutType.Array; return immutable ? LayoutType.ImmutableArray : LayoutType.Array;
case Set: case Set:
SetPropertyType sp = (SetPropertyType)logicalType; 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(); TypeArgumentList itemTypeArgs = new TypeArgumentList();
Out<TypeArgumentList> tempOut_itemTypeArgs2 = new Out<TypeArgumentList>(); Out<TypeArgumentList> tempOut_itemTypeArgs2 = new Out<TypeArgumentList>();
LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, sp.getItems(), LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, sp.items(),
tempOut_itemTypeArgs2); tempOut_itemTypeArgs2);
itemTypeArgs = tempOut_itemTypeArgs2.get(); itemTypeArgs = tempOut_itemTypeArgs2.get();
if (sp.getItems().getNullable()) { if (sp.items().nullable()) {
itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType, itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
itemTypeArgs.clone()) }); itemTypeArgs.clone()) });
itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable; itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
@@ -244,16 +244,16 @@ public final class LayoutCompiler {
// TODO(283638): implement sparse set. // TODO(283638): implement sparse set.
throw new LayoutCompilationException(String.format("Unknown property type: %1$s", throw new LayoutCompilationException(String.format("Unknown property type: %1$s",
logicalType.getType())); logicalType.type()));
case Map: case Map:
MapPropertyType mp = (MapPropertyType)logicalType; 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(); TypeArgumentList keyTypeArgs = new TypeArgumentList();
Out<TypeArgumentList> tempOut_keyTypeArgs = new Out<TypeArgumentList>(); Out<TypeArgumentList> tempOut_keyTypeArgs = new Out<TypeArgumentList>();
LayoutType keyType = LayoutCompiler.LogicalToPhysicalType(ns, mp.getKeys(), tempOut_keyTypeArgs); LayoutType keyType = LayoutCompiler.LogicalToPhysicalType(ns, mp.keys(), tempOut_keyTypeArgs);
keyTypeArgs = tempOut_keyTypeArgs.get(); keyTypeArgs = tempOut_keyTypeArgs.get();
if (mp.getKeys().getNullable()) { if (mp.keys().nullable()) {
keyTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(keyType, keyTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(keyType,
keyTypeArgs.clone()) }); keyTypeArgs.clone()) });
keyType = keyType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable; keyType = keyType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
@@ -261,10 +261,10 @@ public final class LayoutCompiler {
TypeArgumentList valueTypeArgs = new TypeArgumentList(); TypeArgumentList valueTypeArgs = new TypeArgumentList();
Out<TypeArgumentList> tempOut_valueTypeArgs = new Out<TypeArgumentList>(); Out<TypeArgumentList> tempOut_valueTypeArgs = new Out<TypeArgumentList>();
LayoutType valueType = LayoutCompiler.LogicalToPhysicalType(ns, mp.getValues(), LayoutType valueType = LayoutCompiler.LogicalToPhysicalType(ns, mp.values(),
tempOut_valueTypeArgs); tempOut_valueTypeArgs);
valueTypeArgs = tempOut_valueTypeArgs.get(); valueTypeArgs = tempOut_valueTypeArgs.get();
if (mp.getValues().getNullable()) { if (mp.values().nullable()) {
valueTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(valueType, valueTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(valueType,
valueTypeArgs.clone()) }); valueTypeArgs.clone()) });
valueType = valueType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable; valueType = valueType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
@@ -280,18 +280,18 @@ public final class LayoutCompiler {
// TODO(283638): implement sparse map. // TODO(283638): implement sparse map.
throw new LayoutCompilationException(String.format("Unknown property type: %1$s", throw new LayoutCompilationException(String.format("Unknown property type: %1$s",
logicalType.getType())); logicalType.type()));
case Tuple: case Tuple:
TuplePropertyType tp = (TuplePropertyType)logicalType; TuplePropertyType tp = (TuplePropertyType)logicalType;
TypeArgument[] args = new TypeArgument[tp.getItems().size()]; TypeArgument[] args = new TypeArgument[tp.items().size()];
for (int i = 0; i < tp.getItems().size(); i++) { for (int i = 0; i < tp.items().size(); i++) {
TypeArgumentList itemTypeArgs = new TypeArgumentList(); TypeArgumentList itemTypeArgs = new TypeArgumentList();
Out<TypeArgumentList> tempOut_itemTypeArgs3 = new Out<TypeArgumentList>(); Out<TypeArgumentList> tempOut_itemTypeArgs3 = new Out<TypeArgumentList>();
LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, tp.getItems().get(i), LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, tp.items().get(i),
tempOut_itemTypeArgs3); tempOut_itemTypeArgs3);
itemTypeArgs = tempOut_itemTypeArgs3.get(); 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 = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
itemTypeArgs.clone()) }); itemTypeArgs.clone()) });
itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable; itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
@@ -305,21 +305,21 @@ public final class LayoutCompiler {
case Tagged: case Tagged:
TaggedPropertyType tg = (TaggedPropertyType)logicalType; 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 " + 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)); 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); 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(); TypeArgumentList itemTypeArgs = new TypeArgumentList();
Out<TypeArgumentList> tempOut_itemTypeArgs4 = new Out<TypeArgumentList>(); Out<TypeArgumentList> tempOut_itemTypeArgs4 = new Out<TypeArgumentList>();
LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, tg.getItems().get(i), LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, tg.items().get(i),
tempOut_itemTypeArgs4); tempOut_itemTypeArgs4);
itemTypeArgs = tempOut_itemTypeArgs4.get(); 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 = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
itemTypeArgs.clone()) }); itemTypeArgs.clone()) });
itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable; itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
@@ -329,7 +329,7 @@ public final class LayoutCompiler {
} }
typeArgs.setAndGet(new TypeArgumentList(tgArgs)); typeArgs.setAndGet(new TypeArgumentList(tgArgs));
switch (tg.getItems().size()) { switch (tg.items().size()) {
case 1: case 1:
return immutable ? LayoutType.ImmutableTagged : LayoutType.Tagged; return immutable ? LayoutType.ImmutableTagged : LayoutType.Tagged;
case 2: case 2:
@@ -341,28 +341,28 @@ public final class LayoutCompiler {
case Schema: case Schema:
UdtPropertyType up = (UdtPropertyType)logicalType; UdtPropertyType up = (UdtPropertyType)logicalType;
Schema udtSchema; Schema udtSchema;
if (SchemaId.opEquals(up.getSchemaId().clone(), SchemaId.INVALID)) { if (SchemaId.opEquals(up.schemaId().clone(), SchemaId.INVALID)) {
udtSchema = tangible.ListHelper.find(ns.getSchemas(), s = up.getName().equals( > s.Name)) udtSchema = tangible.ListHelper.find(ns.schemas(), s = up.name().equals( > s.Name))
} else { } else {
udtSchema = tangible.ListHelper.find(ns.getSchemas(), s = udtSchema = tangible.ListHelper.find(ns.schemas(), s =
SchemaId.opEquals( > s.SchemaId, up.getSchemaId().clone())) SchemaId.opEquals( > s.SchemaId, up.schemaId().clone()))
if (!udtSchema.getName().equals(up.getName())) { if (!udtSchema.name().equals(up.name())) {
throw new LayoutCompilationException(String.format("Ambiguous schema reference: '%1$s:%2$s'", 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) { if (udtSchema == null) {
throw new LayoutCompilationException(String.format("Cannot resolve schema reference '%1$s:%2$s'", 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; return immutable ? LayoutType.ImmutableUDT : LayoutType.UDT;
default: default:
throw new LayoutCompilationException(String.format("Unknown property type: %1$s", throw new LayoutCompilationException(String.format("Unknown property type: %1$s",
logicalType.getType())); logicalType.type()));
} }
} }
} }

View File

@@ -53,10 +53,10 @@ public final class LayoutResolverNamespace extends LayoutResolver {
return layout; return layout;
} }
for (Schema s : this.schemaNamespace.getSchemas()) { for (Schema s : this.schemaNamespace.schemas()) {
if (SchemaId.opEquals(s.getSchemaId().clone(), if (SchemaId.opEquals(s.schemaId().clone(),
schemaId.clone())) { schemaId.clone())) {
layout = s.Compile(this.schemaNamespace); layout = s.compile(this.schemaNamespace);
layout = this.layoutCache.putIfAbsent(schemaId.value(), layout); layout = this.layoutCache.putIfAbsent(schemaId.value(), layout);
return layout; return layout;
} }

View File

@@ -91,7 +91,7 @@ public abstract class LayoutType<T> implements ILayoutType {
} }
public int countTypeArgument(TypeArgumentList value) { 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) { public final Result deleteFixed(RowBuffer b, RowCursor scope, LayoutColumn column) {
@@ -311,7 +311,9 @@ public abstract class LayoutType<T> implements ILayoutType {
* @return Success if the write is permitted, the error code otherwise. * @return Success if the write is permitted, the error code otherwise.
*/ */
public static Result prepareSparseWrite( 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) { @Nonnull final UpdateOptions options) {
if (edit.immutable() || (edit.scopeType().isUniqueScope() && !edit.deferUniqueIndex())) { if (edit.immutable() || (edit.scopeType().isUniqueScope() && !edit.deferUniqueIndex())) {
@@ -356,10 +358,10 @@ public abstract class LayoutType<T> implements ILayoutType {
public static TypeArgument readTypeArgument(RowBuffer row, int offset, Out<Integer> lenInBytes) { public static TypeArgument readTypeArgument(RowBuffer row, int offset, Out<Integer> lenInBytes) {
LayoutType itemCode = row.readSparseTypeCode(offset); LayoutType itemCode = row.readSparseTypeCode(offset);
int argsLenInBytes; int argsLenInBytes;
Out<Integer> tempOut_argsLenInBytes = new Out<Integer>(); Out<Integer> tempOut_argsLenInBytes = new Out<>();
TypeArgumentList itemTypeArgs = itemCode.readTypeArgumentList(row, offset + (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE), tempOut_argsLenInBytes); TypeArgumentList itemTypeArgs = itemCode.readTypeArgumentList(row, offset + LayoutCode.BYTES, tempOut_argsLenInBytes);
argsLenInBytes = tempOut_argsLenInBytes.get(); 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); return new TypeArgument(itemCode, itemTypeArgs);
} }
@@ -396,7 +398,7 @@ public abstract class LayoutType<T> implements ILayoutType {
public int writeTypeArgument(RowBuffer row, int offset, TypeArgumentList value) { public int writeTypeArgument(RowBuffer row, int offset, TypeArgumentList value) {
row.writeSparseTypeCode(offset, this.layoutCode()); row.writeSparseTypeCode(offset, this.layoutCode());
return com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE; return LayoutCode.BYTES;
} }
public Result writeVariable(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, T value) { public Result writeVariable(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, T value) {

View File

@@ -67,7 +67,7 @@ public abstract class LayoutUniqueScope extends LayoutIndexedScope {
// Perform the move. // Perform the move.
Reference<RowCursor> tempReference_dstEdit = Reference<RowCursor> tempReference_dstEdit =
new Reference<RowCursor>(dstEdit); new Reference<RowCursor>(dstEdit);
b.get().TypedCollectionMoveField(tempReference_dstEdit, sourceEdit, RowOptions.from(options)); b.get().typedCollectionMoveField(tempReference_dstEdit, sourceEdit, RowOptions.from(options));
dstEdit = tempReference_dstEdit.get(); dstEdit = tempReference_dstEdit.get();
// TODO: it would be "better" if the destinationScope were updated to point to the // TODO: it would be "better" if the destinationScope were updated to point to the

View File

@@ -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.ISpanResizer;
import com.azure.data.cosmos.serialization.hybridrow.Result; import com.azure.data.cosmos.serialization.hybridrow.Result;
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer; 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 final class RecordIOFormatter {
public static final Layout RecordLayout = SystemSchema.LayoutResolver.Resolve(SystemSchema.RecordSchemaId); public static final Layout RecordLayout = SystemSchema.LayoutResolver.resolve(SystemSchema.RecordSchemaId);
public static final Layout SegmentLayout = SystemSchema.LayoutResolver.Resolve(SystemSchema.SegmentSchemaId); public static final Layout SegmentLayout = SystemSchema.LayoutResolver.resolve(SystemSchema.SegmentSchemaId);
public static Result FormatRecord(ReadOnlyMemory<Byte> body, Out<RowBuffer> row) { public static Result FormatRecord(ReadOnlyMemory<Byte> body, Out<RowBuffer> row) {
return FormatRecord(body, row, null); return FormatRecord(body, row, null);

View File

@@ -6,24 +6,23 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
/** /**
* Array properties represent an unbounded set of zero or more items. * Array properties represent an unbounded set of zero or more items.
* <p> * <p>
* Arrays may be typed or untyped. Within typed arrays, all items MUST be the same type. The * Arrays may be typed or untyped. Within typed arrays, all items MUST be the same type. The type of items is specified
* type of items is specified via {@link Items}. Typed arrays may be stored more efficiently * via {@link #items}. Typed arrays may be stored more efficiently than untyped arrays. When {@link #items} is
* than untyped arrays. When {@link Items} is unspecified, the array is untyped and its items * unspecified, the array is untyped and its items may be heterogeneous.
* may be heterogeneous.
*/ */
public class ArrayPropertyType extends ScopePropertyType { public class ArrayPropertyType extends ScopePropertyType {
private PropertyType items;
/** /**
* (Optional) type of the elements of the array, if a typed array, otherwise null. * (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: public final PropertyType items() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "items")] public PropertyType Items {get;set;} return this.items;
private PropertyType Items;
public final PropertyType getItems() {
return Items;
} }
public final void setItems(PropertyType value) { public final ArrayPropertyType items(PropertyType value) {
Items = value; this.items = value;
return this;
} }
} }

View File

@@ -4,43 +4,39 @@
package com.azure.data.cosmos.serialization.hybridrow.schemas; package com.azure.data.cosmos.serialization.hybridrow.schemas;
/** /**
* Map properties represent an unbounded set of zero or more key-value pairs with unique * Map properties represent an unbounded set of zero or more key-value pairs with unique keys
* keys.
* <p> * <p>
* <p> * Maps are typed or untyped. Within typed maps, all key MUST be the same type, and all values MUST be the same type.
* Maps are typed or untyped. Within typed maps, all key MUST be the same type, and all * The type of both key and values is specified via {@link #keys} and {@link #values} respectively. Typed maps may be
* values MUST be the same type. The type of both key and values is specified via {@link Keys} * stored more efficiently than untyped maps. When {@link #keys} or {@link #values} is unspecified or marked
* and {@link Values} respectively. Typed maps may be stored more efficiently than untyped * {@link TypeKind#Any}, the map is untyped and its key and/or values may be heterogeneous.
* 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 { 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: public final PropertyType keys() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "keys")] public PropertyType Keys {get;set;} return this.keys;
private PropertyType 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: public final PropertyType values() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "values")] public PropertyType Values {get;set;} return this.values;
private PropertyType Values;
public final PropertyType getKeys() {
return Keys;
} }
public final void setKeys(PropertyType value) { public final MapPropertyType values(PropertyType value) {
Keys = value; this.values = value;
} return this;
public final PropertyType getValues() {
return Values;
}
public final void setValues(PropertyType value) {
Values = value;
} }
} }

View File

@@ -3,39 +3,15 @@
package com.azure.data.cosmos.serialization.hybridrow.schemas; 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.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 { public class Namespace {
/**
* The standard settings used by the JSON parser for interpreting {@link Namespace} private String name;
* documents. private SchemaLanguageVersion version = SchemaLanguageVersion.values()[0];
*/
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 ArrayList<Schema> schemas; private ArrayList<Schema> schemas;
/** /**
@@ -45,12 +21,15 @@ public class Namespace {
this.setSchemas(new ArrayList<Schema>()); this.setSchemas(new ArrayList<Schema>());
} }
/**
* The fully qualified identifier of the namespace.
*/
public final String getName() { public final String getName() {
return Name; return this.name;
} }
public final void setName(String value) { 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 * 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. * contain nested UDTs whose schemas are defined within the same namespace.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final ArrayList<Schema> schemas() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "schemas")] public List<Schema> Schemas
public final ArrayList<Schema> getSchemas() {
return this.schemas; return this.schemas;
} }
@@ -70,23 +47,26 @@ public class Namespace {
this.schemas = value != null ? value : new ArrayList<Schema>(); this.schemas = value != null ? value : new ArrayList<Schema>();
} }
/**
* The version of the HybridRow Schema Definition Language used to encode this namespace.
*/
public final SchemaLanguageVersion getVersion() { public final SchemaLanguageVersion getVersion() {
return Version; return this.version;
} }
public final void setVersion(SchemaLanguageVersion value) { public final void setVersion(SchemaLanguageVersion value) {
Version = value; this.version = value;
} }
/** /**
* Parse a JSON document and return a full namespace. * 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. * @return A namespace containing a set of logical schemas.
*/ */
public static Namespace Parse(String json) { public static Optional<Namespace> parse(String value) {
Namespace ns = JsonConvert.<Namespace>DeserializeObject(json, Namespace.NamespaceParseSettings); Optional<Namespace> ns = Json.<Namespace>parse(value);
SchemaValidator.Validate(ns); ns.ifPresent(SchemaValidator::Validate);
return ns; return ns;
} }
} }

View File

@@ -3,39 +3,36 @@
package com.azure.data.cosmos.serialization.hybridrow.schemas; 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 represent nested structures.
* <p> * <p>
* Object properties map to multiple columns depending on the number of internal properties * Object properties map to multiple columns depending on the number of internal properties within the defined object
* within the defined object structure. Object properties are provided as a convince in schema * structure. Object properties are provided as a convince in schema design. They are effectively equivalent to
* design. They are effectively equivalent to defining the same properties explicitly via * defining the same properties explicitly via {@link PrimitivePropertyType} with nested property paths.
* {@link PrimitivePropertyType} with nested property paths.
*/ */
public class ObjectPropertyType extends ScopePropertyType { public class ObjectPropertyType extends ScopePropertyType {
/**
* A list of zero or more property definitions that define the columns within the schema. private List<Property> properties;
*/
private ArrayList<Property> properties;
/** /**
* Initializes a new instance of the {@link ObjectPropertyType} class. * Initializes a new instance of the {@link ObjectPropertyType} class.
*/ */
public ObjectPropertyType() { public ObjectPropertyType() {
this.properties = new ArrayList<Property>(); 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: public final List<Property> properties() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "properties")] public List<Property> Properties
public final ArrayList<Property> getProperties() {
return this.properties; return this.properties;
} }
public final void setProperties(ArrayList<Property> value) { public final ObjectPropertyType properties(List<Property> value) {
this.properties = value != null ? value : new ArrayList<Property>(); this.properties = value != null ? value : Collections.emptyList();
return this;
} }
} }

View File

@@ -11,15 +11,14 @@ public class PartitionKey {
* The logical path of the referenced property. * The logical path of the referenced property.
* Partition keys MUST refer to properties defined within the same {@link Schema}. * 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: private String path;
//ORIGINAL LINE: [JsonProperty(PropertyName = "path", Required = Required.Always)] public string Path {get;set;}
private String Path;
public final String getPath() { public final String path() {
return Path; return this.path;
} }
public final void setPath(String value) { public final PartitionKey path(String value) {
Path = value; this.path = value;
return this;
} }
} }

View File

@@ -8,35 +8,33 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
* partition. * partition.
*/ */
public class PrimarySortKey { public class PrimarySortKey {
private SortDirection direction = SortDirection.values()[0];
private String path;
/** /**
* The logical path of the referenced property. * The logical path of the referenced property.
* Primary keys MUST refer to properties defined within the same {@link Schema}. * 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: public final SortDirection direction() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "direction", Required = Required.DisallowNull)] public return this.direction;
// SortDirection Direction {get;set;} }
private SortDirection Direction = SortDirection.values()[0];
public final PrimarySortKey direction(SortDirection value) {
this.direction = value;
return this;
}
/** /**
* The logical path of the referenced property. * The logical path of the referenced property.
* Primary keys MUST refer to properties defined within the same {@link Schema}. * 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: public final String path() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "path", Required = Required.Always)] public string Path {get;set;} return this.path;
private String Path;
public final SortDirection getDirection() {
return Direction;
} }
public final void setDirection(SortDirection value) { public final PrimarySortKey path(String value) {
Direction = value; this.path = value;
} return this;
public final String getPath() {
return Path;
}
public final void setPath(String value) {
Path = value;
} }
} }

View File

@@ -10,36 +10,34 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
* column should be represented within the row. * column should be represented within the row.
*/ */
public class PrimitivePropertyType extends PropertyType { public class PrimitivePropertyType extends PropertyType {
private int length;
private StorageKind storage = StorageKind.values()[0];
/** /**
* The maximum allowable length in bytes. * The maximum allowable length in bytes.
* <p> * <p>
* This annotation is only valid for non-fixed length types. A value of 0 means the maximum * This annotation is only valid for non-fixed length types. A value of 0 means the maximum
* allowable length. * allowable length.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final int length() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "length")][JsonConverter(typeof(StrictIntegerConverter))] public return this.length;
// int Length {get;set;} }
private int Length;
public final PrimitivePropertyType length(int value) {
this.length = value;
return this;
}
/** /**
* Storage requirements of the property. * Storage requirements of the property.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final StorageKind storage() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "storage")] public StorageKind Storage {get;set;} return this.storage;
private StorageKind Storage = StorageKind.values()[0];
public final int getLength() {
return Length;
} }
public final void setLength(int value) { public final PrimitivePropertyType storage(StorageKind value) {
Length = value; this.storage = value;
} return this;
public final StorageKind getStorage() {
return Storage;
}
public final void setStorage(StorageKind value) {
Storage = value;
} }
} }

View File

@@ -3,65 +3,56 @@
package com.azure.data.cosmos.serialization.hybridrow.schemas; 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. * Describes a single property definition.
*/ */
public class Property { 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
* <p>
* Comments are for documentary purpose only and do not affect the property at runtime. * 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: public final String comment() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "comment", DefaultValueHandling = DefaultValueHandling return this.comment;
// .IgnoreAndPopulate)] public string Comment {get;set;} }
private String Comment;
public final Property comment(String value) {
this.comment = value;
return this;
}
/** /**
* The logical path of this property. * The logical path of this property.
* <p> * <p>
* For complex properties (e.g. objects) the logical path forms a prefix to relative paths of * For complex properties (e.g. objects) the logical path forms a prefix to relative paths of properties defined
* properties defined within nested structures. * within nested structures.
* <para /> * <p>
* See the logical path specification for full details on both relative and absolute paths. * 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: public final String path() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "path", Required = Required.Always)] public string Path {get;set;} return this.path;
private String Path;
/**
* The type of the property.
* <p>
* 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 void setPath(String value) { public final void setPath(String value) {
Path = value; this.path = value;
} }
public final PropertyType getPropertyType() { /**
return PropertyType; * The type of the property.
* <p>
* 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) { public final void setPropertyType(PropertyType value) {
PropertyType = value; this.propertyType = value;
} }
} }

View File

@@ -6,56 +6,51 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
/** /**
* The base class for property types both primitive and complex. * 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 { 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. * Api-specific type annotations for the property.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final String apiType() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "apitype")] public string ApiType {get;set;} return this.apiType;
private String ApiType; }
public final PropertyType apiType(String value) {
this.apiType = value;
return this;
}
/** /**
* True if the property can be null. * {@code true} if the property can be {@code null}
* Default: true. * <p>
* Default: {@code true}
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final boolean nullable() {
//ORIGINAL LINE: [DefaultValue(true)][JsonProperty(PropertyName = "nullable", DefaultValueHandling = return this.nullable;
// DefaultValueHandling.IgnoreAndPopulate)][JsonConverter(typeof(StrictBooleanConverter))] public bool Nullable }
// {get;set;}
private boolean 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: public final TypeKind type() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "type")] public TypeKind Type {get;set;} return this.type;
private TypeKind Type = TypeKind.values()[0];
protected PropertyType() {
this.setNullable(true);
} }
public final String getApiType() { public final PropertyType type(TypeKind value) {
return ApiType; this.type = value;
} return this;
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;
} }
} }

View File

@@ -3,32 +3,79 @@
package com.azure.data.cosmos.serialization.hybridrow.schemas; 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.SchemaId;
import com.azure.data.cosmos.serialization.hybridrow.layouts.Layout; import com.azure.data.cosmos.serialization.hybridrow.layouts.Layout;
import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCompiler; import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCompiler;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList; 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.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
* <p> * <p>
* The schema of a table or UDT describes the structure of row (i.e. which columns and the * The schema of a table or UDT describes the structure of row (i.e. which columns and the types of those columns). A
* types of those columns). A table schema represents the description of the contents of a collection * table schema represents the description of the contents of a collection level row directly. UDTs described nested
* level row directly. UDTs described nested structured objects that may appear either within a table * structured objects that may appear either within a table column or within another UDT (i.e. nested UDTs).
* column or within another UDT (i.e. nested UDTs).
*/ */
public class Schema { public class Schema {
private String comment;
private String name;
private SchemaOptions options;
private List<PartitionKey> partitionKeys;
private List<PrimarySortKey> primaryKeys;
private List<Property> properties;
private SchemaId schemaId = SchemaId.NONE;
private List<StaticKey> 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. * An (optional) comment describing the purpose of this schema.
* Comments are for documentary purpose only and do not affect the schema at runtime. * 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: public final String comment() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "comment", DefaultValueHandling = DefaultValueHandling return this.comment;
// .IgnoreAndPopulate)] public string Comment {get;set;} }
private String 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. * The name of the schema.
* <p> * <p>
@@ -37,140 +84,99 @@ public class Schema {
* Names must begin with an alpha-numeric character and can only contain alpha-numeric characters and * Names must begin with an alpha-numeric character and can only contain alpha-numeric characters and
* underscores. * underscores.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final String name() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "name", Required = Required.Always)] public string Name {get;set;} return this.name;
private String Name; }
public final Schema name(String value) {
this.name = value;
return this;
}
/** /**
* Schema-wide operations. * Schema-wide operations.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final SchemaOptions options() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "options")] public SchemaOptions Options {get;set;} return this.options;
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<PartitionKey> partitionKeys;
/**
* An (optional) list of zero or more logical paths that form the primary sort key.
*/
private ArrayList<PrimarySortKey> primaryKeys;
/**
* A list of zero or more property definitions that define the columns within the schema.
*/
private ArrayList<Property> 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<StaticKey> staticKeys;
/**
* Initializes a new instance of the {@link Schema} class.
*/
public Schema() {
this.setType(TypeKind.Schema);
this.properties = new ArrayList<Property>();
this.partitionKeys = new ArrayList<PartitionKey>();
this.primaryKeys = new ArrayList<PrimarySortKey>();
this.staticKeys = new ArrayList<StaticKey>();
} }
public final String getComment() { public final Schema options(SchemaOptions value) {
return Comment; this.options = value;
} return this;
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;
} }
/** /**
* An (optional) list of zero or more logical paths that form the partition key. * Parse a JSON fragment and return a schema.
* All paths referenced MUST map to a property within the schema. *
* <para /> * @param value The JSON string value to parse
* This field is never null. * @return A logical schema, if the value parses.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public static Optional<Schema> parse(String value) {
//ORIGINAL LINE: [JsonProperty(PropertyName = "partitionkeys")] public List<PartitionKey> PartitionKeys return Json.<Schema>parse(value); // TODO: DANOBLE: perform structural validation on the Schema after JSON
public final ArrayList<PartitionKey> getPartitionKeys() { // parsing
}
/**
* An (optional) list of zero or more logical paths that form the partition key
* <p>
* 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<PartitionKey> partitionKeys() {
return this.partitionKeys; return this.partitionKeys;
} }
public final void setPartitionKeys(ArrayList<PartitionKey> value) { public final Schema partitionKeys(@Nullable List<PartitionKey> value) {
this.partitionKeys = value != null ? value : new ArrayList<PartitionKey>(); this.partitionKeys = value != null ? value : Collections.emptyList();
return this;
} }
/** /**
* An (optional) list of zero or more logical paths that form the primary sort key. * 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. * <p>
* <para /> * All paths referenced MUST map to a property within the schema. This field is never null.
* 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: public final List<PrimarySortKey> primarySortKeys() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "primarykeys")] public List<PrimarySortKey> PrimarySortKeys
public final ArrayList<PrimarySortKey> getPrimarySortKeys() {
return this.primaryKeys; return this.primaryKeys;
} }
public final void setPrimarySortKeys(ArrayList<PrimarySortKey> value) { public final Schema primarySortKeys(ArrayList<PrimarySortKey> value) {
this.primaryKeys = value != null ? value : new ArrayList<PrimarySortKey>(); 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
* <p>
* This field is never null. * 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: public final List<Property> properties() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "properties")] public List<Property> Properties
public final ArrayList<Property> getProperties() {
return this.properties; return this.properties;
} }
public final void setProperties(ArrayList<Property> value) { public final Schema properties(List<Property> value) {
this.properties = value != null ? value : new ArrayList<Property>(); this.properties = value != null ? value : Collections.emptyList();
return this;
} }
public final SchemaId getSchemaId() { /**
return SchemaId; * The unique identifier for a schema
* <p>
* 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) { public final Schema schemaId(SchemaId value) {
SchemaId = value.clone(); this.schemaId = value;
return this;
} }
/** /**
@@ -178,57 +184,51 @@ public class Schema {
* All paths referenced MUST map to a property within the schema. * All paths referenced MUST map to a property within the schema.
* <para /> * <para />
* This field is never null. * This field is never null.
*
* @return
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final List<StaticKey> staticKeys() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "statickeys", DefaultValueHandling = DefaultValueHandling
// .IgnoreAndPopulate)] public List<StaticKey> StaticKeys
public final ArrayList<StaticKey> getStaticKeys() {
return this.staticKeys; return this.staticKeys;
} }
public final void setStaticKeys(ArrayList<StaticKey> value) { public final Schema staticKeys(List<StaticKey> value) {
this.staticKeys = value != null ? value : new ArrayList<StaticKey>(); this.staticKeys = value != null ? value : Collections.emptyList();
} return this;
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;
} }
/** /**
* Compiles this logical schema into a physical layout that can be used to read and write * Returns a JSON string representation of the current {@link Schema}
* rows.
* *
* @param ns The namespace within which this schema is defined. * @return a JSON string representation of the current {@link Schema}
* @return The layout for the schema.
*/ */
public final Layout Compile(Namespace ns) { @Override
checkArgument(ns != null); public String toString() {
checkArgument(ns.getSchemas().contains(this)); return Json.toString(this);
return LayoutCompiler.Compile(ns, this);
} }
/** /**
* Parse a JSON fragment and return a schema. * The type of this schema
* * <p>
* @param json The JSON text to parse. * This value MUST be {@link TypeKind#Schema}.
* @return A logical schema.
*/ */
public static Schema Parse(String json) { public final TypeKind type() {
return JsonConvert.<Schema>DeserializeObject(json); 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;
} }
} }

View File

@@ -5,9 +5,8 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
import java.io.Serializable; 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 final class SchemaException extends RuntimeException implements Serializable {
public SchemaException() { public SchemaException() {
} }
@@ -18,8 +17,4 @@ public final class SchemaException extends RuntimeException implements Serializa
public SchemaException(String message, RuntimeException innerException) { public SchemaException(String message, RuntimeException innerException) {
super(message, innerException); super(message, innerException);
} }
}
private SchemaException(SerializationInfo info, StreamingContext context) {
super(info, context);
}
}

View File

@@ -3,45 +3,40 @@
package com.azure.data.cosmos.serialization.hybridrow.schemas; package com.azure.data.cosmos.serialization.hybridrow.schemas;
// TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java: import java.util.HashMap;
///#pragma warning disable CA1028 // Enum Storage should be Int32
/** /**
* Versions of the HybridRow Schema Description Language. * 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 { public enum SchemaLanguageVersion {
/** /**
* Initial version of the HybridRow Schema Description Lanauge. * Initial version of the HybridRow Schema Description Lanauge.
*/ */
V1((byte)0); V1((byte)0);
public static final int SIZE = java.lang.Byte.SIZE; public static final int BYTES = Byte.BYTES;
private static java.util.HashMap<Byte, SchemaLanguageVersion> mappings;
private byte byteValue; private static HashMap<Byte, SchemaLanguageVersion> mappings;
private byte value;
SchemaLanguageVersion(byte value) { SchemaLanguageVersion(byte value) {
byteValue = value; this.value = value;
getMappings().put(value, this); mappings().put(value, this);
} }
public byte getValue() { public byte getValue() {
return byteValue; return this.value;
} }
public static SchemaLanguageVersion forValue(byte value) { public static SchemaLanguageVersion forValue(byte value) {
return getMappings().get(value); return mappings().get(value);
} }
private static java.util.HashMap<Byte, SchemaLanguageVersion> getMappings() { private static HashMap<Byte, SchemaLanguageVersion> mappings() {
if (mappings == null) { if (mappings == null) {
synchronized (SchemaLanguageVersion.class) { synchronized (SchemaLanguageVersion.class) {
if (mappings == null) { if (mappings == null) {
mappings = new java.util.HashMap<Byte, SchemaLanguageVersion>(); mappings = new HashMap<>();
} }
} }
} }

View File

@@ -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. * Describes the set of options that apply to the entire schema and the way it is validated.
*/ */
public class SchemaOptions { 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_ * If the is value true, then disables prefixing the system properties with a prefix __sys_
* for reserved properties owned by the store layer. * for reserved properties owned by the store layer.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final boolean disableSystemPrefix() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "disableSystemPrefix", DefaultValueHandling = DefaultValueHandling return this.disableSystemPrefix;
// .IgnoreAndPopulate)][JsonConverter(typeof(StrictBooleanConverter))] public bool DisableSystemPrefix {get;set;} }
private boolean DisableSystemPrefix;
public final void disableSystemPrefix(boolean value) {
this.disableSystemPrefix = value;
}
/** /**
* If true then structural schema validation is enabled. * If true then structural schema validation is enabled.
* <p> * <p>
@@ -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 * 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. * overwritten). No error will be given.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final boolean disallowUnschematized() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "disallowUnschematized")][JsonConverter(typeof return this.disallowUnschematized;
// (StrictBooleanConverter))] public bool DisallowUnschematized {get;set;} }
private boolean 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 * 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 * 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 * 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. * resolve each property based on the timestamp value of that property.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final boolean enablePropertyLevelTimestamp() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "enablePropertyLevelTimestamp")][JsonConverter(typeof return this.enablePropertyLevelTimestamp;
// (StrictBooleanConverter))] public bool EnablePropertyLevelTimestamp {get;set;}
private boolean EnablePropertyLevelTimestamp;
public final boolean getDisableSystemPrefix() {
return DisableSystemPrefix;
} }
public final void setDisableSystemPrefix(boolean value) { public final void enablePropertyLevelTimestamp(boolean value) {
DisableSystemPrefix = value; this.enablePropertyLevelTimestamp = 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;
} }
} }

View File

@@ -24,19 +24,19 @@ HashMap<SchemaId, Schema> ids
, TypeKind.Schema, s.getType())); , TypeKind.Schema, s.getType()));
HashMap<String, Property> pathDupCheck = new HashMap<String, Property>(s.getProperties().size()); HashMap<String, Property> pathDupCheck = new HashMap<String, Property>(s.getProperties().size());
for (Property p : s.getProperties()) { 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()) { 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()) { 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()) { 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()) { for (Property p : s.getProperties()) {
@@ -108,8 +108,8 @@ HashMap<SchemaId, Schema> ids
op: op:
HashMap<String, Property> pathDupCheck = new HashMap<String, Property>(op.Properties.Count); HashMap<String, Property> pathDupCheck = new HashMap<String, Property>(op.Properties.Count);
for (Property nested : op.Properties) { for (Property nested : op.Properties) {
ValidateAssert.DuplicateCheck(nested.getPath(), nested, pathDupCheck, "Property path", "Object"); ValidateAssert.DuplicateCheck(nested.path(), nested, pathDupCheck, "Property path", "Object");
SchemaValidator.Visit(nested.getPropertyType(), p, schemas, ids); SchemaValidator.Visit(nested.propertyType(), p, schemas, ids);
} }
break; break;
@@ -121,8 +121,8 @@ HashMap<SchemaId, Schema> ids
if (SchemaId.opNotEquals(up.SchemaId, if (SchemaId.opNotEquals(up.SchemaId,
SchemaId.INVALID)) { SchemaId.INVALID)) {
Schema s = ValidateAssert.Exists(up.SchemaId, ids, "Schema id", "Namespace"); 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 " + 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.getName())); "the name of schema with id '%2$s': %3$s", up.Name, up.SchemaId, s.name()));
} }
break; break;
@@ -133,27 +133,27 @@ HashMap<SchemaId, Schema> ids
}>schemas, }>schemas,
public static void Validate(Namespace ns) { public static void Validate(Namespace ns) {
HashMap<String, Integer> nameVersioningCheck = new HashMap<String, Integer>(ns.getSchemas().size()); HashMap<String, Integer> nameVersioningCheck = new HashMap<String, Integer>(ns.schemas().size());
HashMap< (String, SchemaId), HashMap< (String, SchemaId),
Schema > nameDupCheck = new HashMap<(String, SchemaId), Schema > (ns.getSchemas().size()); Schema > nameDupCheck = new HashMap<(String, SchemaId), Schema > (ns.schemas().size());
HashMap<SchemaId, Schema> idDupCheck = new HashMap<SchemaId, Schema>(ns.getSchemas().size()); HashMap<SchemaId, Schema> idDupCheck = new HashMap<SchemaId, Schema>(ns.schemas().size());
for (Schema s : ns.getSchemas()) { for (Schema s : ns.schemas()) {
ValidateAssert.IsValidSchemaId(s.getSchemaId().clone(), "Schema id"); ValidateAssert.IsValidSchemaId(s.schemaId().clone(), "Schema id");
ValidateAssert.IsValidIdentifier(s.getName(), "Schema name"); ValidateAssert.IsValidIdentifier(s.name(), "Schema name");
ValidateAssert.DuplicateCheck(s.getSchemaId().clone(), s, idDupCheck, "Schema id", "Namespace"); ValidateAssert.DuplicateCheck(s.schemaId().clone(), s, idDupCheck, "Schema id", "Namespace");
ValidateAssert.DuplicateCheck((s.getName(), s.getSchemaId().clone()), s, nameDupCheck, "Schema reference" ValidateAssert.DuplicateCheck((s.name(), s.schemaId().clone()), s, nameDupCheck, "Schema reference"
, "Namespace") , "Namespace")
// Count the versions of each schema by name. // Count the versions of each schema by name.
int count; int count;
count = nameVersioningCheck.get(s.getName()); count = nameVersioningCheck.get(s.name());
nameVersioningCheck.put(s.getName(), count + 1); nameVersioningCheck.put(s.name(), count + 1);
} }
// Enable id-less Schema references for all types with a unique version in the namespace. // Enable id-less Schema references for all types with a unique version in the namespace.
for (Schema s : ns.getSchemas()) { for (Schema s : ns.schemas()) {
if (nameVersioningCheck.get(s.getName()).equals(1)) { if (nameVersioningCheck.get(s.name()).equals(1)) {
ValidateAssert.DuplicateCheck((s.getName(), SchemaId.INVALID), s, nameDupCheck, "Schema reference", ValidateAssert.DuplicateCheck((s.name(), SchemaId.INVALID), s, nameDupCheck, "Schema reference",
"Namespace") "Namespace")
} }
} }

View File

@@ -4,20 +4,18 @@
package com.azure.data.cosmos.serialization.hybridrow.schemas; package com.azure.data.cosmos.serialization.hybridrow.schemas;
public abstract class ScopePropertyType extends PropertyType { public abstract class ScopePropertyType extends PropertyType {
private boolean immutable;
/** /**
* True if the property's child elements cannot be mutated in place. * True if the property's child elements cannot be mutated in place.
* Immutable properties can still be replaced in their entirety. * Immutable properties can still be replaced in their entirety.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final boolean immutable() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "immutable")][JsonConverter(typeof(StrictBooleanConverter))] public return this.immutable;
// bool Immutable {get;set;}
private boolean Immutable;
public final boolean getImmutable() {
return Immutable;
} }
public final void setImmutable(boolean value) { public final void immutable(boolean value) {
Immutable = value; this.immutable = value;
} }
} }

View File

@@ -4,11 +4,11 @@
package com.azure.data.cosmos.serialization.hybridrow.schemas; 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
* <p> * <p>
* Sets may be typed or untyped. Within typed sets, all items MUST be the same type. The * 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 * 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 * than untyped sets. When {@link #items} is unspecified, the set is untyped and its items
* may be heterogeneous. * may be heterogeneous.
* <p> * <p>
* Each item within a set must be unique. Uniqueness is defined by the HybridRow encoded sequence * 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. * (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: private PropertyType items;
//ORIGINAL LINE: [JsonProperty(PropertyName = "items")] public PropertyType Items {get;set;}
private PropertyType Items;
public final PropertyType getItems() { public final PropertyType items() {
return Items; return this.items;
} }
public final void setItems(PropertyType value) { public final SetPropertyType items(PropertyType value) {
Items = value; this.items = value;
return this;
} }
} }

View File

@@ -6,45 +6,39 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
/** /**
* Describes the sort order direction. * 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 { public enum SortDirection {
/** /**
* Sorts from the lowest to the highest value. * 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), Ascending(0),
/** /**
* Sorts from the highests to the lowest value. * 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); Descending(1);
public static final int SIZE = java.lang.Integer.SIZE; public static final int SIZE = java.lang.Integer.SIZE;
private static java.util.HashMap<Integer, SortDirection> mappings; private static java.util.HashMap<Integer, SortDirection> mappings;
private int intValue; private int value;
SortDirection(int value) { SortDirection(int value) {
intValue = value; this.value = value;
getMappings().put(value, this); mappings().put(value, this);
} }
public int getValue() { public int value() {
return intValue; return this.value;
} }
public static SortDirection forValue(int value) { public static SortDirection forValue(int value) {
return getMappings().get(value); return mappings().get(value);
} }
private static java.util.HashMap<Integer, SortDirection> getMappings() { private static java.util.HashMap<Integer, SortDirection> mappings() {
if (mappings == null) { if (mappings == null) {
synchronized (SortDirection.class) { synchronized (SortDirection.class) {
if (mappings == null) { if (mappings == null) {
mappings = new java.util.HashMap<Integer, SortDirection>(); mappings = new java.util.HashMap<>();
} }
} }
} }

View File

@@ -4,23 +4,23 @@
package com.azure.data.cosmos.serialization.hybridrow.schemas; 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 * Describes a property or property set whose values MUST be the same for all rows that share the same partition key
* key.
*/ */
public class StaticKey { public class StaticKey {
private String path;
/** /**
* The logical path of the referenced property. * The logical path of the referenced property
* <p>
* Static path MUST refer to properties defined within the same {@link Schema}. * 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: public final String path() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "path", Required = Required.Always)] public string Path {get;set;} return this.path;
private String Path;
public final String getPath() {
return Path;
} }
public final void setPath(String value) { public final StaticKey path(String value) {
Path = value; this.path = value;
return this;
} }
} }

View File

@@ -6,63 +6,56 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
/** /**
* Describes the storage placement for primitive properties. * 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 { public enum StorageKind {
/** /**
* The property defines a sparse column. * The property defines a sparse column
* <p> * <p>
* Columns marked {@link Sparse} consume no space in the row when not present. When * Columns marked as sparse consume no space in the row when not present. When present they appear in an unordered
* present they appear in an unordered linked list at the end of the row. Access time for * linked list at the end of the row. Access time for sparse columns is proportional to the number of sparse columns
* {@link Sparse} columns is proportional to the number of {@link Sparse} columns in the * in the row.
* row.
*/ */
Sparse(0), Sparse(0),
/** /**
* The property is a fixed-length, space-reserved column. * The property is a fixed-length, space-reserved column
* <p> * <p>
* The column will consume 1 null-bit, and its byte-width regardless of whether the value is * The column will consume 1 null-bit, and its byte-width regardless of whether the value is present in the row.
* present in the row.
*/ */
Fixed(1), Fixed(1),
/** /**
* The property is a variable-length column. * The property is a variable-length column.
* <p> * <p>
* The column will consume 1 null-bit regardless of whether the value is present. When the value is * The column will consume 1 null-bit regardless of whether the value is present. When the value is present it will
* present it will also consume a variable number of bytes to encode the length preceding the actual * also consume a variable number of bytes to encode the length preceding the actual value.
* value.
* <p> * <p>
* When a <em>long</em> value is marked {@link Variable} then a null-bit is reserved and * When a <em>long</em> value is marked variable then a null-bit is reserved and the value is optionally encoded as
* the value is optionally encoded as {@link Variable} if small enough to fit, otherwise the * variable if small enough to fit, otherwise the null-bit is set and the value is encoded as sparse.
* null-bit is set and the value is encoded as {@link Sparse}.
* </p>
*/ */
Variable(2); Variable(2);
public static final int SIZE = java.lang.Integer.SIZE; public static final int SIZE = java.lang.Integer.SIZE;
private static java.util.HashMap<Integer, StorageKind> mappings; private static java.util.HashMap<Integer, StorageKind> mappings;
private int intValue; private int value;
StorageKind(int value) { StorageKind(int value) {
intValue = value; this.value = value;
getMappings().put(value, this); mappings().put(value, this);
} }
public int getValue() { public int value() {
return intValue; return this.value;
} }
public static StorageKind forValue(int value) { public static StorageKind forValue(int value) {
return getMappings().get(value); return mappings().get(value);
} }
private static java.util.HashMap<Integer, StorageKind> getMappings() { private static java.util.HashMap<Integer, StorageKind> mappings() {
if (mappings == null) { if (mappings == null) {
synchronized (StorageKind.class) { synchronized (StorageKind.class) {
if (mappings == null) { if (mappings == null) {
mappings = new java.util.HashMap<Integer, StorageKind>(); mappings = new java.util.HashMap<>();
} }
} }
} }

View File

@@ -4,20 +4,22 @@
package com.azure.data.cosmos.serialization.hybridrow.schemas; package com.azure.data.cosmos.serialization.hybridrow.schemas;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
/** /**
* Tagged properties pair one or more typed values with an API-specific uint8 type code. * Tagged properties pair one or more typed values with an API-specific uint8 type code.
* <p> * <p>
* The uint8 type code is implicitly in position 0 within the resulting tagged and should not * The {@code UInt8} type code is implicitly in position 0 within the resulting tagged and should not be specified in
* be specified in {@link Items}. * {@link #items}.
*/ */
public class TaggedPropertyType extends ScopePropertyType { public class TaggedPropertyType extends ScopePropertyType {
public static final int MaxTaggedArguments = 2; public static final int MaxTaggedArguments = 2;
public static final int MinTaggedArguments = 1; public static final int MinTaggedArguments = 1;
/** /**
* Types of the elements of the tagged in element order. * Types of the elements of the tagged in element order.
*/ */
private ArrayList<PropertyType> items; private List<PropertyType> items;
/** /**
* Initializes a new instance of the {@link TaggedPropertyType} class. * 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. * Types of the elements of the tagged in element order.
* @return
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final List<PropertyType> items() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "items")] public List<PropertyType> Items
public final ArrayList<PropertyType> getItems() {
return this.items; return this.items;
} }
public final void setItems(ArrayList<PropertyType> value) { public final TaggedPropertyType items(List<PropertyType> value) {
this.items = value != null ? value : new ArrayList<PropertyType>(); this.items = value != null ? value : new ArrayList<>();
return this;
} }
} }

View File

@@ -4,6 +4,7 @@
package com.azure.data.cosmos.serialization.hybridrow.schemas; package com.azure.data.cosmos.serialization.hybridrow.schemas;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
/** /**
* Tuple properties represent a typed, finite, ordered set of two or more items. * 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. * Types of the elements of the tuple in element order.
*/ */
private ArrayList<PropertyType> items; private List<PropertyType> items;
/** /**
* Initializes a new instance of the {@link TuplePropertyType} class. * 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. * Types of the elements of the tuple in element order.
* @return
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
//ORIGINAL LINE: [JsonProperty(PropertyName = "items")] public List<PropertyType> Items //ORIGINAL LINE: [JsonProperty(PropertyName = "items")] public List<PropertyType> Items
public final ArrayList<PropertyType> getItems() { public final List<PropertyType> items() {
return this.items; return this.items;
} }
public final void setItems(ArrayList<PropertyType> value) { public final void items(List<PropertyType> value) {
this.items = value != null ? value : new ArrayList<PropertyType>(); this.items = value != null ? value : new ArrayList<PropertyType>();
} }
} }

View File

@@ -13,46 +13,46 @@ import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
* all outer schemas where the UDT is used. * all outer schemas where the UDT is used.
*/ */
public class UdtPropertyType extends ScopePropertyType { 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 identifier of the UDT schema defining the structure for the nested row.
* <p> * <p>
* The UDT schema MUST be defined within the same {@link Namespace} as the schema that * The UDT schema MUST be defined within the same {@link Namespace} as the schema that
* references it. * references it.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final String name() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "name", Required = Required.Always)] public string Name {get;set;} return this.name;
private String Name; }
public final void name(String value) {
this.name = value;
}
/** /**
* The unique identifier for a schema. * The unique identifier for a schema.
* <p> * <p>
* Optional uniquifier if multiple versions of {@link Name} appears within the Namespace. * Optional uniquifier if multiple versions of {@link #name} appears within the Namespace.
* <p> * <p>
* If multiple versions of a UDT are defined within the {@link Namespace} then the globally * 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. * unique identifier of the specific version referenced MUST be provided.
* </p> * </p>
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: public final SchemaId schemaId() {
//ORIGINAL LINE: [JsonProperty(PropertyName = "id", Required = Required.DisallowNull, DefaultValueHandling = return this.schemaId;
// 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 String getName() { public final UdtPropertyType schemaId(SchemaId value) {
return Name; this.schemaId = value;
} return this;
public final void setName(String value) {
Name = value;
}
public final SchemaId getSchemaId() {
return SchemaId;
}
public final void setSchemaId(SchemaId value) {
SchemaId = value.clone();
} }
} }