mirror of
https://github.com/microsoft/HybridRow.git
synced 2026-01-21 02:13:18 +00:00
Progressed on port from dotnet to java
This commit is contained in:
@@ -5,18 +5,31 @@ package com.azure.data.cosmos.core;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectReader;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.google.common.base.Strings.lenientFormat;
|
||||
|
||||
public final class Json {
|
||||
|
||||
private static final ObjectMapper mapper = new ObjectMapper();
|
||||
private static final ObjectReader reader = mapper.reader();
|
||||
private static final ObjectWriter writer = mapper.writer();
|
||||
|
||||
private Json() {
|
||||
}
|
||||
|
||||
public static <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) {
|
||||
try {
|
||||
return writer.writeValueAsString(object);
|
||||
|
||||
@@ -27,6 +27,7 @@ public final class Float128 {
|
||||
* The size (in bytes) of a {@link Float128}.
|
||||
*/
|
||||
public static final int BYTES = 2 * Long.BYTES;
|
||||
public static final Float128 ZERO = new Float128(0L, 0L);
|
||||
|
||||
private final long high;
|
||||
private final long low;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package com.azure.data.cosmos.serialization.hybridrow;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.core.Utf8String;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.codecs.DateTimeCodec;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.codecs.DecimalCodec;
|
||||
@@ -70,6 +69,7 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -83,6 +83,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.base.Strings.lenientFormat;
|
||||
|
||||
// import com.azure.data.cosmos.serialization.hybridrow.RowBuffer.UniqueIndexItem;
|
||||
|
||||
//import static com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutTypes.MongoDbObjectId;
|
||||
|
||||
/**
|
||||
@@ -152,256 +154,6 @@ public final class RowBuffer {
|
||||
checkState(HybridRowHeader.BYTES + layout.size() <= this.length());
|
||||
}
|
||||
|
||||
public void TypedCollectionMoveField(RowCursor dstEdit, RowCursor srcEdit, RowOptions options) {
|
||||
|
||||
int encodedSize = this.sparseComputeSize(srcEdit);
|
||||
int numBytes = encodedSize - (srcEdit.valueOffset() - srcEdit.metaOffset());
|
||||
|
||||
// Insert the field metadata into its new location.
|
||||
int metaBytes;
|
||||
Out<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
|
||||
*
|
||||
@@ -442,25 +194,6 @@ public final class RowBuffer {
|
||||
return offset;
|
||||
}
|
||||
|
||||
// TODO: DANOBLE: ressurrect this method
|
||||
// public void WriteSparseMongoDbObjectId(@Nonnull final RowCursor edit, MongoDbObjectId value,
|
||||
// UpdateOptions options) {
|
||||
// int numBytes = MongoDbObjectId.Size;
|
||||
// int metaBytes;
|
||||
// final Out<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
|
||||
*
|
||||
@@ -538,16 +271,30 @@ public final class RowBuffer {
|
||||
return this.readHeader();
|
||||
}
|
||||
|
||||
// TODO: DANOBLE: ressurrect this method
|
||||
// public void WriteSparseMongoDbObjectId(@Nonnull final RowCursor edit, MongoDbObjectId value,
|
||||
// UpdateOptions options) {
|
||||
// int numBytes = MongoDbObjectId.Size;
|
||||
// int metaBytes;
|
||||
// final Out<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) {
|
||||
final long value = this.buffer.getUnsignedIntLE(offset);
|
||||
this.buffer.setIntLE(offset, (int) (value + increment));
|
||||
}
|
||||
|
||||
// TODO: DANOBLE: resurrect this method
|
||||
// public MongoDbObjectId ReadMongoDbObjectId(int offset) {
|
||||
// return MemoryMarshal.<MongoDbObjectId>Read(this.buffer.Slice(offset));
|
||||
// }
|
||||
|
||||
/**
|
||||
* Initializes a row to the minimal size for the given layout.
|
||||
*
|
||||
@@ -640,6 +387,11 @@ public final class RowBuffer {
|
||||
return item.value();
|
||||
}
|
||||
|
||||
// TODO: DANOBLE: resurrect this method
|
||||
// public MongoDbObjectId ReadMongoDbObjectId(int offset) {
|
||||
// return MemoryMarshal.<MongoDbObjectId>Read(this.buffer.Slice(offset));
|
||||
// }
|
||||
|
||||
public boolean readBit(final int offset, @Nonnull final LayoutBit bit) {
|
||||
|
||||
checkNotNull(bit, "expected non-null bit");
|
||||
@@ -652,13 +404,6 @@ public final class RowBuffer {
|
||||
return item.value();
|
||||
}
|
||||
|
||||
// TODO: DANOBLE: resurrect this method
|
||||
// public MongoDbObjectId ReadSparseMongoDbObjectId(Reference<RowCursor> edit) {
|
||||
// this.readSparsePrimitiveTypeCode(edit, MongoDbObjectId);
|
||||
// edit.endOffset = edit.valueOffset() + MongoDbObjectId.Size;
|
||||
// return this.ReadMongoDbObjectId(edit.valueOffset()).clone();
|
||||
// }
|
||||
|
||||
public OffsetDateTime readDateTime(int offset) {
|
||||
Item<OffsetDateTime> item = this.read(() -> DateTimeCodec.decode(this.buffer), offset);
|
||||
return item.value();
|
||||
@@ -684,6 +429,13 @@ public final class RowBuffer {
|
||||
return item.value();
|
||||
}
|
||||
|
||||
// TODO: DANOBLE: resurrect this method
|
||||
// public MongoDbObjectId ReadSparseMongoDbObjectId(Reference<RowCursor> edit) {
|
||||
// this.readSparsePrimitiveTypeCode(edit, MongoDbObjectId);
|
||||
// edit.endOffset = edit.valueOffset() + MongoDbObjectId.Size;
|
||||
// return this.ReadMongoDbObjectId(edit.valueOffset()).clone();
|
||||
// }
|
||||
|
||||
public float readFloat32(int offset) {
|
||||
Item<Float> item = this.read(this.buffer::readFloatLE, offset);
|
||||
return item.value();
|
||||
@@ -997,14 +749,6 @@ public final class RowBuffer {
|
||||
return item.value();
|
||||
}
|
||||
|
||||
// TODO: DANOBLE: Support MongoDbObjectId values
|
||||
// public void WriteMongoDbObjectId(int offset, MongoDbObjectId value) {
|
||||
// Reference<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) {
|
||||
Item<Long> item = this.read(this::read7BitEncodedInt, offset);
|
||||
return item.value();
|
||||
@@ -1035,6 +779,14 @@ public final class RowBuffer {
|
||||
return this.resolver;
|
||||
}
|
||||
|
||||
// TODO: DANOBLE: Support MongoDbObjectId values
|
||||
// public void WriteMongoDbObjectId(int offset, MongoDbObjectId value) {
|
||||
// Reference<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
|
||||
*
|
||||
@@ -1168,7 +920,7 @@ public final class RowBuffer {
|
||||
|
||||
if (scopeType instanceof LayoutTypedArray || scopeType instanceof LayoutTypedSet || scopeType instanceof LayoutTypedMap) {
|
||||
|
||||
final int valueOffset = edit.valueOffset() + (Integer.SIZE / Byte.SIZE); // Point after the Size
|
||||
final int valueOffset = edit.valueOffset() + Integer.BYTES; // Point after the Size
|
||||
|
||||
return new RowCursor()
|
||||
.scopeType(scopeType)
|
||||
@@ -1257,6 +1009,150 @@ public final class RowBuffer {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void typedCollectionMoveField(
|
||||
@Nonnull final RowCursor dstEdit,
|
||||
@Nonnull final RowCursor srcEdit,
|
||||
@Nonnull final RowOptions options) {
|
||||
|
||||
final int length = this.sparseComputeSize(srcEdit) - (srcEdit.valueOffset() - srcEdit.metaOffset());
|
||||
|
||||
// Insert the field metadata into its new location
|
||||
|
||||
Out<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) {
|
||||
checkNotNull(bit, "expected non-null bit");
|
||||
checkArgument(!bit.isInvalid());
|
||||
@@ -1299,7 +1195,6 @@ public final class RowBuffer {
|
||||
}
|
||||
|
||||
public void writeFixedBinary(final int offset, @Nonnull final ByteBuf value, final int length) {
|
||||
|
||||
checkNotNull(value, "expected non-null value");
|
||||
checkArgument(offset >= 0, "expected offset >= 0, not %s", offset);
|
||||
checkArgument(length >= 0, "expected length >= 0, not %s", length);
|
||||
@@ -1313,6 +1208,13 @@ public final class RowBuffer {
|
||||
}, offset, value);
|
||||
}
|
||||
|
||||
public void writeFixedBinary(final int offset, @Nonnull final ByteBuf value, final int index, final int length) {
|
||||
checkArgument(index >= 0, "expected index >= 0, not %s", index);
|
||||
value.markReaderIndex().readerIndex(index);
|
||||
this.writeFixedBinary(offset, value, length);
|
||||
value.resetReaderIndex();
|
||||
}
|
||||
|
||||
public void writeFixedBinary(final int offset, @Nonnull final byte[] value, final int index, final int length) {
|
||||
|
||||
checkNotNull(value, "expected non-null value");
|
||||
@@ -1888,6 +1790,43 @@ public final class RowBuffer {
|
||||
this.writeUInt8(offset, code.value());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public RowCursor writeSparseUDT(
|
||||
@Nonnull final RowCursor edit,
|
||||
@Nonnull final LayoutScope scope,
|
||||
@Nonnull final Layout udt,
|
||||
@Nonnull final UpdateOptions options) {
|
||||
|
||||
TypeArgumentList typeArgs = new TypeArgumentList(udt.schemaId());
|
||||
int length = udt.size() + LayoutCode.BYTES;
|
||||
|
||||
final Out<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(
|
||||
@Nonnull final RowCursor edit, final short value, @Nonnull final UpdateOptions options) {
|
||||
|
||||
@@ -2074,6 +2013,71 @@ public final class RowBuffer {
|
||||
this.buffer.getBytes(0, stream, this.length());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public RowCursor writeTypedArray(
|
||||
@Nonnull final RowCursor edit,
|
||||
@Nonnull final LayoutScope scope,
|
||||
@Nonnull final TypeArgumentList typeArgs,
|
||||
@Nonnull final UpdateOptions options) {
|
||||
|
||||
final int length = Integer.BYTES;
|
||||
final Out<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
|
||||
public RowCursor writeTypedSet(
|
||||
@Nonnull final RowCursor edit,
|
||||
@@ -2423,7 +2427,7 @@ public final class RowBuffer {
|
||||
}
|
||||
if (code instanceof LayoutTypedArray || code instanceof LayoutTypedSet || code instanceof LayoutTypedMap) {
|
||||
// Variable length typed collection scopes preceded by their scope size take sizeof(uint) for a size of 0.
|
||||
return (Integer.SIZE / Byte.SIZE);
|
||||
return Integer.BYTES;
|
||||
}
|
||||
if (code instanceof LayoutTuple) {
|
||||
// Fixed arity sparse collections take 1 byte for end-of-scope plus a null for each element.
|
||||
@@ -2874,7 +2878,7 @@ public final class RowBuffer {
|
||||
checkState(edit.pathOffset() == 0);
|
||||
checkState(edit.pathToken() == 0);
|
||||
} else {
|
||||
int offset = edit.metaOffset() + LayoutCode.SIZE;
|
||||
int offset = edit.metaOffset() + LayoutCode.BYTES;
|
||||
Out<Integer> pathLenInBytes = new Out<>();
|
||||
Out<Integer> pathOffset = new Out<>();
|
||||
int token = this.readSparsePathLen(edit.layout(), offset, pathLenInBytes, pathOffset);
|
||||
@@ -3147,7 +3151,7 @@ public final class RowBuffer {
|
||||
}
|
||||
|
||||
if (code == LayoutTypes.FLOAT_128) {
|
||||
this.writeFloat128(offset, null);
|
||||
this.writeFloat128(offset, Float128.ZERO);
|
||||
return LayoutTypes.FLOAT_128.size();
|
||||
}
|
||||
|
||||
@@ -3162,12 +3166,12 @@ public final class RowBuffer {
|
||||
}
|
||||
|
||||
if (code == LayoutTypes.UNIX_DATE_TIME) {
|
||||
this.writeUnixDateTime(offset, null);
|
||||
this.writeUnixDateTime(offset, UnixDateTime.EPOCH);
|
||||
return LayoutTypes.UNIX_DATE_TIME.size();
|
||||
}
|
||||
|
||||
if (code == LayoutTypes.GUID) {
|
||||
this.writeGuid(offset, null);
|
||||
this.writeGuid(offset, GuidCodec.EMPTY);
|
||||
return LayoutTypes.GUID.size();
|
||||
}
|
||||
|
||||
@@ -3179,8 +3183,8 @@ public final class RowBuffer {
|
||||
}
|
||||
|
||||
if (code == LayoutTypes.UTF_8 || code == LayoutTypes.BINARY || code == LayoutTypes.VAR_INT || code == LayoutTypes.VAR_UINT) {
|
||||
// Variable length types preceded by their varuint size take 1 byte for a size of 0.
|
||||
return this.write7BitEncodedUInt(offset, 0);
|
||||
// Variable length types preceded by their varuint size take 1 byte for a size of 0
|
||||
return this.write(this::write7BitEncodedUInt, offset, 0L).length();
|
||||
}
|
||||
|
||||
if (code == LayoutTypes.OBJECT || code == LayoutTypes.ARRAY) {
|
||||
@@ -3192,7 +3196,7 @@ public final class RowBuffer {
|
||||
if (code == LayoutTypes.TYPED_ARRAY || code == LayoutTypes.TypedSet || code == LayoutTypes.TypedMap) {
|
||||
// Variable length typed collection scopes preceded by their scope size take sizeof(uint) for a size of 0.
|
||||
this.writeUInt32(offset, 0);
|
||||
return (Integer.SIZE / Byte.SIZE);
|
||||
return Integer.BYTES;
|
||||
}
|
||||
|
||||
if (code == LayoutTypes.TUPLE) {
|
||||
@@ -3223,14 +3227,15 @@ public final class RowBuffer {
|
||||
|
||||
if (code == LayoutTypes.UDT) {
|
||||
|
||||
// Clear all presence bits.
|
||||
// Clear all presence bits
|
||||
Layout udt = this.resolver.resolve(typeArgs.schemaId());
|
||||
this.buffer.Slice(offset, udt.size()).Fill(0);
|
||||
this.write(this.buffer::writeZero, offset, udt.size());
|
||||
|
||||
// Write scope terminator.
|
||||
// Write scope terminator
|
||||
this.writeSparseTypeCode(offset + udt.size(), LayoutCode.END_SCOPE);
|
||||
return udt.size() + LayoutCode.BYTES;
|
||||
}
|
||||
|
||||
throw new IllegalStateException(lenientFormat("Not Implemented: %s", code));
|
||||
}
|
||||
|
||||
@@ -3291,6 +3296,7 @@ public final class RowBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void writeUInt16(Short value) {
|
||||
this.buffer.writeShortLE(value);
|
||||
}
|
||||
@@ -3361,20 +3367,20 @@ public final class RowBuffer {
|
||||
*/
|
||||
static final class UniqueIndexItem {
|
||||
|
||||
private LayoutCode Code = LayoutCode.values()[0];
|
||||
private int MetaOffset;
|
||||
private int Size;
|
||||
private int ValueOffset;
|
||||
private LayoutCode code = LayoutCode.values()[0];
|
||||
private int metaOffset;
|
||||
private int size;
|
||||
private int valueOffset;
|
||||
|
||||
/**
|
||||
* The layout code of the value.
|
||||
*/
|
||||
public LayoutCode code() {
|
||||
return this.Code;
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public UniqueIndexItem code(LayoutCode code) {
|
||||
this.Code = code;
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -3382,11 +3388,11 @@ public final class RowBuffer {
|
||||
* If existing, the offset to the metadata of the existing field, otherwise the location to insert a new field
|
||||
*/
|
||||
public int metaOffset() {
|
||||
return this.MetaOffset;
|
||||
return this.metaOffset;
|
||||
}
|
||||
|
||||
public UniqueIndexItem metaOffset(int metaOffset) {
|
||||
this.MetaOffset = metaOffset;
|
||||
this.metaOffset = metaOffset;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -3394,11 +3400,11 @@ public final class RowBuffer {
|
||||
* Size of the target element
|
||||
*/
|
||||
public int size() {
|
||||
return this.Size;
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public UniqueIndexItem size(int size) {
|
||||
this.Size = size;
|
||||
this.size = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -3406,11 +3412,11 @@ public final class RowBuffer {
|
||||
* If existing, the offset to the value of the existing field, otherwise undefined
|
||||
*/
|
||||
public int valueOffset() {
|
||||
return this.ValueOffset;
|
||||
return this.valueOffset;
|
||||
}
|
||||
|
||||
public UniqueIndexItem valueOffset(int valueOffset) {
|
||||
this.ValueOffset = valueOffset;
|
||||
this.valueOffset = valueOffset;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
public final class GuidCodec {
|
||||
|
||||
public static final int BYTES = 2 * Long.BYTES;
|
||||
public static final UUID EMPTY = new UUID(0L, 0L);
|
||||
|
||||
private GuidCodec() {
|
||||
}
|
||||
|
||||
@@ -410,7 +410,7 @@ public final class RowWriter {
|
||||
new Reference<RowCursor>(this.cursor);
|
||||
Out<RowCursor> tempOut_nestedScope3 =
|
||||
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);
|
||||
nestedScope = tempOut_nestedScope3.get();
|
||||
this.cursor = tempRef_cursor3.argValue;
|
||||
@@ -495,7 +495,7 @@ public final class RowWriter {
|
||||
new Reference<RowCursor>(this.cursor);
|
||||
Out<RowCursor> tempOut_nestedScope9 =
|
||||
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();
|
||||
this.cursor = tempReference_cursor9.get();
|
||||
break;
|
||||
@@ -522,8 +522,8 @@ public final class RowWriter {
|
||||
new Reference<RowCursor>(this.cursor);
|
||||
Out<RowCursor> tempOut_nestedScope11 =
|
||||
new Out<RowCursor>();
|
||||
this.row.WriteTypedMap(tempRef_cursor11, scopeType, typeArg.typeArgs().clone(),
|
||||
UpdateOptions.Upsert, tempOut_nestedScope11);
|
||||
this.row.writeTypedMap(tempRef_cursor11, scopeType, typeArg.typeArgs().clone(),
|
||||
UpdateOptions.Upsert);
|
||||
nestedScope = tempOut_nestedScope11.get();
|
||||
this.cursor = tempRef_cursor11.argValue;
|
||||
|
||||
@@ -556,7 +556,7 @@ public final class RowWriter {
|
||||
if (type instanceof LayoutUniqueScope) {
|
||||
Reference<RowCursor> tempReference_nestedScope2 =
|
||||
new Reference<RowCursor>(nestedScope);
|
||||
result = this.row.TypedCollectionUniqueIndexRebuild(tempReference_nestedScope2);
|
||||
result = this.row.typedCollectionUniqueIndexRebuild(tempReference_nestedScope2);
|
||||
nestedScope = tempReference_nestedScope2.get();
|
||||
if (result != Result.SUCCESS) {
|
||||
// TODO: If the index rebuild fails then the row is corrupted. Should we automatically clean up here?
|
||||
|
||||
@@ -13,12 +13,9 @@ import com.google.common.collect.ImmutableList;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@@ -30,7 +27,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
* order and type of columns defines the physical ordering of bytes used to encode the row and impacts the cost of
|
||||
* updating the row.
|
||||
* <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}.
|
||||
*
|
||||
* {@link Layout} is immutable.
|
||||
|
||||
@@ -38,12 +38,12 @@ public final class LayoutCompiler {
|
||||
public static Layout Compile(Namespace ns, Schema schema) {
|
||||
checkArgument(ns != null);
|
||||
checkArgument(schema != null);
|
||||
checkArgument(schema.getType() == TypeKind.Schema);
|
||||
checkArgument(!tangible.StringHelper.isNullOrWhiteSpace(schema.getName()));
|
||||
checkArgument(ns.getSchemas().contains(schema));
|
||||
checkArgument(schema.type() == TypeKind.Schema);
|
||||
checkArgument(!tangible.StringHelper.isNullOrWhiteSpace(schema.name()));
|
||||
checkArgument(ns.schemas().contains(schema));
|
||||
|
||||
LayoutBuilder builder = new LayoutBuilder(schema.getName(), schema.getSchemaId().clone());
|
||||
LayoutCompiler.AddProperties(builder, ns, LayoutCode.SCHEMA, schema.getProperties());
|
||||
LayoutBuilder builder = new LayoutBuilder(schema.name(), schema.schemaId().clone());
|
||||
LayoutCompiler.AddProperties(builder, ns, LayoutCode.SCHEMA, schema.properties());
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
@@ -54,17 +54,17 @@ public final class LayoutCompiler {
|
||||
TypeArgumentList typeArgs = new TypeArgumentList();
|
||||
Out<TypeArgumentList> tempOut_typeArgs =
|
||||
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();
|
||||
switch (LayoutCodeTraits.ClearImmutableBit(type.LayoutCode)) {
|
||||
case OBJECT_SCOPE: {
|
||||
if (!p.getPropertyType().getNullable()) {
|
||||
if (!p.propertyType().nullable()) {
|
||||
throw new LayoutCompilationException("Non-nullable sparse column are not supported.");
|
||||
}
|
||||
|
||||
ObjectPropertyType op = (ObjectPropertyType)p.getPropertyType();
|
||||
builder.addObjectScope(p.getPath(), type);
|
||||
LayoutCompiler.AddProperties(builder, ns, type.LayoutCode, op.getProperties());
|
||||
ObjectPropertyType op = (ObjectPropertyType)p.propertyType();
|
||||
builder.addObjectScope(p.path(), type);
|
||||
LayoutCompiler.AddProperties(builder, ns, type.LayoutCode, op.properties());
|
||||
builder.EndObjectScope();
|
||||
break;
|
||||
}
|
||||
@@ -80,11 +80,11 @@ public final class LayoutCompiler {
|
||||
case TAGGED_SCOPE:
|
||||
case TAGGED2_SCOPE:
|
||||
case SCHEMA: {
|
||||
if (!p.getPropertyType().getNullable()) {
|
||||
if (!p.propertyType().nullable()) {
|
||||
throw new LayoutCompilationException("Non-nullable sparse column are not supported.");
|
||||
}
|
||||
|
||||
builder.addTypedScope(p.getPath(), type, typeArgs.clone());
|
||||
builder.addTypedScope(p.path(), type, typeArgs.clone());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -93,23 +93,23 @@ public final class LayoutCompiler {
|
||||
}
|
||||
|
||||
default: {
|
||||
PropertyType tempVar = p.getPropertyType();
|
||||
PropertyType tempVar = p.propertyType();
|
||||
PrimitivePropertyType pp = tempVar instanceof PrimitivePropertyType ?
|
||||
(PrimitivePropertyType)tempVar : null;
|
||||
if (pp != null) {
|
||||
switch (pp.getStorage()) {
|
||||
switch (pp.storage()) {
|
||||
case Fixed:
|
||||
if (LayoutCodeTraits.ClearImmutableBit(scope) != LayoutCode.SCHEMA) {
|
||||
throw new LayoutCompilationException("Cannot have fixed storage within a sparse " +
|
||||
"scope.");
|
||||
}
|
||||
|
||||
if (type.getIsNull() && !pp.getNullable()) {
|
||||
if (type.getIsNull() && !pp.nullable()) {
|
||||
throw new LayoutCompilationException("Non-nullable null columns are not supported" +
|
||||
".");
|
||||
}
|
||||
|
||||
builder.addFixedColumn(p.getPath(), type, pp.getNullable(), pp.getLength());
|
||||
builder.addFixedColumn(p.path(), type, pp.nullable(), pp.length());
|
||||
break;
|
||||
case Variable:
|
||||
if (LayoutCodeTraits.ClearImmutableBit(scope) != LayoutCode.SCHEMA) {
|
||||
@@ -117,24 +117,24 @@ public final class LayoutCompiler {
|
||||
"sparse scope.");
|
||||
}
|
||||
|
||||
if (!pp.getNullable()) {
|
||||
if (!pp.nullable()) {
|
||||
throw new LayoutCompilationException("Non-nullable variable columns are not " +
|
||||
"supported.");
|
||||
}
|
||||
|
||||
builder.addVariableColumn(p.getPath(), type, pp.getLength());
|
||||
builder.addVariableColumn(p.path(), type, pp.length());
|
||||
break;
|
||||
case Sparse:
|
||||
if (!pp.getNullable()) {
|
||||
if (!pp.nullable()) {
|
||||
throw new LayoutCompilationException("Non-nullable sparse columns are not " +
|
||||
"supported.");
|
||||
}
|
||||
|
||||
builder.addSparseColumn(p.getPath(), type);
|
||||
builder.addSparseColumn(p.path(), type);
|
||||
break;
|
||||
default:
|
||||
throw new LayoutCompilationException(String.format("Unknown storage specification: " +
|
||||
"%1$s", pp.getStorage()));
|
||||
"%1$s", pp.storage()));
|
||||
}
|
||||
} else {
|
||||
throw new LayoutCompilationException(String.format("Unknown property type: %1$s",
|
||||
@@ -151,12 +151,12 @@ public final class LayoutCompiler {
|
||||
Out<TypeArgumentList> typeArgs) {
|
||||
typeArgs.setAndGet(TypeArgumentList.EMPTY);
|
||||
boolean tempVar =
|
||||
(logicalType instanceof ScopePropertyType ? (ScopePropertyType)logicalType : null).getImmutable();
|
||||
(logicalType instanceof ScopePropertyType ? (ScopePropertyType)logicalType : null).immutable();
|
||||
boolean immutable =
|
||||
(logicalType instanceof ScopePropertyType ? (ScopePropertyType)logicalType : null) == null ? null :
|
||||
tempVar != null && tempVar;
|
||||
|
||||
switch (logicalType.getType()) {
|
||||
switch (logicalType.type()) {
|
||||
case Null:
|
||||
return LayoutType.Null;
|
||||
case Boolean:
|
||||
@@ -206,12 +206,12 @@ public final class LayoutCompiler {
|
||||
return immutable ? LayoutType.ImmutableObject : LayoutType.Object;
|
||||
case Array:
|
||||
ArrayPropertyType ap = (ArrayPropertyType)logicalType;
|
||||
if ((ap.getItems() != null) && (ap.getItems().getType() != TypeKind.Any)) {
|
||||
if ((ap.items() != null) && (ap.items().type() != TypeKind.Any)) {
|
||||
TypeArgumentList itemTypeArgs = new TypeArgumentList();
|
||||
Out<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();
|
||||
if (ap.getItems().getNullable()) {
|
||||
if (ap.items().nullable()) {
|
||||
itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
|
||||
itemTypeArgs.clone()) });
|
||||
itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
|
||||
@@ -225,13 +225,13 @@ public final class LayoutCompiler {
|
||||
return immutable ? LayoutType.ImmutableArray : LayoutType.Array;
|
||||
case Set:
|
||||
SetPropertyType sp = (SetPropertyType)logicalType;
|
||||
if ((sp.getItems() != null) && (sp.getItems().getType() != TypeKind.Any)) {
|
||||
if ((sp.items() != null) && (sp.items().type() != TypeKind.Any)) {
|
||||
TypeArgumentList itemTypeArgs = new TypeArgumentList();
|
||||
Out<TypeArgumentList> tempOut_itemTypeArgs2 = new Out<TypeArgumentList>();
|
||||
LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, sp.getItems(),
|
||||
LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, sp.items(),
|
||||
tempOut_itemTypeArgs2);
|
||||
itemTypeArgs = tempOut_itemTypeArgs2.get();
|
||||
if (sp.getItems().getNullable()) {
|
||||
if (sp.items().nullable()) {
|
||||
itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
|
||||
itemTypeArgs.clone()) });
|
||||
itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
|
||||
@@ -244,16 +244,16 @@ public final class LayoutCompiler {
|
||||
|
||||
// TODO(283638): implement sparse set.
|
||||
throw new LayoutCompilationException(String.format("Unknown property type: %1$s",
|
||||
logicalType.getType()));
|
||||
logicalType.type()));
|
||||
|
||||
case Map:
|
||||
MapPropertyType mp = (MapPropertyType)logicalType;
|
||||
if ((mp.getKeys() != null) && (mp.getKeys().getType() != TypeKind.Any) && (mp.getValues() != null) && (mp.getValues().getType() != TypeKind.Any)) {
|
||||
if ((mp.keys() != null) && (mp.keys().type() != TypeKind.Any) && (mp.values() != null) && (mp.values().type() != TypeKind.Any)) {
|
||||
TypeArgumentList keyTypeArgs = new TypeArgumentList();
|
||||
Out<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();
|
||||
if (mp.getKeys().getNullable()) {
|
||||
if (mp.keys().nullable()) {
|
||||
keyTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(keyType,
|
||||
keyTypeArgs.clone()) });
|
||||
keyType = keyType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
|
||||
@@ -261,10 +261,10 @@ public final class LayoutCompiler {
|
||||
|
||||
TypeArgumentList valueTypeArgs = new TypeArgumentList();
|
||||
Out<TypeArgumentList> tempOut_valueTypeArgs = new Out<TypeArgumentList>();
|
||||
LayoutType valueType = LayoutCompiler.LogicalToPhysicalType(ns, mp.getValues(),
|
||||
LayoutType valueType = LayoutCompiler.LogicalToPhysicalType(ns, mp.values(),
|
||||
tempOut_valueTypeArgs);
|
||||
valueTypeArgs = tempOut_valueTypeArgs.get();
|
||||
if (mp.getValues().getNullable()) {
|
||||
if (mp.values().nullable()) {
|
||||
valueTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(valueType,
|
||||
valueTypeArgs.clone()) });
|
||||
valueType = valueType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
|
||||
@@ -280,18 +280,18 @@ public final class LayoutCompiler {
|
||||
|
||||
// TODO(283638): implement sparse map.
|
||||
throw new LayoutCompilationException(String.format("Unknown property type: %1$s",
|
||||
logicalType.getType()));
|
||||
logicalType.type()));
|
||||
|
||||
case Tuple:
|
||||
TuplePropertyType tp = (TuplePropertyType)logicalType;
|
||||
TypeArgument[] args = new TypeArgument[tp.getItems().size()];
|
||||
for (int i = 0; i < tp.getItems().size(); i++) {
|
||||
TypeArgument[] args = new TypeArgument[tp.items().size()];
|
||||
for (int i = 0; i < tp.items().size(); i++) {
|
||||
TypeArgumentList itemTypeArgs = new TypeArgumentList();
|
||||
Out<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);
|
||||
itemTypeArgs = tempOut_itemTypeArgs3.get();
|
||||
if (tp.getItems().get(i).getNullable()) {
|
||||
if (tp.items().get(i).nullable()) {
|
||||
itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
|
||||
itemTypeArgs.clone()) });
|
||||
itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
|
||||
@@ -305,21 +305,21 @@ public final class LayoutCompiler {
|
||||
|
||||
case Tagged:
|
||||
TaggedPropertyType tg = (TaggedPropertyType)logicalType;
|
||||
if ((tg.getItems().size() < TaggedPropertyType.MinTaggedArguments) || (tg.getItems().size() > TaggedPropertyType.MaxTaggedArguments)) {
|
||||
if ((tg.items().size() < TaggedPropertyType.MinTaggedArguments) || (tg.items().size() > TaggedPropertyType.MaxTaggedArguments)) {
|
||||
throw new LayoutCompilationException(String.format("Invalid number of arguments in Tagged: %1$s " +
|
||||
"<= %2$s <= %3$s", TaggedPropertyType.MinTaggedArguments, tg.getItems().size(),
|
||||
"<= %2$s <= %3$s", TaggedPropertyType.MinTaggedArguments, tg.items().size(),
|
||||
TaggedPropertyType.MaxTaggedArguments));
|
||||
}
|
||||
|
||||
TypeArgument[] tgArgs = new TypeArgument[tg.getItems().size() + 1];
|
||||
TypeArgument[] tgArgs = new TypeArgument[tg.items().size() + 1];
|
||||
tgArgs[0] = new TypeArgument(LayoutType.UInt8, TypeArgumentList.EMPTY);
|
||||
for (int i = 0; i < tg.getItems().size(); i++) {
|
||||
for (int i = 0; i < tg.items().size(); i++) {
|
||||
TypeArgumentList itemTypeArgs = new TypeArgumentList();
|
||||
Out<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);
|
||||
itemTypeArgs = tempOut_itemTypeArgs4.get();
|
||||
if (tg.getItems().get(i).getNullable()) {
|
||||
if (tg.items().get(i).nullable()) {
|
||||
itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
|
||||
itemTypeArgs.clone()) });
|
||||
itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
|
||||
@@ -329,7 +329,7 @@ public final class LayoutCompiler {
|
||||
}
|
||||
|
||||
typeArgs.setAndGet(new TypeArgumentList(tgArgs));
|
||||
switch (tg.getItems().size()) {
|
||||
switch (tg.items().size()) {
|
||||
case 1:
|
||||
return immutable ? LayoutType.ImmutableTagged : LayoutType.Tagged;
|
||||
case 2:
|
||||
@@ -341,28 +341,28 @@ public final class LayoutCompiler {
|
||||
case Schema:
|
||||
UdtPropertyType up = (UdtPropertyType)logicalType;
|
||||
Schema udtSchema;
|
||||
if (SchemaId.opEquals(up.getSchemaId().clone(), SchemaId.INVALID)) {
|
||||
udtSchema = tangible.ListHelper.find(ns.getSchemas(), s = up.getName().equals( > s.Name))
|
||||
if (SchemaId.opEquals(up.schemaId().clone(), SchemaId.INVALID)) {
|
||||
udtSchema = tangible.ListHelper.find(ns.schemas(), s = up.name().equals( > s.Name))
|
||||
} else {
|
||||
udtSchema = tangible.ListHelper.find(ns.getSchemas(), s =
|
||||
SchemaId.opEquals( > s.SchemaId, up.getSchemaId().clone()))
|
||||
if (!udtSchema.getName().equals(up.getName())) {
|
||||
udtSchema = tangible.ListHelper.find(ns.schemas(), s =
|
||||
SchemaId.opEquals( > s.SchemaId, up.schemaId().clone()))
|
||||
if (!udtSchema.name().equals(up.name())) {
|
||||
throw new LayoutCompilationException(String.format("Ambiguous schema reference: '%1$s:%2$s'",
|
||||
up.getName(), up.getSchemaId().clone()));
|
||||
up.name(), up.schemaId().clone()));
|
||||
}
|
||||
}
|
||||
|
||||
if (udtSchema == null) {
|
||||
throw new LayoutCompilationException(String.format("Cannot resolve schema reference '%1$s:%2$s'",
|
||||
up.getName(), up.getSchemaId().clone()));
|
||||
up.name(), up.schemaId().clone()));
|
||||
}
|
||||
|
||||
typeArgs.setAndGet(new TypeArgumentList(udtSchema.getSchemaId().clone()));
|
||||
typeArgs.setAndGet(new TypeArgumentList(udtSchema.schemaId().clone()));
|
||||
return immutable ? LayoutType.ImmutableUDT : LayoutType.UDT;
|
||||
|
||||
default:
|
||||
throw new LayoutCompilationException(String.format("Unknown property type: %1$s",
|
||||
logicalType.getType()));
|
||||
logicalType.type()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,10 +53,10 @@ public final class LayoutResolverNamespace extends LayoutResolver {
|
||||
return layout;
|
||||
}
|
||||
|
||||
for (Schema s : this.schemaNamespace.getSchemas()) {
|
||||
if (SchemaId.opEquals(s.getSchemaId().clone(),
|
||||
for (Schema s : this.schemaNamespace.schemas()) {
|
||||
if (SchemaId.opEquals(s.schemaId().clone(),
|
||||
schemaId.clone())) {
|
||||
layout = s.Compile(this.schemaNamespace);
|
||||
layout = s.compile(this.schemaNamespace);
|
||||
layout = this.layoutCache.putIfAbsent(schemaId.value(), layout);
|
||||
return layout;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ public abstract class LayoutType<T> implements ILayoutType {
|
||||
}
|
||||
|
||||
public int countTypeArgument(TypeArgumentList value) {
|
||||
return (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
return LayoutCode.BYTES;
|
||||
}
|
||||
|
||||
public final Result deleteFixed(RowBuffer b, RowCursor scope, LayoutColumn column) {
|
||||
@@ -311,7 +311,9 @@ public abstract class LayoutType<T> implements ILayoutType {
|
||||
* @return Success if the write is permitted, the error code otherwise.
|
||||
*/
|
||||
public static Result prepareSparseWrite(
|
||||
@Nonnull final RowBuffer b, @Nonnull final RowCursor edit, @Nonnull final TypeArgument typeArg,
|
||||
@Nonnull final RowBuffer b,
|
||||
@Nonnull final RowCursor edit,
|
||||
@Nonnull final TypeArgument typeArg,
|
||||
@Nonnull final UpdateOptions options) {
|
||||
|
||||
if (edit.immutable() || (edit.scopeType().isUniqueScope() && !edit.deferUniqueIndex())) {
|
||||
@@ -356,10 +358,10 @@ public abstract class LayoutType<T> implements ILayoutType {
|
||||
public static TypeArgument readTypeArgument(RowBuffer row, int offset, Out<Integer> lenInBytes) {
|
||||
LayoutType itemCode = row.readSparseTypeCode(offset);
|
||||
int argsLenInBytes;
|
||||
Out<Integer> tempOut_argsLenInBytes = new Out<Integer>();
|
||||
TypeArgumentList itemTypeArgs = itemCode.readTypeArgumentList(row, offset + (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE), tempOut_argsLenInBytes);
|
||||
Out<Integer> tempOut_argsLenInBytes = new Out<>();
|
||||
TypeArgumentList itemTypeArgs = itemCode.readTypeArgumentList(row, offset + LayoutCode.BYTES, tempOut_argsLenInBytes);
|
||||
argsLenInBytes = tempOut_argsLenInBytes.get();
|
||||
lenInBytes.setAndGet((com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE) + argsLenInBytes);
|
||||
lenInBytes.setAndGet(LayoutCode.BYTES + argsLenInBytes);
|
||||
return new TypeArgument(itemCode, itemTypeArgs);
|
||||
}
|
||||
|
||||
@@ -396,7 +398,7 @@ public abstract class LayoutType<T> implements ILayoutType {
|
||||
|
||||
public int writeTypeArgument(RowBuffer row, int offset, TypeArgumentList value) {
|
||||
row.writeSparseTypeCode(offset, this.layoutCode());
|
||||
return com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE;
|
||||
return LayoutCode.BYTES;
|
||||
}
|
||||
|
||||
public Result writeVariable(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, T value) {
|
||||
|
||||
@@ -67,7 +67,7 @@ public abstract class LayoutUniqueScope extends LayoutIndexedScope {
|
||||
// Perform the move.
|
||||
Reference<RowCursor> tempReference_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();
|
||||
|
||||
// TODO: it would be "better" if the destinationScope were updated to point to the
|
||||
|
||||
@@ -9,10 +9,12 @@ import com.azure.data.cosmos.serialization.hybridrow.HybridRowVersion;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.ISpanResizer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.Layout;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.SystemSchema;
|
||||
|
||||
public final class RecordIOFormatter {
|
||||
public static final Layout RecordLayout = SystemSchema.LayoutResolver.Resolve(SystemSchema.RecordSchemaId);
|
||||
public static final Layout SegmentLayout = SystemSchema.LayoutResolver.Resolve(SystemSchema.SegmentSchemaId);
|
||||
public static final Layout RecordLayout = SystemSchema.LayoutResolver.resolve(SystemSchema.RecordSchemaId);
|
||||
public static final Layout SegmentLayout = SystemSchema.LayoutResolver.resolve(SystemSchema.SegmentSchemaId);
|
||||
|
||||
public static Result FormatRecord(ReadOnlyMemory<Byte> body, Out<RowBuffer> row) {
|
||||
return FormatRecord(body, row, null);
|
||||
|
||||
@@ -6,24 +6,23 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
/**
|
||||
* Array properties represent an unbounded set of zero or more items.
|
||||
* <p>
|
||||
* Arrays may be typed or untyped. Within typed arrays, all items MUST be the same type. The
|
||||
* type of items is specified via {@link Items}. Typed arrays may be stored more efficiently
|
||||
* than untyped arrays. When {@link Items} is unspecified, the array is untyped and its items
|
||||
* may be heterogeneous.
|
||||
* Arrays may be typed or untyped. Within typed arrays, all items MUST be the same type. The type of items is specified
|
||||
* via {@link #items}. Typed arrays may be stored more efficiently than untyped arrays. When {@link #items} is
|
||||
* unspecified, the array is untyped and its items may be heterogeneous.
|
||||
*/
|
||||
public class ArrayPropertyType extends ScopePropertyType {
|
||||
|
||||
private PropertyType items;
|
||||
|
||||
/**
|
||||
* (Optional) type of the elements of the array, if a typed array, otherwise null.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "items")] public PropertyType Items {get;set;}
|
||||
private PropertyType Items;
|
||||
|
||||
public final PropertyType getItems() {
|
||||
return Items;
|
||||
public final PropertyType items() {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
public final void setItems(PropertyType value) {
|
||||
Items = value;
|
||||
public final ArrayPropertyType items(PropertyType value) {
|
||||
this.items = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,43 +4,39 @@
|
||||
package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
/**
|
||||
* Map properties represent an unbounded set of zero or more key-value pairs with unique
|
||||
* keys.
|
||||
* Map properties represent an unbounded set of zero or more key-value pairs with unique keys
|
||||
* <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. The type of both key and values is specified via {@link Keys}
|
||||
* and {@link Values} respectively. Typed maps may be stored more efficiently than untyped
|
||||
* maps. When {@link Keys} or {@link Values} is unspecified or marked
|
||||
* {@link TypeKind.Any}, the map is untyped and its key and/or values may be heterogeneous.
|
||||
* Maps are typed or untyped. Within typed maps, all key MUST be the same type, and all values MUST be the same type.
|
||||
* The type of both key and values is specified via {@link #keys} and {@link #values} respectively. Typed maps may be
|
||||
* stored more efficiently than untyped maps. When {@link #keys} or {@link #values} is unspecified or marked
|
||||
* {@link TypeKind#Any}, the map is untyped and its key and/or values may be heterogeneous.
|
||||
*/
|
||||
public class MapPropertyType extends ScopePropertyType {
|
||||
|
||||
private PropertyType keys;
|
||||
private PropertyType values;
|
||||
|
||||
/**
|
||||
* (Optional) type of the keys of the map, if a typed map, otherwise null.
|
||||
* (Optional) type of the keys of the map, if a typed map, otherwise {@code null}
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "keys")] public PropertyType Keys {get;set;}
|
||||
private PropertyType Keys;
|
||||
public final PropertyType keys() {
|
||||
return this.keys;
|
||||
}
|
||||
|
||||
public final MapPropertyType keys(PropertyType value) {
|
||||
this.keys = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Optional) type of the values of the map, if a typed map, otherwise null.
|
||||
* (Optional) type of the values of the map, if a typed map, otherwise {@code null}
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "values")] public PropertyType Values {get;set;}
|
||||
private PropertyType Values;
|
||||
|
||||
public final PropertyType getKeys() {
|
||||
return Keys;
|
||||
public final PropertyType values() {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
public final void setKeys(PropertyType value) {
|
||||
Keys = value;
|
||||
}
|
||||
|
||||
public final PropertyType getValues() {
|
||||
return Values;
|
||||
}
|
||||
|
||||
public final void setValues(PropertyType value) {
|
||||
Values = value;
|
||||
public final MapPropertyType values(PropertyType value) {
|
||||
this.values = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -3,39 +3,15 @@
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
import Newtonsoft.Json.*;
|
||||
import com.azure.data.cosmos.core.Json;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Optional;
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java:
|
||||
///#pragma warning disable CA1716 // Identifiers should not match keywords
|
||||
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonObject] public class Namespace
|
||||
public class Namespace {
|
||||
/**
|
||||
* The standard settings used by the JSON parser for interpreting {@link Namespace}
|
||||
* documents.
|
||||
*/
|
||||
private static final JsonSerializerSettings NamespaceParseSettings = new JsonSerializerSettings() {
|
||||
CheckAdditionalContent =true
|
||||
};
|
||||
/**
|
||||
* The fully qualified identifier of the namespace.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "name")] public string Name {get;set;}
|
||||
private String Name;
|
||||
/**
|
||||
* The version of the HybridRow Schema Definition Language used to encode this namespace.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "version")] public SchemaLanguageVersion Version {get;set;}
|
||||
private SchemaLanguageVersion Version = SchemaLanguageVersion.values()[0];
|
||||
/**
|
||||
* The set of schemas that make up the {@link Namespace}.
|
||||
*/
|
||||
|
||||
private String name;
|
||||
private SchemaLanguageVersion version = SchemaLanguageVersion.values()[0];
|
||||
private ArrayList<Schema> schemas;
|
||||
|
||||
/**
|
||||
@@ -45,12 +21,15 @@ public class Namespace {
|
||||
this.setSchemas(new ArrayList<Schema>());
|
||||
}
|
||||
|
||||
/**
|
||||
* The fully qualified identifier of the namespace.
|
||||
*/
|
||||
public final String getName() {
|
||||
return Name;
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public final void setName(String value) {
|
||||
Name = value;
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,9 +39,7 @@ public class Namespace {
|
||||
* Table schemas can only reference UDT schemas defined in the same namespace. UDT schemas can
|
||||
* contain nested UDTs whose schemas are defined within the same namespace.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "schemas")] public List<Schema> Schemas
|
||||
public final ArrayList<Schema> getSchemas() {
|
||||
public final ArrayList<Schema> schemas() {
|
||||
return this.schemas;
|
||||
}
|
||||
|
||||
@@ -70,23 +47,26 @@ public class Namespace {
|
||||
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() {
|
||||
return Version;
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public final void setVersion(SchemaLanguageVersion value) {
|
||||
Version = value;
|
||||
this.version = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a JSON document and return a full namespace.
|
||||
*
|
||||
* @param json The JSON text to parse.
|
||||
* @param value The JSON text to parse
|
||||
* @return A namespace containing a set of logical schemas.
|
||||
*/
|
||||
public static Namespace Parse(String json) {
|
||||
Namespace ns = JsonConvert.<Namespace>DeserializeObject(json, Namespace.NamespaceParseSettings);
|
||||
SchemaValidator.Validate(ns);
|
||||
public static Optional<Namespace> parse(String value) {
|
||||
Optional<Namespace> ns = Json.<Namespace>parse(value);
|
||||
ns.ifPresent(SchemaValidator::Validate);
|
||||
return ns;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,39 +3,36 @@
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Object properties represent nested structures.
|
||||
* <p>
|
||||
* Object properties map to multiple columns depending on the number of internal properties
|
||||
* within the defined object structure. Object properties are provided as a convince in schema
|
||||
* design. They are effectively equivalent to defining the same properties explicitly via
|
||||
* {@link PrimitivePropertyType} with nested property paths.
|
||||
* Object properties map to multiple columns depending on the number of internal properties within the defined object
|
||||
* structure. Object properties are provided as a convince in schema design. They are effectively equivalent to
|
||||
* defining the same properties explicitly via {@link PrimitivePropertyType} with nested property paths.
|
||||
*/
|
||||
public class ObjectPropertyType extends ScopePropertyType {
|
||||
/**
|
||||
* A list of zero or more property definitions that define the columns within the schema.
|
||||
*/
|
||||
private ArrayList<Property> properties;
|
||||
|
||||
private List<Property> properties;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link ObjectPropertyType} class.
|
||||
*/
|
||||
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:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "properties")] public List<Property> Properties
|
||||
public final ArrayList<Property> getProperties() {
|
||||
public final List<Property> properties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
public final void setProperties(ArrayList<Property> value) {
|
||||
this.properties = value != null ? value : new ArrayList<Property>();
|
||||
public final ObjectPropertyType properties(List<Property> value) {
|
||||
this.properties = value != null ? value : Collections.emptyList();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -11,15 +11,14 @@ public class PartitionKey {
|
||||
* The logical path of the referenced property.
|
||||
* Partition keys MUST refer to properties defined within the same {@link Schema}.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "path", Required = Required.Always)] public string Path {get;set;}
|
||||
private String Path;
|
||||
private String path;
|
||||
|
||||
public final String getPath() {
|
||||
return Path;
|
||||
public final String path() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public final void setPath(String value) {
|
||||
Path = value;
|
||||
public final PartitionKey path(String value) {
|
||||
this.path = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -8,35 +8,33 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
* partition.
|
||||
*/
|
||||
public class PrimarySortKey {
|
||||
|
||||
private SortDirection direction = SortDirection.values()[0];
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* The logical path of the referenced property.
|
||||
* Primary keys MUST refer to properties defined within the same {@link Schema}.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "direction", Required = Required.DisallowNull)] public
|
||||
// SortDirection Direction {get;set;}
|
||||
private SortDirection Direction = SortDirection.values()[0];
|
||||
public final SortDirection direction() {
|
||||
return this.direction;
|
||||
}
|
||||
|
||||
public final PrimarySortKey direction(SortDirection value) {
|
||||
this.direction = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The logical path of the referenced property.
|
||||
* Primary keys MUST refer to properties defined within the same {@link Schema}.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "path", Required = Required.Always)] public string Path {get;set;}
|
||||
private String Path;
|
||||
|
||||
public final SortDirection getDirection() {
|
||||
return Direction;
|
||||
public final String path() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public final void setDirection(SortDirection value) {
|
||||
Direction = value;
|
||||
}
|
||||
|
||||
public final String getPath() {
|
||||
return Path;
|
||||
}
|
||||
|
||||
public final void setPath(String value) {
|
||||
Path = value;
|
||||
public final PrimarySortKey path(String value) {
|
||||
this.path = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -10,36 +10,34 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
* column should be represented within the row.
|
||||
*/
|
||||
public class PrimitivePropertyType extends PropertyType {
|
||||
|
||||
private int length;
|
||||
private StorageKind storage = StorageKind.values()[0];
|
||||
|
||||
/**
|
||||
* The maximum allowable length in bytes.
|
||||
* <p>
|
||||
* This annotation is only valid for non-fixed length types. A value of 0 means the maximum
|
||||
* allowable length.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "length")][JsonConverter(typeof(StrictIntegerConverter))] public
|
||||
// int Length {get;set;}
|
||||
private int Length;
|
||||
public final int length() {
|
||||
return this.length;
|
||||
}
|
||||
|
||||
public final PrimitivePropertyType length(int value) {
|
||||
this.length = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Storage requirements of the property.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "storage")] public StorageKind Storage {get;set;}
|
||||
private StorageKind Storage = StorageKind.values()[0];
|
||||
|
||||
public final int getLength() {
|
||||
return Length;
|
||||
public final StorageKind storage() {
|
||||
return this.storage;
|
||||
}
|
||||
|
||||
public final void setLength(int value) {
|
||||
Length = value;
|
||||
}
|
||||
|
||||
public final StorageKind getStorage() {
|
||||
return Storage;
|
||||
}
|
||||
|
||||
public final void setStorage(StorageKind value) {
|
||||
Storage = value;
|
||||
public final PrimitivePropertyType storage(StorageKind value) {
|
||||
this.storage = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -3,65 +3,56 @@
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java:
|
||||
///#pragma warning disable CA1716 // Identifiers should not match keywords
|
||||
|
||||
|
||||
/**
|
||||
* Describes a single property definition.
|
||||
*/
|
||||
public class Property {
|
||||
|
||||
private String comment;
|
||||
private String path;
|
||||
private PropertyType propertyType;
|
||||
|
||||
/**
|
||||
* An (optional) comment describing the purpose of this property.
|
||||
* An (optional) comment describing the purpose of this property
|
||||
* <p>
|
||||
* Comments are for documentary purpose only and do not affect the property at runtime.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "comment", DefaultValueHandling = DefaultValueHandling
|
||||
// .IgnoreAndPopulate)] public string Comment {get;set;}
|
||||
private String Comment;
|
||||
public final String comment() {
|
||||
return this.comment;
|
||||
}
|
||||
|
||||
public final Property comment(String value) {
|
||||
this.comment = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The logical path of this property.
|
||||
* <p>
|
||||
* For complex properties (e.g. objects) the logical path forms a prefix to relative paths of
|
||||
* properties defined within nested structures.
|
||||
* <para />
|
||||
* For complex properties (e.g. objects) the logical path forms a prefix to relative paths of properties defined
|
||||
* within nested structures.
|
||||
* <p>
|
||||
* See the logical path specification for full details on both relative and absolute paths.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "path", Required = Required.Always)] public string Path {get;set;}
|
||||
private String Path;
|
||||
/**
|
||||
* The type of the property.
|
||||
* <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 String path() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public final void setPath(String value) {
|
||||
Path = value;
|
||||
this.path = value;
|
||||
}
|
||||
|
||||
public final PropertyType getPropertyType() {
|
||||
return PropertyType;
|
||||
/**
|
||||
* The type of the property.
|
||||
* <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) {
|
||||
PropertyType = value;
|
||||
this.propertyType = value;
|
||||
}
|
||||
}
|
||||
@@ -6,56 +6,51 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
/**
|
||||
* The base class for property types both primitive and complex.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonConverter(typeof(PropertySchemaConverter))] public abstract class PropertyType
|
||||
public abstract class PropertyType {
|
||||
|
||||
private String apiType;
|
||||
private boolean nullable;
|
||||
private TypeKind type = TypeKind.values()[0];
|
||||
|
||||
protected PropertyType() {
|
||||
this.nullable(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Api-specific type annotations for the property.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "apitype")] public string ApiType {get;set;}
|
||||
private String ApiType;
|
||||
public final String apiType() {
|
||||
return this.apiType;
|
||||
}
|
||||
|
||||
public final PropertyType apiType(String value) {
|
||||
this.apiType = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the property can be null.
|
||||
* Default: true.
|
||||
* {@code true} if the property can be {@code null}
|
||||
* <p>
|
||||
* Default: {@code true}
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [DefaultValue(true)][JsonProperty(PropertyName = "nullable", DefaultValueHandling =
|
||||
// DefaultValueHandling.IgnoreAndPopulate)][JsonConverter(typeof(StrictBooleanConverter))] public bool Nullable
|
||||
// {get;set;}
|
||||
private boolean Nullable;
|
||||
public final boolean nullable() {
|
||||
return this.nullable;
|
||||
}
|
||||
|
||||
public final PropertyType nullable(boolean value) {
|
||||
this.nullable = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The logical type of the property.
|
||||
* The logical type of the property
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "type")] public TypeKind Type {get;set;}
|
||||
private TypeKind Type = TypeKind.values()[0];
|
||||
|
||||
protected PropertyType() {
|
||||
this.setNullable(true);
|
||||
public final TypeKind type() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public final String getApiType() {
|
||||
return ApiType;
|
||||
}
|
||||
|
||||
public final void setApiType(String value) {
|
||||
ApiType = value;
|
||||
}
|
||||
|
||||
public final boolean getNullable() {
|
||||
return Nullable;
|
||||
}
|
||||
|
||||
public final void setNullable(boolean value) {
|
||||
Nullable = value;
|
||||
}
|
||||
|
||||
public final TypeKind getType() {
|
||||
return Type;
|
||||
}
|
||||
|
||||
public final void setType(TypeKind value) {
|
||||
Type = value;
|
||||
public final PropertyType type(TypeKind value) {
|
||||
this.type = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -3,32 +3,79 @@
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
import Newtonsoft.Json.*;
|
||||
import com.azure.data.cosmos.core.Json;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.Layout;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCompiler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* A schema describes either table or UDT metadata.
|
||||
* A schema describes either table or UDT metadata
|
||||
* <p>
|
||||
* The schema of a table or UDT describes the structure of row (i.e. which columns and the
|
||||
* types of those columns). A table schema represents the description of the contents of a collection
|
||||
* level row directly. UDTs described nested structured objects that may appear either within a table
|
||||
* column or within another UDT (i.e. nested UDTs).
|
||||
* The schema of a table or UDT describes the structure of row (i.e. which columns and the types of those columns). A
|
||||
* table schema represents the description of the contents of a collection level row directly. UDTs described nested
|
||||
* structured objects that may appear either within a table column or within another UDT (i.e. nested UDTs).
|
||||
*/
|
||||
public class Schema {
|
||||
|
||||
private String comment;
|
||||
private String name;
|
||||
private SchemaOptions options;
|
||||
private List<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.
|
||||
* Comments are for documentary purpose only and do not affect the schema at runtime.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "comment", DefaultValueHandling = DefaultValueHandling
|
||||
// .IgnoreAndPopulate)] public string Comment {get;set;}
|
||||
private String Comment;
|
||||
public final String comment() {
|
||||
return this.comment;
|
||||
}
|
||||
|
||||
public final Schema comment(String value) {
|
||||
this.comment = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles this logical schema into a physical layout that can be used to read and write rows
|
||||
*
|
||||
* @param ns The namespace within which this schema is defined.
|
||||
* @return The layout for the schema.
|
||||
*/
|
||||
public final Layout compile(Namespace ns) {
|
||||
|
||||
checkNotNull(ns, "expected non-null ns");
|
||||
checkArgument(ns.schemas().contains(this));
|
||||
|
||||
return LayoutCompiler.Compile(ns, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the schema.
|
||||
* <p>
|
||||
@@ -37,140 +84,99 @@ public class Schema {
|
||||
* Names must begin with an alpha-numeric character and can only contain alpha-numeric characters and
|
||||
* underscores.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "name", Required = Required.Always)] public string Name {get;set;}
|
||||
private String Name;
|
||||
public final String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public final Schema name(String value) {
|
||||
this.name = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schema-wide operations.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "options")] public SchemaOptions Options {get;set;}
|
||||
private SchemaOptions Options;
|
||||
/**
|
||||
* The unique identifier for a schema.
|
||||
* Identifiers must be unique within the scope of the database in which they are used.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "id", Required = Required.Always)] public SchemaId SchemaId {get;set;}
|
||||
private com.azure.data.cosmos.serialization.hybridrow.SchemaId SchemaId = new SchemaId();
|
||||
/**
|
||||
* The type of this schema. This value MUST be {@link TypeKind.Schema}.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [DefaultValue(TypeKind.Schema)][JsonProperty(PropertyName = "type", Required = Required
|
||||
// .DisallowNull, DefaultValueHandling = DefaultValueHandling.Populate)] public TypeKind Type {get;set;}
|
||||
private TypeKind Type = TypeKind.values()[0];
|
||||
/**
|
||||
* The version of the HybridRow Schema Definition Language used to encode this schema.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "version")] public SchemaLanguageVersion Version {get;set;}
|
||||
private SchemaLanguageVersion Version = SchemaLanguageVersion.values()[0];
|
||||
/**
|
||||
* An (optional) list of zero or more logical paths that form the partition key.
|
||||
*/
|
||||
private ArrayList<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 SchemaOptions options() {
|
||||
return this.options;
|
||||
}
|
||||
|
||||
public final String getComment() {
|
||||
return Comment;
|
||||
}
|
||||
|
||||
public final void setComment(String value) {
|
||||
Comment = value;
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
return Name;
|
||||
}
|
||||
|
||||
public final void setName(String value) {
|
||||
Name = value;
|
||||
}
|
||||
|
||||
public final SchemaOptions getOptions() {
|
||||
return Options;
|
||||
}
|
||||
|
||||
public final void setOptions(SchemaOptions value) {
|
||||
Options = value;
|
||||
public final Schema options(SchemaOptions value) {
|
||||
this.options = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* An (optional) list of zero or more logical paths that form the partition key.
|
||||
* All paths referenced MUST map to a property within the schema.
|
||||
* <para />
|
||||
* This field is never null.
|
||||
* Parse a JSON fragment and return a schema.
|
||||
*
|
||||
* @param value The JSON string value to parse
|
||||
* @return A logical schema, if the value parses.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "partitionkeys")] public List<PartitionKey> PartitionKeys
|
||||
public final ArrayList<PartitionKey> getPartitionKeys() {
|
||||
public static Optional<Schema> parse(String value) {
|
||||
return Json.<Schema>parse(value); // TODO: DANOBLE: perform structural validation on the Schema after JSON
|
||||
// parsing
|
||||
}
|
||||
|
||||
/**
|
||||
* An (optional) list of zero or more logical paths that form the partition key
|
||||
* <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;
|
||||
}
|
||||
|
||||
public final void setPartitionKeys(ArrayList<PartitionKey> value) {
|
||||
this.partitionKeys = value != null ? value : new ArrayList<PartitionKey>();
|
||||
public final Schema partitionKeys(@Nullable List<PartitionKey> value) {
|
||||
this.partitionKeys = value != null ? value : Collections.emptyList();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* An (optional) list of zero or more logical paths that form the primary sort key.
|
||||
* All paths referenced MUST map to a property within the schema.
|
||||
* <para />
|
||||
* This field is never null.
|
||||
* An (optional) list of zero or more logical paths that form the primary sort 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
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "primarykeys")] public List<PrimarySortKey> PrimarySortKeys
|
||||
public final ArrayList<PrimarySortKey> getPrimarySortKeys() {
|
||||
public final List<PrimarySortKey> primarySortKeys() {
|
||||
return this.primaryKeys;
|
||||
}
|
||||
|
||||
public final void setPrimarySortKeys(ArrayList<PrimarySortKey> value) {
|
||||
this.primaryKeys = value != null ? value : new ArrayList<PrimarySortKey>();
|
||||
public final Schema primarySortKeys(ArrayList<PrimarySortKey> value) {
|
||||
this.primaryKeys = value != null ? value : Collections.emptyList();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of zero or more property definitions that define the columns within the schema.
|
||||
* A list of zero or more property definitions that define the columns within the schema
|
||||
* <p>
|
||||
* This field is never null.
|
||||
*
|
||||
* @return list of zero or more property definitions that define the columns within the schema
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "properties")] public List<Property> Properties
|
||||
public final ArrayList<Property> getProperties() {
|
||||
public final List<Property> properties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
public final void setProperties(ArrayList<Property> value) {
|
||||
this.properties = value != null ? value : new ArrayList<Property>();
|
||||
public final Schema properties(List<Property> value) {
|
||||
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) {
|
||||
SchemaId = value.clone();
|
||||
public final Schema schemaId(SchemaId value) {
|
||||
this.schemaId = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,57 +184,51 @@ public class Schema {
|
||||
* All paths referenced MUST map to a property within the schema.
|
||||
* <para />
|
||||
* This field is never null.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "statickeys", DefaultValueHandling = DefaultValueHandling
|
||||
// .IgnoreAndPopulate)] public List<StaticKey> StaticKeys
|
||||
public final ArrayList<StaticKey> getStaticKeys() {
|
||||
public final List<StaticKey> staticKeys() {
|
||||
return this.staticKeys;
|
||||
}
|
||||
|
||||
public final void setStaticKeys(ArrayList<StaticKey> value) {
|
||||
this.staticKeys = value != null ? value : new ArrayList<StaticKey>();
|
||||
}
|
||||
|
||||
public final TypeKind getType() {
|
||||
return Type;
|
||||
}
|
||||
|
||||
public final void setType(TypeKind value) {
|
||||
Type = value;
|
||||
}
|
||||
|
||||
public final SchemaLanguageVersion getVersion() {
|
||||
return Version;
|
||||
}
|
||||
|
||||
public final void setVersion(SchemaLanguageVersion value) {
|
||||
Version = value;
|
||||
public final Schema staticKeys(List<StaticKey> value) {
|
||||
this.staticKeys = value != null ? value : Collections.emptyList();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles this logical schema into a physical layout that can be used to read and write
|
||||
* rows.
|
||||
* Returns a JSON string representation of the current {@link Schema}
|
||||
*
|
||||
* @param ns The namespace within which this schema is defined.
|
||||
* @return The layout for the schema.
|
||||
* @return a JSON string representation of the current {@link Schema}
|
||||
*/
|
||||
public final Layout Compile(Namespace ns) {
|
||||
checkArgument(ns != null);
|
||||
checkArgument(ns.getSchemas().contains(this));
|
||||
|
||||
return LayoutCompiler.Compile(ns, this);
|
||||
@Override
|
||||
public String toString() {
|
||||
return Json.toString(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a JSON fragment and return a schema.
|
||||
*
|
||||
* @param json The JSON text to parse.
|
||||
* @return A logical schema.
|
||||
* The type of this schema
|
||||
* <p>
|
||||
* This value MUST be {@link TypeKind#Schema}.
|
||||
*/
|
||||
public static Schema Parse(String json) {
|
||||
return JsonConvert.<Schema>DeserializeObject(json);
|
||||
public final TypeKind type() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
// TODO: perform structural validation on the Schema after JSON parsing.
|
||||
public final Schema type(TypeKind value) {
|
||||
this.type = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The version of the HybridRow Schema Definition Language used to encode this schema
|
||||
*/
|
||||
public final SchemaLanguageVersion version() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public final Schema version(SchemaLanguageVersion value) {
|
||||
this.version = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,8 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [Serializable][ExcludeFromCodeCoverage] public sealed class SchemaException : Exception
|
||||
public final class SchemaException extends RuntimeException implements Serializable {
|
||||
|
||||
public SchemaException() {
|
||||
}
|
||||
|
||||
@@ -18,8 +17,4 @@ public final class SchemaException extends RuntimeException implements Serializa
|
||||
public SchemaException(String message, RuntimeException innerException) {
|
||||
super(message, innerException);
|
||||
}
|
||||
|
||||
private SchemaException(SerializationInfo info, StreamingContext context) {
|
||||
super(info, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,45 +3,40 @@
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java:
|
||||
///#pragma warning disable CA1028 // Enum Storage should be Int32
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Versions of the HybridRow Schema Description Language.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonConverter(typeof(StringEnumConverter), true)] public enum SchemaLanguageVersion : byte
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: [JsonConverter(typeof(StringEnumConverter), true)] public enum SchemaLanguageVersion : byte
|
||||
public enum SchemaLanguageVersion {
|
||||
/**
|
||||
* Initial version of the HybridRow Schema Description Lanauge.
|
||||
*/
|
||||
V1((byte)0);
|
||||
|
||||
public static final int SIZE = java.lang.Byte.SIZE;
|
||||
private static java.util.HashMap<Byte, SchemaLanguageVersion> mappings;
|
||||
private byte byteValue;
|
||||
public static final int BYTES = Byte.BYTES;
|
||||
|
||||
private static HashMap<Byte, SchemaLanguageVersion> mappings;
|
||||
private byte value;
|
||||
|
||||
SchemaLanguageVersion(byte value) {
|
||||
byteValue = value;
|
||||
getMappings().put(value, this);
|
||||
this.value = value;
|
||||
mappings().put(value, this);
|
||||
}
|
||||
|
||||
public byte getValue() {
|
||||
return byteValue;
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public static SchemaLanguageVersion forValue(byte value) {
|
||||
return getMappings().get(value);
|
||||
return mappings().get(value);
|
||||
}
|
||||
|
||||
private static java.util.HashMap<Byte, SchemaLanguageVersion> getMappings() {
|
||||
private static HashMap<Byte, SchemaLanguageVersion> mappings() {
|
||||
if (mappings == null) {
|
||||
synchronized (SchemaLanguageVersion.class) {
|
||||
if (mappings == null) {
|
||||
mappings = new java.util.HashMap<Byte, SchemaLanguageVersion>();
|
||||
mappings = new HashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,14 +7,23 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
* Describes the set of options that apply to the entire schema and the way it is validated.
|
||||
*/
|
||||
public class SchemaOptions {
|
||||
|
||||
private boolean disableSystemPrefix;
|
||||
private boolean disallowUnschematized;
|
||||
private boolean enablePropertyLevelTimestamp;
|
||||
|
||||
/**
|
||||
* If the is value true, then disables prefixing the system properties with a prefix __sys_
|
||||
* for reserved properties owned by the store layer.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "disableSystemPrefix", DefaultValueHandling = DefaultValueHandling
|
||||
// .IgnoreAndPopulate)][JsonConverter(typeof(StrictBooleanConverter))] public bool DisableSystemPrefix {get;set;}
|
||||
private boolean DisableSystemPrefix;
|
||||
public final boolean disableSystemPrefix() {
|
||||
return this.disableSystemPrefix;
|
||||
}
|
||||
|
||||
public final void disableSystemPrefix(boolean value) {
|
||||
this.disableSystemPrefix = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* If true then structural schema validation is enabled.
|
||||
* <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
|
||||
* overwritten). No error will be given.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "disallowUnschematized")][JsonConverter(typeof
|
||||
// (StrictBooleanConverter))] public bool DisallowUnschematized {get;set;}
|
||||
private boolean DisallowUnschematized;
|
||||
public final boolean disallowUnschematized() {
|
||||
return this.disallowUnschematized;
|
||||
}
|
||||
|
||||
public final void disallowUnschematized(boolean value) {
|
||||
this.disallowUnschematized = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set and has the value true, then triggers behavior in the Schema that acts based on property
|
||||
* level timestamps. In Cassandra, this means that new columns are added for each top level property
|
||||
* that has values of the client side timestamp. This is then used in conflict resolution to independently
|
||||
* resolve each property based on the timestamp value of that property.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "enablePropertyLevelTimestamp")][JsonConverter(typeof
|
||||
// (StrictBooleanConverter))] public bool EnablePropertyLevelTimestamp {get;set;}
|
||||
private boolean EnablePropertyLevelTimestamp;
|
||||
|
||||
public final boolean getDisableSystemPrefix() {
|
||||
return DisableSystemPrefix;
|
||||
public final boolean enablePropertyLevelTimestamp() {
|
||||
return this.enablePropertyLevelTimestamp;
|
||||
}
|
||||
|
||||
public final void setDisableSystemPrefix(boolean value) {
|
||||
DisableSystemPrefix = value;
|
||||
}
|
||||
|
||||
public final boolean getDisallowUnschematized() {
|
||||
return DisallowUnschematized;
|
||||
}
|
||||
|
||||
public final void setDisallowUnschematized(boolean value) {
|
||||
DisallowUnschematized = value;
|
||||
}
|
||||
|
||||
public final boolean getEnablePropertyLevelTimestamp() {
|
||||
return EnablePropertyLevelTimestamp;
|
||||
}
|
||||
|
||||
public final void setEnablePropertyLevelTimestamp(boolean value) {
|
||||
EnablePropertyLevelTimestamp = value;
|
||||
public final void enablePropertyLevelTimestamp(boolean value) {
|
||||
this.enablePropertyLevelTimestamp = value;
|
||||
}
|
||||
}
|
||||
@@ -24,19 +24,19 @@ HashMap<SchemaId, Schema> ids
|
||||
, TypeKind.Schema, s.getType()));
|
||||
HashMap<String, Property> pathDupCheck = new HashMap<String, Property>(s.getProperties().size());
|
||||
for (Property p : s.getProperties()) {
|
||||
ValidateAssert.DuplicateCheck(p.getPath(), p, pathDupCheck, "Property path", "Schema");
|
||||
ValidateAssert.DuplicateCheck(p.path(), p, pathDupCheck, "Property path", "Schema");
|
||||
}
|
||||
|
||||
for (PartitionKey pk : s.getPartitionKeys()) {
|
||||
ValidateAssert.Exists(pk.getPath(), pathDupCheck, "Partition key column", "Schema");
|
||||
ValidateAssert.Exists(pk.path(), pathDupCheck, "Partition key column", "Schema");
|
||||
}
|
||||
|
||||
for (PrimarySortKey ps : s.getPrimarySortKeys()) {
|
||||
ValidateAssert.Exists(ps.getPath(), pathDupCheck, "Primary sort key column", "Schema");
|
||||
ValidateAssert.Exists(ps.path(), pathDupCheck, "Primary sort key column", "Schema");
|
||||
}
|
||||
|
||||
for (StaticKey sk : s.getStaticKeys()) {
|
||||
ValidateAssert.Exists(sk.getPath(), pathDupCheck, "Static key column", "Schema");
|
||||
ValidateAssert.Exists(sk.path(), pathDupCheck, "Static key column", "Schema");
|
||||
}
|
||||
|
||||
for (Property p : s.getProperties()) {
|
||||
@@ -108,8 +108,8 @@ HashMap<SchemaId, Schema> ids
|
||||
op:
|
||||
HashMap<String, Property> pathDupCheck = new HashMap<String, Property>(op.Properties.Count);
|
||||
for (Property nested : op.Properties) {
|
||||
ValidateAssert.DuplicateCheck(nested.getPath(), nested, pathDupCheck, "Property path", "Object");
|
||||
SchemaValidator.Visit(nested.getPropertyType(), p, schemas, ids);
|
||||
ValidateAssert.DuplicateCheck(nested.path(), nested, pathDupCheck, "Property path", "Object");
|
||||
SchemaValidator.Visit(nested.propertyType(), p, schemas, ids);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -121,8 +121,8 @@ HashMap<SchemaId, Schema> ids
|
||||
if (SchemaId.opNotEquals(up.SchemaId,
|
||||
SchemaId.INVALID)) {
|
||||
Schema s = ValidateAssert.Exists(up.SchemaId, ids, "Schema id", "Namespace");
|
||||
ValidateAssert.AreEqual(up.Name, s.getName(), String.format("Schema name '%1$s' does not match " +
|
||||
"the name of schema with id '%2$s': %3$s", up.Name, up.SchemaId, s.getName()));
|
||||
ValidateAssert.AreEqual(up.Name, s.name(), String.format("Schema name '%1$s' does not match " +
|
||||
"the name of schema with id '%2$s': %3$s", up.Name, up.SchemaId, s.name()));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -133,27 +133,27 @@ HashMap<SchemaId, Schema> ids
|
||||
}>schemas,
|
||||
|
||||
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),
|
||||
Schema > nameDupCheck = new HashMap<(String, SchemaId), Schema > (ns.getSchemas().size());
|
||||
HashMap<SchemaId, Schema> idDupCheck = new HashMap<SchemaId, Schema>(ns.getSchemas().size());
|
||||
for (Schema s : ns.getSchemas()) {
|
||||
ValidateAssert.IsValidSchemaId(s.getSchemaId().clone(), "Schema id");
|
||||
ValidateAssert.IsValidIdentifier(s.getName(), "Schema name");
|
||||
ValidateAssert.DuplicateCheck(s.getSchemaId().clone(), s, idDupCheck, "Schema id", "Namespace");
|
||||
ValidateAssert.DuplicateCheck((s.getName(), s.getSchemaId().clone()), s, nameDupCheck, "Schema reference"
|
||||
Schema > nameDupCheck = new HashMap<(String, SchemaId), Schema > (ns.schemas().size());
|
||||
HashMap<SchemaId, Schema> idDupCheck = new HashMap<SchemaId, Schema>(ns.schemas().size());
|
||||
for (Schema s : ns.schemas()) {
|
||||
ValidateAssert.IsValidSchemaId(s.schemaId().clone(), "Schema id");
|
||||
ValidateAssert.IsValidIdentifier(s.name(), "Schema name");
|
||||
ValidateAssert.DuplicateCheck(s.schemaId().clone(), s, idDupCheck, "Schema id", "Namespace");
|
||||
ValidateAssert.DuplicateCheck((s.name(), s.schemaId().clone()), s, nameDupCheck, "Schema reference"
|
||||
, "Namespace")
|
||||
|
||||
// Count the versions of each schema by name.
|
||||
int count;
|
||||
count = nameVersioningCheck.get(s.getName());
|
||||
nameVersioningCheck.put(s.getName(), count + 1);
|
||||
count = nameVersioningCheck.get(s.name());
|
||||
nameVersioningCheck.put(s.name(), count + 1);
|
||||
}
|
||||
|
||||
// Enable id-less Schema references for all types with a unique version in the namespace.
|
||||
for (Schema s : ns.getSchemas()) {
|
||||
if (nameVersioningCheck.get(s.getName()).equals(1)) {
|
||||
ValidateAssert.DuplicateCheck((s.getName(), SchemaId.INVALID), s, nameDupCheck, "Schema reference",
|
||||
for (Schema s : ns.schemas()) {
|
||||
if (nameVersioningCheck.get(s.name()).equals(1)) {
|
||||
ValidateAssert.DuplicateCheck((s.name(), SchemaId.INVALID), s, nameDupCheck, "Schema reference",
|
||||
"Namespace")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,20 +4,18 @@
|
||||
package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
public abstract class ScopePropertyType extends PropertyType {
|
||||
|
||||
private boolean immutable;
|
||||
|
||||
/**
|
||||
* True if the property's child elements cannot be mutated in place.
|
||||
* Immutable properties can still be replaced in their entirety.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "immutable")][JsonConverter(typeof(StrictBooleanConverter))] public
|
||||
// bool Immutable {get;set;}
|
||||
private boolean Immutable;
|
||||
|
||||
public final boolean getImmutable() {
|
||||
return Immutable;
|
||||
public final boolean immutable() {
|
||||
return this.immutable;
|
||||
}
|
||||
|
||||
public final void setImmutable(boolean value) {
|
||||
Immutable = value;
|
||||
public final void immutable(boolean value) {
|
||||
this.immutable = value;
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,11 @@
|
||||
package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
/**
|
||||
* Set properties represent an unbounded set of zero or more unique items.
|
||||
* Set properties represent an unbounded set of zero or more unique items
|
||||
* <p>
|
||||
* Sets may be typed or untyped. Within typed sets, all items MUST be the same type. The
|
||||
* type of items is specified via {@link Items}. Typed sets may be stored more efficiently
|
||||
* than untyped sets. When {@link Items} is unspecified, the set is untyped and its items
|
||||
* type of items is specified via {@link #items}. Typed sets may be stored more efficiently
|
||||
* than untyped sets. When {@link #items} is unspecified, the set is untyped and its items
|
||||
* may be heterogeneous.
|
||||
* <p>
|
||||
* Each item within a set must be unique. Uniqueness is defined by the HybridRow encoded sequence
|
||||
@@ -18,15 +18,14 @@ public class SetPropertyType extends ScopePropertyType {
|
||||
/**
|
||||
* (Optional) type of the elements of the set, if a typed set, otherwise null.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "items")] public PropertyType Items {get;set;}
|
||||
private PropertyType Items;
|
||||
private PropertyType items;
|
||||
|
||||
public final PropertyType getItems() {
|
||||
return Items;
|
||||
public final PropertyType items() {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
public final void setItems(PropertyType value) {
|
||||
Items = value;
|
||||
public final SetPropertyType items(PropertyType value) {
|
||||
this.items = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -6,45 +6,39 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
/**
|
||||
* Describes the sort order direction.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonConverter(typeof(StringEnumConverter), true)] public enum SortDirection
|
||||
public enum SortDirection {
|
||||
/**
|
||||
* Sorts from the lowest to the highest value.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [EnumMember(Value = "asc")] Ascending = 0,
|
||||
Ascending(0),
|
||||
|
||||
/**
|
||||
* Sorts from the highests to the lowest value.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [EnumMember(Value = "desc")] Descending,
|
||||
Descending(1);
|
||||
|
||||
public static final int SIZE = java.lang.Integer.SIZE;
|
||||
private static java.util.HashMap<Integer, SortDirection> mappings;
|
||||
private int intValue;
|
||||
private int value;
|
||||
|
||||
SortDirection(int value) {
|
||||
intValue = value;
|
||||
getMappings().put(value, this);
|
||||
this.value = value;
|
||||
mappings().put(value, this);
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return intValue;
|
||||
public int value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public static SortDirection forValue(int value) {
|
||||
return getMappings().get(value);
|
||||
return mappings().get(value);
|
||||
}
|
||||
|
||||
private static java.util.HashMap<Integer, SortDirection> getMappings() {
|
||||
private static java.util.HashMap<Integer, SortDirection> mappings() {
|
||||
if (mappings == null) {
|
||||
synchronized (SortDirection.class) {
|
||||
if (mappings == null) {
|
||||
mappings = new java.util.HashMap<Integer, SortDirection>();
|
||||
mappings = new java.util.HashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,23 +4,23 @@
|
||||
package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
/**
|
||||
* Describes a property or set of properties whose values MUST be the same for all rows that share the same partition
|
||||
* key.
|
||||
* Describes a property or property set whose values MUST be the same for all rows that share the same partition key
|
||||
*/
|
||||
public class StaticKey {
|
||||
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* The logical path of the referenced property.
|
||||
* The logical path of the referenced property
|
||||
* <p>
|
||||
* Static path MUST refer to properties defined within the same {@link Schema}.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "path", Required = Required.Always)] public string Path {get;set;}
|
||||
private String Path;
|
||||
|
||||
public final String getPath() {
|
||||
return Path;
|
||||
public final String path() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public final void setPath(String value) {
|
||||
Path = value;
|
||||
public final StaticKey path(String value) {
|
||||
this.path = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -6,63 +6,56 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
/**
|
||||
* Describes the storage placement for primitive properties.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonConverter(typeof(StringEnumConverter), true)] public enum StorageKind
|
||||
public enum StorageKind {
|
||||
/**
|
||||
* The property defines a sparse column.
|
||||
* The property defines a sparse column
|
||||
* <p>
|
||||
* Columns marked {@link Sparse} consume no space in the row when not present. When
|
||||
* present they appear in an unordered linked list at the end of the row. Access time for
|
||||
* {@link Sparse} columns is proportional to the number of {@link Sparse} columns in the
|
||||
* row.
|
||||
* Columns marked as sparse consume no space in the row when not present. When present they appear in an unordered
|
||||
* linked list at the end of the row. Access time for sparse columns is proportional to the number of sparse columns
|
||||
* in the row.
|
||||
*/
|
||||
Sparse(0),
|
||||
|
||||
/**
|
||||
* The property is a fixed-length, space-reserved column.
|
||||
* The property is a fixed-length, space-reserved column
|
||||
* <p>
|
||||
* The column will consume 1 null-bit, and its byte-width regardless of whether the value is
|
||||
* present in the row.
|
||||
* The column will consume 1 null-bit, and its byte-width regardless of whether the value is present in the row.
|
||||
*/
|
||||
Fixed(1),
|
||||
|
||||
/**
|
||||
* The property is a variable-length column.
|
||||
* <p>
|
||||
* The column will consume 1 null-bit regardless of whether the value is present. When the value is
|
||||
* present it will also consume a variable number of bytes to encode the length preceding the actual
|
||||
* value.
|
||||
* The column will consume 1 null-bit regardless of whether the value is present. When the value is present it will
|
||||
* also consume a variable number of bytes to encode the length preceding the actual value.
|
||||
* <p>
|
||||
* When a <em>long</em> value is marked {@link Variable} then a null-bit is reserved and
|
||||
* the value is optionally encoded as {@link Variable} if small enough to fit, otherwise the
|
||||
* null-bit is set and the value is encoded as {@link Sparse}.
|
||||
* </p>
|
||||
* When a <em>long</em> value is marked variable then a null-bit is reserved and the value is optionally encoded as
|
||||
* variable if small enough to fit, otherwise the null-bit is set and the value is encoded as sparse.
|
||||
*/
|
||||
Variable(2);
|
||||
|
||||
public static final int SIZE = java.lang.Integer.SIZE;
|
||||
private static java.util.HashMap<Integer, StorageKind> mappings;
|
||||
private int intValue;
|
||||
private int value;
|
||||
|
||||
StorageKind(int value) {
|
||||
intValue = value;
|
||||
getMappings().put(value, this);
|
||||
this.value = value;
|
||||
mappings().put(value, this);
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return intValue;
|
||||
public int value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public static StorageKind forValue(int value) {
|
||||
return getMappings().get(value);
|
||||
return mappings().get(value);
|
||||
}
|
||||
|
||||
private static java.util.HashMap<Integer, StorageKind> getMappings() {
|
||||
private static java.util.HashMap<Integer, StorageKind> mappings() {
|
||||
if (mappings == null) {
|
||||
synchronized (StorageKind.class) {
|
||||
if (mappings == null) {
|
||||
mappings = new java.util.HashMap<Integer, StorageKind>();
|
||||
mappings = new java.util.HashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,20 +4,22 @@
|
||||
package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tagged properties pair one or more typed values with an API-specific uint8 type code.
|
||||
* <p>
|
||||
* The uint8 type code is implicitly in position 0 within the resulting tagged and should not
|
||||
* be specified in {@link Items}.
|
||||
* The {@code UInt8} type code is implicitly in position 0 within the resulting tagged and should not be specified in
|
||||
* {@link #items}.
|
||||
*/
|
||||
public class TaggedPropertyType extends ScopePropertyType {
|
||||
|
||||
public static final int MaxTaggedArguments = 2;
|
||||
public static final int MinTaggedArguments = 1;
|
||||
/**
|
||||
* Types of the elements of the tagged in element order.
|
||||
*/
|
||||
private ArrayList<PropertyType> items;
|
||||
private List<PropertyType> items;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link TaggedPropertyType} class.
|
||||
@@ -28,14 +30,14 @@ public class TaggedPropertyType extends ScopePropertyType {
|
||||
|
||||
/**
|
||||
* Types of the elements of the tagged in element order.
|
||||
* @return
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "items")] public List<PropertyType> Items
|
||||
public final ArrayList<PropertyType> getItems() {
|
||||
public final List<PropertyType> items() {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
public final void setItems(ArrayList<PropertyType> value) {
|
||||
this.items = value != null ? value : new ArrayList<PropertyType>();
|
||||
public final TaggedPropertyType items(List<PropertyType> value) {
|
||||
this.items = value != null ? value : new ArrayList<>();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tuple properties represent a typed, finite, ordered set of two or more items.
|
||||
@@ -12,7 +13,7 @@ public class TuplePropertyType extends ScopePropertyType {
|
||||
/**
|
||||
* Types of the elements of the tuple in element order.
|
||||
*/
|
||||
private ArrayList<PropertyType> items;
|
||||
private List<PropertyType> items;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link TuplePropertyType} class.
|
||||
@@ -23,14 +24,15 @@ public class TuplePropertyType extends ScopePropertyType {
|
||||
|
||||
/**
|
||||
* Types of the elements of the tuple in element order.
|
||||
* @return
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "items")] public List<PropertyType> Items
|
||||
public final ArrayList<PropertyType> getItems() {
|
||||
public final List<PropertyType> 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>();
|
||||
}
|
||||
}
|
||||
@@ -13,46 +13,46 @@ import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
|
||||
* all outer schemas where the UDT is used.
|
||||
*/
|
||||
public class UdtPropertyType extends ScopePropertyType {
|
||||
|
||||
private String name;
|
||||
private SchemaId schemaId;
|
||||
|
||||
/**
|
||||
* Initializes a new {@link UdtPropertyType}
|
||||
*/
|
||||
public UdtPropertyType() {
|
||||
this.schemaId(SchemaId.INVALID);
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier of the UDT schema defining the structure for the nested row.
|
||||
* <p>
|
||||
* The UDT schema MUST be defined within the same {@link Namespace} as the schema that
|
||||
* references it.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "name", Required = Required.Always)] public string Name {get;set;}
|
||||
private String Name;
|
||||
public final String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public final void name(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The unique identifier for a schema.
|
||||
* <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>
|
||||
* 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.
|
||||
* </p>
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [JsonProperty(PropertyName = "id", Required = Required.DisallowNull, DefaultValueHandling =
|
||||
// DefaultValueHandling.IgnoreAndPopulate)] public SchemaId SchemaId {get;set;}
|
||||
private com.azure.data.cosmos.serialization.hybridrow.SchemaId SchemaId = new SchemaId();
|
||||
|
||||
public UdtPropertyType() {
|
||||
this.setSchemaId(com.azure.data.cosmos.serialization.hybridrow.SchemaId.INVALID);
|
||||
public final SchemaId schemaId() {
|
||||
return this.schemaId;
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
return Name;
|
||||
}
|
||||
|
||||
public final void setName(String value) {
|
||||
Name = value;
|
||||
}
|
||||
|
||||
public final SchemaId getSchemaId() {
|
||||
return SchemaId;
|
||||
}
|
||||
|
||||
public final void setSchemaId(SchemaId value) {
|
||||
SchemaId = value.clone();
|
||||
public final UdtPropertyType schemaId(SchemaId value) {
|
||||
this.schemaId = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user