mirror of
https://github.com/microsoft/HybridRow.git
synced 2026-01-20 01:43:20 +00:00
Renamed jre as java because Java is used to can refer to two things: the platform and the language. In this case we are referring to the Java Platform, not the Java Runtime Environment.
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.core;
|
||||
|
||||
public class Codecs {
|
||||
}
|
||||
27
java/src/main/java/com/azure/data/cosmos/core/Json.java
Normal file
27
java/src/main/java/com/azure/data/cosmos/core/Json.java
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.core;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
|
||||
import static com.google.common.base.Strings.lenientFormat;
|
||||
|
||||
public final class Json {
|
||||
|
||||
private static final ObjectMapper mapper = new ObjectMapper();
|
||||
private static final ObjectWriter writer = mapper.writer();
|
||||
|
||||
private Json() {
|
||||
}
|
||||
|
||||
public static String toString(Object object) {
|
||||
try {
|
||||
return writer.writeValueAsString(object);
|
||||
} catch (JsonProcessingException error) {
|
||||
return lenientFormat("{\"error\": \"%s\"}", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
84
java/src/main/java/com/azure/data/cosmos/core/Out.java
Normal file
84
java/src/main/java/com/azure/data/cosmos/core/Out.java
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.core;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A container object which may or may not contain a non-null value
|
||||
*
|
||||
* This is a value-based class and as such use of identity-sensitive operations--including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization--on instances of {@Out} may have unpredictable results and
|
||||
* should be avoided.
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public final class Out<T> {
|
||||
|
||||
private volatile T value;
|
||||
|
||||
public T get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void set(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public T setAndGet(T value) {
|
||||
return this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code true} if there is a value present, otherwise {@code false}
|
||||
* <p>
|
||||
* This is equivalent to evaluating the expression {@code out.get() == null}.
|
||||
*
|
||||
* @return {@code true} if there is a value present, otherwise {@code false}
|
||||
*/
|
||||
public boolean isPresent() {
|
||||
return value != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether some other object is equal to this {@link Out} value. The other object is considered equal if:
|
||||
* <ul>
|
||||
* <li>it is also an {@link Out} and;
|
||||
* <li>both instances have no value present or;
|
||||
* <li>the present values are equal to each other as determined by {@link T#equals(Object)}}.
|
||||
* </ul>
|
||||
*
|
||||
* @param other an object to be tested for equality
|
||||
* @return {code true} if the other object is equal to this object; otherwise {@code false}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(other instanceof Out)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Objects.equals(value, ((Out)other).value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value of the present value, if any, or 0 (zero) if
|
||||
* no value is present.
|
||||
*
|
||||
* @return hash code value of the present value or 0 if no value is present
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value == null ? "null" : value.toString();
|
||||
}
|
||||
}
|
||||
77
java/src/main/java/com/azure/data/cosmos/core/Reference.java
Normal file
77
java/src/main/java/com/azure/data/cosmos/core/Reference.java
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.core;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A container object which may or may not contain a non-null value
|
||||
*
|
||||
* This is a value-based class and as such use of identity-sensitive operations--including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization--on instances of {@Reference} may have unpredictable results
|
||||
* and should be avoided.
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public final class Reference<T> {
|
||||
|
||||
private volatile T value;
|
||||
|
||||
public Reference(T value) {
|
||||
this.setAndGet(value);
|
||||
}
|
||||
|
||||
public T get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void set(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
public T setAndGet(T value) {
|
||||
return this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code true} if there is a value present, otherwise {@code false}
|
||||
*
|
||||
* This is equivalent to evaluating the expression {@code ref.get() == null}.
|
||||
*
|
||||
* @return {@code true} if there is a value present, otherwise {@code false}
|
||||
*/
|
||||
public boolean isPresent() {
|
||||
return value != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether some other object is equal to this {@link Reference} value. The other object is considered equal if:
|
||||
* <ul>
|
||||
* <li>it is also an {@link Reference} and;
|
||||
* <li>both instances have no value present or;
|
||||
* <li>the present values are equal to each other as determined by {@link T#equals(Object)}}.
|
||||
* </ul>
|
||||
*
|
||||
* @param other an object to be tested for equality
|
||||
* @return {code true} if the other object is equal to this object; otherwise {@code false}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(other instanceof Reference)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Objects.equals(value, ((Reference)other).value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value == null ? "null" : value.toString();
|
||||
}
|
||||
}
|
||||
488
java/src/main/java/com/azure/data/cosmos/core/Utf8String.java
Normal file
488
java/src/main/java/com/azure/data/cosmos/core/Utf8String.java
Normal file
@@ -0,0 +1,488 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.core;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeType;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
import com.google.common.base.Utf8;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Optional;
|
||||
import java.util.Spliterator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
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 static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
@JsonSerialize(using = Utf8String.JsonSerializer.class)
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public final class Utf8String implements CharSequence, Comparable<Utf8String> {
|
||||
|
||||
public static final Utf8String EMPTY = new Utf8String(Unpooled.EMPTY_BUFFER, 0);
|
||||
public static final Utf8String NULL = new Utf8String();
|
||||
|
||||
private final ByteBuf buffer;
|
||||
private final int length;
|
||||
|
||||
private Utf8String() {
|
||||
this.buffer = null;
|
||||
this.length = -1;
|
||||
}
|
||||
|
||||
private Utf8String(@Nonnull final ByteBuf buffer) {
|
||||
this(buffer, decodedLength(buffer));
|
||||
}
|
||||
|
||||
private Utf8String(@Nonnull final ByteBuf buffer, final int decodedLength) {
|
||||
checkNotNull(buffer);
|
||||
this.buffer = buffer.asReadOnly();
|
||||
this.length = decodedLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code true} if the length of this instance is zero
|
||||
*/
|
||||
public final boolean isEmpty() {
|
||||
return this.length == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code true} if this instance is null
|
||||
*/
|
||||
public final boolean isNull() {
|
||||
return this.buffer == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char charAt(final int index) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-allocating enumeration of each character in the UTF-8 stream
|
||||
*/
|
||||
@Override
|
||||
public IntStream chars() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-allocating enumeration of each code point in the UTF-8 stream
|
||||
*/
|
||||
public final IntStream codePoints() {
|
||||
if (this.length == 0) {
|
||||
return IntStream.empty();
|
||||
}
|
||||
return StreamSupport.intStream(new CodePointIterable(this.buffer, this.length), false);
|
||||
}
|
||||
|
||||
public final int compareTo(@Nonnull final Utf8String other) {
|
||||
|
||||
checkNotNull(other);
|
||||
|
||||
if (other.buffer == this.buffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (other.buffer == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (this.buffer == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return this.buffer.compareTo(other.buffer);
|
||||
}
|
||||
|
||||
public final int compareTo(final String other) {
|
||||
|
||||
if (this.buffer == null) {
|
||||
return other == null ? 0 : -1;
|
||||
}
|
||||
|
||||
final int length = this.length();
|
||||
final int otherLength = other.length();
|
||||
final int limit = Math.min(length, otherLength);
|
||||
|
||||
if (limit > 0) {
|
||||
|
||||
final CodePointIterable iterable = new CodePointIterable(this.buffer, this.length);
|
||||
int index = 0;
|
||||
|
||||
for (int codePoint : iterable) {
|
||||
|
||||
final int otherCodePoint = other.codePointAt(index++);
|
||||
|
||||
if (codePoint != otherCodePoint) {
|
||||
return codePoint - otherCodePoint;
|
||||
}
|
||||
|
||||
if (index >= limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return length - otherLength;
|
||||
}
|
||||
|
||||
public final boolean equals(ByteBuf other) {
|
||||
return this.buffer.equals(other);
|
||||
}
|
||||
|
||||
public final boolean equals(String other) {
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
return this.compareTo(other) == 0;
|
||||
}
|
||||
|
||||
public final boolean equals(Utf8String other) {
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
return this.buffer.equals(other.buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
if (other instanceof ByteBuf) {
|
||||
return this.equals((ByteBuf)other);
|
||||
}
|
||||
if (other instanceof String) {
|
||||
return this.equals((String)other);
|
||||
}
|
||||
if (other instanceof Utf8String) {
|
||||
return this.equals((Utf8String)other);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.buffer.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of this character sequence
|
||||
* <p>
|
||||
* The length is the number of Unicode characters in the sequence.
|
||||
*/
|
||||
public final int length() {
|
||||
return this.length;
|
||||
}
|
||||
|
||||
public static boolean opEquals(Utf8String left, Utf8String right) {
|
||||
if (null == left) {
|
||||
return null == right;
|
||||
}
|
||||
return left.equals(right);
|
||||
}
|
||||
|
||||
public static boolean opGreaterThan(Utf8String left, Utf8String right) {
|
||||
return left != null && left.compareTo(right) > 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThan(Utf8String left, String right) {
|
||||
return left != null && left.compareTo(right) > 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThan(String left, Utf8String right) {
|
||||
return right == null || right.compareTo(left) <= 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThanOrEquals(Utf8String left, Utf8String right) {
|
||||
return left == null ? right == null : left.compareTo(right) >= 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThanOrEquals(Utf8String left, String right) {
|
||||
return left == null ? right == null : left.compareTo(right) >= 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThanOrEquals(String left, Utf8String right) {
|
||||
return right == null ? left != null : right.compareTo(left) < 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThan(Utf8String left, Utf8String right) {
|
||||
return left == null ? right != null : left.compareTo(right) < 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThan(Utf8String left, String right) {
|
||||
return left == null ? right != null : left.compareTo(right) < 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThan(String left, Utf8String right) {
|
||||
return right == null ? left == null : right.compareTo(left) >= 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThanOrEquals(Utf8String left, Utf8String right) {
|
||||
return left == null || left.compareTo(right) <= 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThanOrEquals(Utf8String left, String right) {
|
||||
return left == null || left.compareTo(right) <= 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThanOrEquals(String left, Utf8String right) {
|
||||
return right != null && right.compareTo(left) > 0;
|
||||
}
|
||||
|
||||
public static boolean opNotEquals(Utf8String left, Utf8String right) {
|
||||
if (null == left) {
|
||||
return null != right;
|
||||
}
|
||||
return !left.equals(right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
checkArgument(start < 0 || end < 0 || start > end || end > this.length, "start: %s, end: %s", start, end);
|
||||
// TODO: DANOBLE: compute buffer index for start and end character positions and use them in the slice
|
||||
return new Utf8String(this.buffer.slice(), end - start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.buffer.getCharSequence(0, this.buffer.capacity(), UTF_8).toString();
|
||||
}
|
||||
|
||||
public String toUtf16() {
|
||||
return this.buffer.getCharSequence(0, this.buffer.capacity(), UTF_8).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Utf8String} from a UTF16 encoding string.
|
||||
*
|
||||
* @param string The UTF16 encoding string.
|
||||
* @return A new {@link Utf8String}.
|
||||
* <p>
|
||||
* This method must transcode the UTF-16 into UTF-8 which both requires allocation and is a size of data operation.
|
||||
*/
|
||||
public static Utf8String transcodeUtf16(final String string) {
|
||||
|
||||
if (string == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (string.isEmpty()) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
final int length = Utf8.encodedLength(string);
|
||||
final ByteBuf buffer = Unpooled.wrappedBuffer(new byte[length]);
|
||||
final int count = buffer.writeCharSequence(string, UTF_8);
|
||||
|
||||
checkState(count == length, "count: %s, length: %s", count, length);
|
||||
|
||||
return new Utf8String(buffer, string.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the contents of a byte buffer to prove it contains a valid UTF-8 character sequence
|
||||
*
|
||||
* @param buffer The byte buffer to validate
|
||||
* @return A {@link Utf8String} instance, if the @{code buffer} validates or a value of @{link Optional#empty}
|
||||
* otherwise.
|
||||
*/
|
||||
public static Optional<Utf8String> tryParseUtf8Bytes(@Nonnull final ByteBuf buffer) {
|
||||
checkNotNull(buffer);
|
||||
return Utf8.isWellFormed(buffer.array()) ? Optional.of(new Utf8String(buffer)) : Optional.empty();
|
||||
}
|
||||
|
||||
private static int decodedLength(final ByteBuf buffer) {
|
||||
|
||||
final CodePointIterable iterable = new CodePointIterable(buffer, -1);
|
||||
int decodedLength = 0;
|
||||
|
||||
for (int ignored : iterable) {
|
||||
decodedLength++;
|
||||
}
|
||||
|
||||
return decodedLength;
|
||||
}
|
||||
|
||||
private static final class CodePointIterable implements Iterable<Integer>, Iterator<Integer>, Spliterator.OfInt {
|
||||
|
||||
private static final int CHARACTERISTICS = Spliterator.IMMUTABLE | Spliterator.NONNULL | Spliterator.ORDERED;
|
||||
|
||||
private final ByteBuf buffer;
|
||||
private final int length;
|
||||
private int index;
|
||||
|
||||
public CodePointIterable(final ByteBuf buffer, final int length) {
|
||||
this.buffer = buffer;
|
||||
this.length = length;
|
||||
this.index = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int characteristics() {
|
||||
return this.length == -1 ? CHARACTERISTICS : CHARACTERISTICS | Spliterator.SIZED | Spliterator.SUBSIZED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long estimateSize() {
|
||||
return this.length < 0 ? Long.MAX_VALUE : this.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachRemaining(final Consumer<? super Integer> action) {
|
||||
OfInt.super.forEachRemaining(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return this.index < this.buffer.capacity();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public Iterator<Integer> iterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer next() {
|
||||
|
||||
if (!this.hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
final int leadingByte = this.buffer.getByte(this.index++) & 0xFF;
|
||||
|
||||
// A 1-byte UTF-8 code point is a special case that covers the 7-bit ASCII character set
|
||||
|
||||
if (leadingByte < 0x80) {
|
||||
return leadingByte;
|
||||
}
|
||||
|
||||
// The initial byte of 2-, 3- and 4-byte UTF-8 code points start with 2, 3, or 4 one bits followed by a 0
|
||||
// bit
|
||||
|
||||
final int codePoint;
|
||||
|
||||
if ((leadingByte & 0b1110_0000) == 0b1100_0000) {
|
||||
|
||||
// 110xxxxx 10xxxxxx => 0x00000080 - 0x000007FF
|
||||
|
||||
codePoint = ((leadingByte & 0b0001_1111) << 6) |
|
||||
(this.buffer.getByte(this.index++) & 0b0011_1111);
|
||||
|
||||
} else if ((leadingByte & 0b1111_0000) == 0b1110_0000) {
|
||||
|
||||
// 1110xxxx 10xxxxxx 10xxxxxx => 0x00000800 - 0x0000FFFF
|
||||
|
||||
codePoint = ((leadingByte & 0b0000_1111) << 12) |
|
||||
((this.buffer.getByte(this.index++) & 0b0011_1111) << 6) |
|
||||
((this.buffer.getByte(this.index++) & 0b0011_1111));
|
||||
|
||||
} else if ((leadingByte & 0b1111_1000) == 0b1111_0000) {
|
||||
|
||||
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx => 0x00010000 - 0x001FFFFF
|
||||
|
||||
codePoint = ((leadingByte & 0b0000_0111) << 18) |
|
||||
((this.buffer.getByte(this.index++) & 0b0011_1111) << 12) |
|
||||
((this.buffer.getByte(this.index++) & 0b0011_1111) << 6) |
|
||||
((this.buffer.getByte(this.index++) & 0b0011_1111));
|
||||
|
||||
} else {
|
||||
// leading byte is improperly encoded and we'll detect that before returning
|
||||
codePoint = leadingByte;
|
||||
}
|
||||
|
||||
checkState(Character.isDefined(codePoint), "invalid character: %s", codePoint);
|
||||
return codePoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<Integer> spliterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdvance(@Nonnull final IntConsumer action) {
|
||||
|
||||
checkNotNull(action);
|
||||
|
||||
if (this.hasNext()) {
|
||||
action.accept(this.next());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OfInt trySplit() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static final class Deserializer extends StdDeserializer<Utf8String> {
|
||||
|
||||
private Deserializer() {
|
||||
super(Utf8String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8String deserialize(JsonParser parser, DeserializationContext context) throws IOException {
|
||||
|
||||
final JsonNode node = parser.getCodec().readTree(parser);
|
||||
final JsonNodeType type = node.getNodeType();
|
||||
|
||||
switch (type) {
|
||||
case STRING:
|
||||
return Utf8String.transcodeUtf16(node.textValue());
|
||||
case NULL:
|
||||
return null;
|
||||
default: {
|
||||
String message = lenientFormat("expected string value or null, not %s", type.name().toLowerCase());
|
||||
throw new JsonParseException(parser, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static final class JsonSerializer extends StdSerializer<Utf8String> {
|
||||
|
||||
private JsonSerializer() {
|
||||
super(Utf8String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Utf8String value, JsonGenerator generator, SerializerProvider provider) throws IOException {
|
||||
generator.writeString(value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
417
java/src/main/java/com/azure/data/cosmos/core/UtfAnyString.java
Normal file
417
java/src/main/java/com/azure/data/cosmos/core/UtfAnyString.java
Normal file
@@ -0,0 +1,417 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.core;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static com.azure.data.cosmos.core.Utf8String.transcodeUtf16;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* A string whose memory representation may be either UTF-8 or UTF-16
|
||||
* <p>
|
||||
* This type supports polymorphic use of {@link String} and {@link Utf8String} when equality, hashing, and comparison
|
||||
* are needed against either encoding. An API leveraging {@link UtfAnyString} can avoid separate method overloads
|
||||
* while still accepting either encoding without imposing additional allocations.
|
||||
*/
|
||||
public final class UtfAnyString implements CharSequence, Comparable<UtfAnyString> {
|
||||
|
||||
private static final UtfAnyString EMPTY = new UtfAnyString("");
|
||||
private static final int NULL_HASHCODE = reduceHashCode(5_381, 5_381);
|
||||
|
||||
private CharSequence buffer;
|
||||
|
||||
public UtfAnyString() {
|
||||
}
|
||||
|
||||
public UtfAnyString(final String string) {
|
||||
this.buffer = string;
|
||||
}
|
||||
|
||||
public UtfAnyString(final Utf8String utf8String) {
|
||||
this.buffer = utf8String;
|
||||
}
|
||||
|
||||
private UtfAnyString(final CharSequence sequence) {
|
||||
this.buffer = sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code true} if the {@link UtfAnyString} is empty
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return this.buffer != null && this.buffer.length() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code true} if the {@link UtfAnyString} is {@code null}
|
||||
*/
|
||||
public boolean isNull() {
|
||||
return null == this.buffer;
|
||||
}
|
||||
|
||||
public boolean isUtf16() {
|
||||
return this.buffer instanceof String;
|
||||
}
|
||||
|
||||
public boolean isUtf8() {
|
||||
return this.buffer instanceof Utf8String;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code char} value at the specified {@code index}
|
||||
* <p>
|
||||
* An index ranges from zero to {@link UtfAnyString#length()} minus one. The first {@code char} value of the
|
||||
* sequence is at index zero, the next at index one, and so on, as for array indexing. If the {@code char}
|
||||
* value specified by the {@code index} is a surrogate, the surrogate (not the surrogate pair) is returned.
|
||||
*
|
||||
* @param index the index of the {@code char} value to be returned
|
||||
* @return the specified {@code char} value
|
||||
* @throws IndexOutOfBoundsException if the {@code index} argument is negative or not less than
|
||||
* {@link UtfAnyString#length()}
|
||||
* @throws UnsupportedOperationException if this {@link UtfAnyString} is {@code null}.
|
||||
*/
|
||||
@Override
|
||||
public char charAt(final int index) {
|
||||
if (this.buffer == null) {
|
||||
throw new UnsupportedOperationException("String is null");
|
||||
}
|
||||
return this.buffer.charAt(index);
|
||||
}
|
||||
|
||||
public UtfAnyString clone() {
|
||||
return new UtfAnyString(this.buffer);
|
||||
}
|
||||
|
||||
public int compareTo(@Nonnull final String other) {
|
||||
|
||||
checkNotNull(other);
|
||||
|
||||
if (other == this.buffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this.buffer == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return this.buffer instanceof String
|
||||
? ((String) this.buffer).compareTo(other)
|
||||
: ((Utf8String) this.buffer).compareTo(other);
|
||||
}
|
||||
|
||||
public int compareTo(@Nonnull final Utf8String other) {
|
||||
|
||||
checkNotNull(other);
|
||||
|
||||
if (other == this.buffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this.buffer == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return this.buffer instanceof String
|
||||
? -other.compareTo((String) this.buffer)
|
||||
: ((Utf8String) this.buffer).compareTo(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull final UtfAnyString other) {
|
||||
|
||||
checkNotNull(other);
|
||||
|
||||
if (other.buffer == this.buffer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (other.buffer == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (this.buffer == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (this.buffer instanceof String) {
|
||||
return other.buffer instanceof String
|
||||
? ((String) this.buffer).compareTo((String) other.buffer)
|
||||
: -((Utf8String) other.buffer).compareTo((String) this.buffer);
|
||||
}
|
||||
|
||||
return ((Utf8String) this.buffer).compareTo((Utf8String) other.buffer);
|
||||
}
|
||||
|
||||
public static UtfAnyString empty() {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (other instanceof String) {
|
||||
return this.equals((String) other);
|
||||
}
|
||||
|
||||
if (other instanceof Utf8String) {
|
||||
return this.equals((Utf8String) other);
|
||||
}
|
||||
|
||||
if (other instanceof UtfAnyString) {
|
||||
return this.equals((UtfAnyString) other);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean equals(final String other) {
|
||||
|
||||
if (null == this.buffer) {
|
||||
return null == other;
|
||||
}
|
||||
|
||||
if (this.buffer instanceof String) {
|
||||
return other.contentEquals(this.buffer); // skips the type check that String.equals performs
|
||||
}
|
||||
|
||||
return ((Utf8String) this.buffer).equals(other);
|
||||
}
|
||||
|
||||
public boolean equals(final Utf8String other) {
|
||||
|
||||
if (null == other) {
|
||||
return null == this.buffer;
|
||||
}
|
||||
|
||||
return other.equals(this.buffer);
|
||||
}
|
||||
|
||||
public boolean equals(final UtfAnyString other) {
|
||||
|
||||
if (null == other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null == this.buffer) {
|
||||
return null == other.buffer;
|
||||
}
|
||||
|
||||
return this.buffer instanceof String ? other.buffer.equals(this.buffer) : this.buffer.equals(other.buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
final long[] hash = { 5_381, 5_381 };
|
||||
|
||||
if (this.buffer == null) {
|
||||
return NULL_HASHCODE;
|
||||
}
|
||||
|
||||
if (this.buffer instanceof String) {
|
||||
|
||||
final int ignored = ((String) buffer).codePoints().reduce(0, (index, codePoint) -> {
|
||||
if (index % 2 == 0) {
|
||||
hash[0] = ((hash[0] << 5) + hash[0]) ^ codePoint;
|
||||
} else {
|
||||
hash[1] = ((hash[1] << 5) + hash[1]) ^ codePoint;
|
||||
}
|
||||
return index;
|
||||
});
|
||||
|
||||
return reduceHashCode(hash[0], hash[1]);
|
||||
}
|
||||
|
||||
return this.buffer.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of this character sequence. The length is the number
|
||||
* of 16-bit {@code char}s in the sequence.
|
||||
*
|
||||
* @return the number of {@code char}s in this sequence
|
||||
*
|
||||
* @throws UnsupportedOperationException if this {@link UtfAnyString} is {@code null}
|
||||
*/
|
||||
@Override
|
||||
public int length() {
|
||||
if (this.buffer == null) {
|
||||
throw new UnsupportedOperationException("String is null");
|
||||
}
|
||||
return this.buffer.length();
|
||||
}
|
||||
|
||||
public static boolean opEquals(UtfAnyString left, UtfAnyString right) {
|
||||
return left.equals(right.clone());
|
||||
}
|
||||
|
||||
public static boolean opEquals(UtfAnyString left, String right) {
|
||||
return left.equals(right);
|
||||
}
|
||||
|
||||
public static boolean opEquals(String left, UtfAnyString right) {
|
||||
return right.equals(left);
|
||||
}
|
||||
|
||||
public static boolean opEquals(UtfAnyString left, Utf8String right) {
|
||||
return left.equals(right);
|
||||
}
|
||||
|
||||
public static boolean opEquals(Utf8String left, UtfAnyString right) {
|
||||
return right.equals(left);
|
||||
}
|
||||
|
||||
public static boolean opGreaterThan(UtfAnyString left, UtfAnyString right) {
|
||||
return left.compareTo(right.clone()) > 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThan(UtfAnyString left, String right) {
|
||||
return left.compareTo(right) > 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThan(String left, UtfAnyString right) {
|
||||
return right.compareTo(left) <= 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThan(UtfAnyString left, Utf8String right) {
|
||||
return left.compareTo(right) > 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThan(Utf8String left, UtfAnyString right) {
|
||||
return right.compareTo(left) <= 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThanOrEquals(UtfAnyString left, UtfAnyString right) {
|
||||
return left.compareTo(right.clone()) >= 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThanOrEquals(UtfAnyString left, String right) {
|
||||
return left.compareTo(right) >= 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThanOrEquals(String left, UtfAnyString right) {
|
||||
return right.compareTo(left) < 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThanOrEquals(UtfAnyString left, Utf8String right) {
|
||||
return left.compareTo(right) >= 0;
|
||||
}
|
||||
|
||||
public static boolean opGreaterThanOrEquals(Utf8String left, UtfAnyString right) {
|
||||
return right.compareTo(left) < 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThan(UtfAnyString left, UtfAnyString right) {
|
||||
return left.compareTo(right.clone()) < 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThan(UtfAnyString left, String right) {
|
||||
return left.compareTo(right) < 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThan(String left, UtfAnyString right) {
|
||||
return right.compareTo(left) >= 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThan(UtfAnyString left, Utf8String right) {
|
||||
return left.compareTo(right) < 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThan(Utf8String left, UtfAnyString right) {
|
||||
return right.compareTo(left) >= 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThanOrEquals(UtfAnyString left, UtfAnyString right) {
|
||||
return left.compareTo(right.clone()) <= 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThanOrEquals(UtfAnyString left, String right) {
|
||||
return left.compareTo(right) <= 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThanOrEquals(String left, UtfAnyString right) {
|
||||
return right.compareTo(left) > 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThanOrEquals(UtfAnyString left, Utf8String right) {
|
||||
return left.compareTo(right) <= 0;
|
||||
}
|
||||
|
||||
public static boolean opLessThanOrEquals(Utf8String left, UtfAnyString right) {
|
||||
return right.compareTo(left) > 0;
|
||||
}
|
||||
|
||||
public static boolean opNotEquals(UtfAnyString left, UtfAnyString right) {
|
||||
return !left.equals(right.clone());
|
||||
}
|
||||
|
||||
public static boolean opNotEquals(UtfAnyString left, String right) {
|
||||
return !left.equals(right);
|
||||
}
|
||||
|
||||
public static boolean opNotEquals(String left, UtfAnyString right) {
|
||||
return !right.equals(left);
|
||||
}
|
||||
|
||||
public static boolean opNotEquals(UtfAnyString left, Utf8String right) {
|
||||
return !left.equals(right);
|
||||
}
|
||||
|
||||
public static boolean opNotEquals(Utf8String left, UtfAnyString right) {
|
||||
return !right.equals(left);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code CharSequence} that is a subsequence of this sequence
|
||||
* <p>
|
||||
* The subsequence starts with the {@code char} value at the specified index and ends with the{@code char} value at
|
||||
* index {@code end - 1}. The length (in {@code char}s) of the returned sequence is {@code end - start}, so if
|
||||
* {@code start == end}, an empty sequence is returned.
|
||||
*
|
||||
* @param start the start index, inclusive
|
||||
* @param end the end index, exclusive
|
||||
* @return the specified subsequence
|
||||
* @throws IndexOutOfBoundsException if {@code start} or {@code end} are negative, {@code end} is greater than
|
||||
* {@link UtfAnyString#length()}, or {@code start} is greater than {@code
|
||||
* end}.
|
||||
* @throws UnsupportedOperationException if string is {@code null}
|
||||
*/
|
||||
@Override
|
||||
@Nonnull
|
||||
public CharSequence subSequence(final int start, final int end) {
|
||||
if (this.buffer == null) {
|
||||
throw new UnsupportedOperationException("String is null");
|
||||
}
|
||||
return this.buffer.subSequence(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public String toString() {
|
||||
return String.valueOf(this.buffer);
|
||||
}
|
||||
|
||||
public String toUtf16() {
|
||||
if (null == this.buffer) {
|
||||
return null;
|
||||
}
|
||||
return this.buffer instanceof String ? (String) this.buffer : this.buffer.toString();
|
||||
}
|
||||
|
||||
public Utf8String toUtf8() {
|
||||
if (null == this.buffer) {
|
||||
return null;
|
||||
}
|
||||
return this.buffer instanceof String ? transcodeUtf16((String) this.buffer) : (Utf8String) this.buffer;
|
||||
}
|
||||
|
||||
private static int reduceHashCode(final long h1, final long h2) {
|
||||
return Long.valueOf(h1 + (h2 * 1_566_083_941L)).intValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow;
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java:
|
||||
///#pragma warning disable CA1051 // Do not declare visible instance fields
|
||||
|
||||
|
||||
/**
|
||||
* An IEEE 128-bit floating point value.
|
||||
* <p>
|
||||
* A binary integer decimal representation of a 128-bit decimal value, supporting 34 decimal digits of
|
||||
* significand and an exponent range of -6143 to +6144.
|
||||
* <list type="table">
|
||||
* <listheader>
|
||||
* <term>Source</term> <description>Link</description>
|
||||
* </listheader> <item>
|
||||
* <term>Wikipedia:</term>
|
||||
* <description>https: //en.wikipedia.org/wiki/Decimal128_floating-point_format</description>
|
||||
* </item> <item>
|
||||
* <term>The spec:</term> <description>https: //ieeexplore.ieee.org/document/4610935</description>
|
||||
* </item> <item>
|
||||
* <term>Decimal Encodings:</term> <description>http: //speleotrove.com/decimal/decbits.html</description>
|
||||
* </item>
|
||||
* </list>
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [DebuggerDisplay("{" + nameof(Float128.Low) + "," + nameof(Float128.High) + "}")][StructLayout
|
||||
// (LayoutKind.Sequential, Pack = 1)] public readonly struct Float128
|
||||
//C# TO JAVA CONVERTER WARNING: Java does not allow user-defined value types. The behavior of this class may differ
|
||||
// from the original:
|
||||
//ORIGINAL LINE: [DebuggerDisplay("{" + nameof(Float128.Low) + "," + nameof(Float128.High) + "}")][StructLayout
|
||||
// (LayoutKind.Sequential, Pack = 1)] public readonly struct Float128
|
||||
//C# TO JAVA CONVERTER WARNING: Java has no equivalent to the C# readonly struct:
|
||||
public final class Float128 {
|
||||
/**
|
||||
* The size (in bytes) of a {@link Float128}.
|
||||
*/
|
||||
public static final int Size = (Long.SIZE / Byte.SIZE) + (Long.SIZE / Byte.SIZE);
|
||||
|
||||
private final long high;
|
||||
private final long low;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link Float128} struct.
|
||||
*
|
||||
* @param high the high-order 64 bits.
|
||||
* @param low the low-order 64 bits.
|
||||
*/
|
||||
public Float128(long high, long low) {
|
||||
this.high = high;
|
||||
this.low = low;
|
||||
}
|
||||
|
||||
/**
|
||||
* The high-order 64 bits of the IEEE 754-2008 128-bit decimal floating point, using the BID
|
||||
* encoding scheme.
|
||||
*/
|
||||
public long high() {
|
||||
return this.high;
|
||||
}
|
||||
|
||||
/**
|
||||
* The low-order 64 bits of the IEEE 754-2008 128-bit decimal floating point, using the BID
|
||||
* encoding scheme.
|
||||
*/
|
||||
public long low() {
|
||||
return this.low;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow;
|
||||
|
||||
/**
|
||||
* Describes the header that precedes all valid Hybrid Rows.
|
||||
*/
|
||||
public final class HybridRowHeader {
|
||||
/**
|
||||
* Size (in bytes) of a serialized header.
|
||||
*/
|
||||
public static final int SIZE = (HybridRowVersion.SIZE / Byte.SIZE) + SchemaId.SIZE;
|
||||
|
||||
private SchemaId schemaId;
|
||||
private HybridRowVersion version = HybridRowVersion.values()[0];
|
||||
|
||||
/**
|
||||
* Initializes a new instance of a {@link HybridRowHeader}
|
||||
*
|
||||
* @param version The version of the HybridRow library used to write this row.
|
||||
* @param schemaId The unique identifier of the schema whose layout was used to write this row.
|
||||
*/
|
||||
public HybridRowHeader(HybridRowVersion version, SchemaId schemaId) {
|
||||
this.version = version;
|
||||
this.schemaId = SchemaId.from(schemaId.value());
|
||||
}
|
||||
|
||||
/**
|
||||
* The unique identifier of the schema whose layout was used to write this row.
|
||||
*/
|
||||
public SchemaId schemaId() {
|
||||
return this.schemaId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The version of the HybridRow library used to write this row.
|
||||
*/
|
||||
public HybridRowVersion version() {
|
||||
return this.version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Versions of HybridRow
|
||||
* <p>
|
||||
* A version from this list MUST be inserted in the version BOM at the beginning of all rows.
|
||||
*/
|
||||
public enum HybridRowVersion {
|
||||
|
||||
Invalid((byte)0),
|
||||
|
||||
/**
|
||||
* Initial version of the HybridRow format.
|
||||
*/
|
||||
V1((byte)0x81);
|
||||
|
||||
public static final int SIZE = java.lang.Byte.SIZE;
|
||||
private static java.util.HashMap<Byte, HybridRowVersion> mappings;
|
||||
private byte value;
|
||||
|
||||
HybridRowVersion(byte value) {
|
||||
this.value = value;
|
||||
getMappings().put(value, this);
|
||||
}
|
||||
|
||||
public byte value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public static HybridRowVersion from(byte value) {
|
||||
return getMappings().get(value);
|
||||
}
|
||||
|
||||
private static java.util.HashMap<Byte, HybridRowVersion> getMappings() {
|
||||
if (mappings == null) {
|
||||
synchronized (HybridRowVersion.class) {
|
||||
if (mappings == null) {
|
||||
mappings = new HashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return mappings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow;
|
||||
|
||||
public interface ISpanResizer<T> {
|
||||
/**
|
||||
* Resizes an existing a buffer.
|
||||
* <typeparam name="T">The type of the elements of the memory.</typeparam>
|
||||
*
|
||||
* @param minimumLength The minimum required length (in elements) of the memory.
|
||||
* @param buffer Optional existing memory to be copied to the new buffer. Ownership of <paramref
|
||||
* name="buffer" /> is
|
||||
* transferred as part of this call and it should not be used by the caller after this call
|
||||
* completes.
|
||||
* @return A new memory whose size is <em>at least as big</em> as <paramref name="minimumLength" />
|
||||
* and containing the content of <paramref name="buffer" />.
|
||||
*/
|
||||
|
||||
Span<T> Resize(int minimumLength);
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: Span<T> Resize(int minimumLength, Span<T> buffer = default);
|
||||
Span<T> Resize(int minimumLength, Span<T> buffer);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class MemorySpanResizer<T> implements ISpanResizer<T> {
|
||||
private Memory<T> memory;
|
||||
|
||||
|
||||
public MemorySpanResizer() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public MemorySpanResizer(int initialCapacity = 0)
|
||||
public MemorySpanResizer(int initialCapacity) {
|
||||
checkArgument(initialCapacity >= 0);
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Java does not allow direct instantiation of arrays of generic type parameters:
|
||||
//ORIGINAL LINE: this.memory = initialCapacity == 0 ? default : new Memory<T>(new T[initialCapacity]);
|
||||
this.memory = initialCapacity == 0 ? null : new Memory<T>((T[])new Object[initialCapacity]);
|
||||
}
|
||||
|
||||
public Memory<T> getMemory() {
|
||||
return this.memory;
|
||||
}
|
||||
|
||||
/**
|
||||
* <inheritdoc />
|
||||
*/
|
||||
|
||||
public Span<T> Resize(int minimumLength) {
|
||||
return Resize(minimumLength, null);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public Span<T> Resize(int minimumLength, Span<T> buffer = default)
|
||||
public Span<T> Resize(int minimumLength, Span<T> buffer) {
|
||||
if (this.memory.Length < minimumLength) {
|
||||
//C# TO JAVA CONVERTER WARNING: Java does not allow direct instantiation of arrays of generic type
|
||||
// parameters:
|
||||
//ORIGINAL LINE: this.memory = new Memory<T>(new T[Math.Max(minimumLength, buffer.Length)]);
|
||||
this.memory = new Memory<T>((T[])new Object[Math.max(minimumLength, buffer.Length)]);
|
||||
}
|
||||
|
||||
Span<T> next = this.memory.Span;
|
||||
if (!buffer.IsEmpty && next.Slice(0, buffer.Length) != buffer) {
|
||||
buffer.CopyTo(next);
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow;
|
||||
|
||||
/**
|
||||
* The literal null value.
|
||||
* <p>
|
||||
* May be stored hybrid row to indicate the literal null value. Typically this value should
|
||||
* not be used and the corresponding column should be absent from the row.
|
||||
*/
|
||||
public final class NullValue {
|
||||
/**
|
||||
* The default null literal.
|
||||
* This is the same value as default({@link NullValue}).
|
||||
*/
|
||||
public static final NullValue Default = new NullValue();
|
||||
|
||||
/**
|
||||
* Returns true if this is the same value as {@code other}.
|
||||
*
|
||||
* @param other The value to compare against.
|
||||
* @return True if the two values are the same.
|
||||
*/
|
||||
public boolean equals(NullValue other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (null == other) {
|
||||
return false;
|
||||
}
|
||||
return other instanceof NullValue && this.equals((NullValue)other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
public enum Result {
|
||||
Success(0),
|
||||
Failure(1),
|
||||
NotFound(2),
|
||||
Exists(3),
|
||||
TooBig(4),
|
||||
|
||||
/**
|
||||
* The type of an existing field does not match the expected type for this operation.
|
||||
*/
|
||||
TypeMismatch(5),
|
||||
|
||||
/**
|
||||
* An attempt to write in a read-only scope.
|
||||
*/
|
||||
InsufficientPermissions(6),
|
||||
|
||||
/**
|
||||
* An attempt to write a field that did not match its (optional) type constraints.
|
||||
*/
|
||||
TypeConstraint(7),
|
||||
|
||||
/**
|
||||
* The byte sequence could not be parsed as a valid row.
|
||||
*/
|
||||
InvalidRow(8),
|
||||
|
||||
/**
|
||||
* The byte sequence was too short for the requested action.
|
||||
*/
|
||||
InsufficientBuffer(9),
|
||||
|
||||
/**
|
||||
* The operation was cancelled.
|
||||
*/
|
||||
Canceled(10);
|
||||
|
||||
public static final int SIZE = Integer.SIZE;
|
||||
|
||||
private static Int2ObjectMap<Result> mappings;
|
||||
private final int value;
|
||||
|
||||
Result(int value) {
|
||||
this.value = value;
|
||||
mappings().put(value, this);
|
||||
}
|
||||
|
||||
public static Result from(int value) {
|
||||
return mappings().get(value);
|
||||
}
|
||||
|
||||
public int value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
private static Int2ObjectMap<Result> mappings() {
|
||||
if (mappings == null) {
|
||||
synchronized (Result.class) {
|
||||
if (mappings == null) {
|
||||
mappings = new Int2ObjectOpenHashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return mappings;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,325 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow;
|
||||
|
||||
import com.azure.data.cosmos.core.UtfAnyString;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.Layout;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutEndScope;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutScope;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutTuple;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutType;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutTypes;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.StringToken;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.TypeArgument;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.TypeArgumentList;
|
||||
|
||||
import static com.google.common.base.Strings.lenientFormat;
|
||||
|
||||
public final class RowCursor implements Cloneable {
|
||||
|
||||
private LayoutType cellType;
|
||||
private TypeArgumentList cellTypeArgs;
|
||||
private int count;
|
||||
private boolean deferUniqueIndex;
|
||||
private int endOffset;
|
||||
private boolean exists;
|
||||
private boolean immutable;
|
||||
private int index;
|
||||
private Layout layout;
|
||||
private int metaOffset;
|
||||
private int pathOffset;
|
||||
private int pathToken;
|
||||
private LayoutScope scopeType;
|
||||
private TypeArgumentList scopeTypeArgs;
|
||||
private int start;
|
||||
private int valueOffset;
|
||||
private UtfAnyString writePath;
|
||||
private StringToken writePathToken;
|
||||
|
||||
RowCursor() {
|
||||
}
|
||||
|
||||
protected RowCursor clone() {
|
||||
try {
|
||||
return (RowCursor) super.clone();
|
||||
} catch (CloneNotSupportedException error) {
|
||||
throw new IllegalStateException(error);
|
||||
}
|
||||
}
|
||||
|
||||
public static RowCursor Create(RowBuffer row) {
|
||||
|
||||
final SchemaId schemaId = row.ReadSchemaId(1);
|
||||
final Layout layout = row.resolver().resolve(schemaId);
|
||||
final int sparseSegmentOffset = row.computeVariableValueOffset(layout, HybridRowHeader.SIZE, layout.numVariable());
|
||||
|
||||
return new RowCursor()
|
||||
.layout(layout)
|
||||
.scopeType(LayoutTypes.UDT)
|
||||
.scopeTypeArgs(new TypeArgumentList(schemaId))
|
||||
.start(HybridRowHeader.SIZE)
|
||||
.metaOffset(sparseSegmentOffset)
|
||||
.valueOffset(sparseSegmentOffset);
|
||||
}
|
||||
|
||||
public static RowCursor CreateForAppend(RowBuffer row) {
|
||||
|
||||
final SchemaId schemaId = row.ReadSchemaId(1);
|
||||
final Layout layout = row.resolver().resolve(schemaId);
|
||||
|
||||
return new RowCursor()
|
||||
.layout(layout)
|
||||
.scopeType(LayoutTypes.UDT)
|
||||
.scopeTypeArgs(new TypeArgumentList(schemaId))
|
||||
.start(HybridRowHeader.SIZE)
|
||||
.metaOffset(row.length())
|
||||
.valueOffset(row.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* If existing, the layout code of the existing field, otherwise undefined.
|
||||
*/
|
||||
public LayoutType cellType() {
|
||||
return this.cellType;
|
||||
}
|
||||
|
||||
public RowCursor cellType(LayoutType cellType) {
|
||||
this.cellType = cellType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* For types with generic parameters (e.g. {@link LayoutTuple}, the type parameters.
|
||||
*/
|
||||
public TypeArgumentList cellTypeArgs() {
|
||||
return this.cellTypeArgs;
|
||||
}
|
||||
|
||||
public RowCursor cellTypeArgs(TypeArgumentList value) {
|
||||
this.cellTypeArgs = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* For sized scopes (e.g. Typed Array), the number of elements.
|
||||
*/
|
||||
public int count() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
public RowCursor count(int count) {
|
||||
this.count = count;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, this scope is an unique index scope whose index will be built after its items are written.
|
||||
*/
|
||||
public boolean deferUniqueIndex() {
|
||||
return this.deferUniqueIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* If existing, the offset to the end of the existing field. Used as a hint when skipping
|
||||
* forward.
|
||||
*/
|
||||
public int endOffset() {
|
||||
return this.endOffset;
|
||||
}
|
||||
|
||||
public RowCursor endOffset(int value) {
|
||||
this.endOffset = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if an existing field matching the search criteria was found.
|
||||
*/
|
||||
public boolean exists() {
|
||||
return this.exists;
|
||||
}
|
||||
|
||||
public RowCursor exists(boolean value) {
|
||||
this.exists = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If {@code true}, this scope's nested fields cannot be updated individually
|
||||
* <p>
|
||||
* The entire scope can still be replaced.
|
||||
*/
|
||||
public boolean immutable() {
|
||||
return this.immutable;
|
||||
}
|
||||
|
||||
public RowCursor immutable(boolean value) {
|
||||
this.immutable = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* For indexed scopes (e.g. an Array scope), the zero-based index into the scope of the sparse field
|
||||
*/
|
||||
public int index() {
|
||||
return this.index;
|
||||
}
|
||||
|
||||
public RowCursor index(int value) {
|
||||
this.index = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The layout describing the contents of the scope, or {@code null} if the scope is unschematized.
|
||||
*/
|
||||
public Layout layout() {
|
||||
return this.layout;
|
||||
}
|
||||
|
||||
public RowCursor layout(Layout value) {
|
||||
this.layout = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
public RowCursor metaOffset(final int value) {
|
||||
this.metaOffset = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If existing, the offset scope relative path for reading.
|
||||
*/
|
||||
public int pathOffset() {
|
||||
return this.pathOffset;
|
||||
}
|
||||
|
||||
public RowCursor pathOffset(final int value) {
|
||||
this.pathOffset = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If existing, the layout string token of scope relative path for reading.
|
||||
*/
|
||||
public int pathToken() {
|
||||
return this.pathToken;
|
||||
}
|
||||
|
||||
public RowCursor pathToken(int value) {
|
||||
this.pathToken = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The kind of scope within which this edit was prepared
|
||||
*/
|
||||
public LayoutScope scopeType() {
|
||||
return this.scopeType;
|
||||
}
|
||||
|
||||
public RowCursor scopeType(LayoutScope scopeType) {
|
||||
this.scopeType = scopeType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type parameters of the scope within which this edit was prepared
|
||||
*/
|
||||
public TypeArgumentList scopeTypeArgs() {
|
||||
return this.scopeTypeArgs;
|
||||
}
|
||||
|
||||
public RowCursor scopeTypeArgs(TypeArgumentList scopeTypeArgs) {
|
||||
this.scopeTypeArgs = scopeTypeArgs;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The 0-based byte offset from the beginning of the row where the first sparse field within
|
||||
* the scope begins.
|
||||
*/
|
||||
public int start() {
|
||||
return this.start;
|
||||
}
|
||||
|
||||
public RowCursor start(int start) {
|
||||
this.start = start;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
try {
|
||||
|
||||
if (this.scopeType() == null) {
|
||||
return "<Invalid>";
|
||||
}
|
||||
|
||||
TypeArgument scopeTypeArg = (this.scopeType() instanceof LayoutEndScope)
|
||||
? TypeArgument.NONE
|
||||
: new TypeArgument(this.scopeType(), this.scopeTypeArgs());
|
||||
|
||||
TypeArgument typeArg = (this.cellType() == null) || (this.cellType() instanceof LayoutEndScope)
|
||||
? TypeArgument.NONE
|
||||
: new TypeArgument(this.cellType(), this.cellTypeArgs());
|
||||
|
||||
String pathOrIndex = this.writePath().isNull() ? String.valueOf(this.index()) : this.writePath().toString();
|
||||
|
||||
return lenientFormat("%s[%s] : %s@%s/%s%s",
|
||||
scopeTypeArg,
|
||||
pathOrIndex,
|
||||
typeArg,
|
||||
this.metaOffset(),
|
||||
this.valueOffset(),
|
||||
this.immutable() ? " immutable" : "");
|
||||
|
||||
} catch (Exception ignored) {
|
||||
return "<???>";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If existing, the offset to the value of the existing field, otherwise undefined.
|
||||
*/
|
||||
public int valueOffset() {
|
||||
return this.valueOffset;
|
||||
}
|
||||
|
||||
public RowCursor valueOffset(int valueOffset) {
|
||||
this.valueOffset = valueOffset;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If existing, the scope relative path for writing.
|
||||
*/
|
||||
public UtfAnyString writePath() {
|
||||
return this.writePath;
|
||||
}
|
||||
|
||||
public void writePath(UtfAnyString writePath) {
|
||||
this.writePath = writePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* If WritePath is tokenized, then its token.
|
||||
*/
|
||||
public StringToken writePathToken() {
|
||||
return this.writePathToken;
|
||||
}
|
||||
|
||||
public void writePathToken(StringToken writePathToken) {
|
||||
this.writePathToken = writePathToken;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow;
|
||||
|
||||
import com.azure.data.cosmos.core.UtfAnyString;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutEndScope;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.StringToken;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public final class RowCursors {
|
||||
|
||||
private RowCursors() {
|
||||
}
|
||||
|
||||
public static RowCursor Find(@Nonnull RowCursor edit, @Nonnull RowBuffer row, @Nonnull UtfAnyString path) {
|
||||
checkArgument(!edit.scopeType().isIndexedScope());
|
||||
|
||||
if (!(edit.cellType() instanceof LayoutEndScope)) {
|
||||
while (row.sparseIteratorMoveNext(edit)) {
|
||||
if (path.equals(row.readSparsePath(edit))) {
|
||||
edit.exists(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
edit.writePath(path);
|
||||
edit.writePathToken(null);
|
||||
|
||||
return edit;
|
||||
}
|
||||
|
||||
public static RowCursor Find(@Nonnull RowCursor edit, @Nonnull RowBuffer row, @Nonnull StringToken pathToken) {
|
||||
|
||||
checkNotNull(edit);
|
||||
checkNotNull(row);
|
||||
checkNotNull(pathToken);
|
||||
|
||||
checkArgument(!edit.scopeType().isIndexedScope());
|
||||
|
||||
if (!(edit.cellType() instanceof LayoutEndScope)) {
|
||||
while (row.sparseIteratorMoveNext(edit)) {
|
||||
if (pathToken.id() == (long) edit.pathToken()) {
|
||||
edit.exists(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
edit.writePath(new UtfAnyString(pathToken.path()));
|
||||
edit.writePathToken(pathToken);
|
||||
|
||||
return edit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an equivalent scope that is read-only.
|
||||
*/
|
||||
public static RowCursor asReadOnly(RowCursor src) {
|
||||
return src.clone().immutable(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of the current cursor.
|
||||
* <p>
|
||||
* The two cursors will have independent and unconnected lifetimes after cloning. However, mutations to a
|
||||
* {@link RowBuffer} can invalidate any active cursors over the same row.
|
||||
*/
|
||||
public static RowCursor copy(RowCursor source) {
|
||||
return source.clone();
|
||||
}
|
||||
|
||||
public static boolean moveNext(RowCursor edit, RowBuffer row) {
|
||||
edit.writePath(null);
|
||||
edit.writePathToken(null);
|
||||
return row.sparseIteratorMoveNext(edit);
|
||||
}
|
||||
|
||||
public static boolean moveNext(@Nonnull RowCursor edit, @Nonnull RowBuffer row, @Nonnull RowCursor childScope) {
|
||||
if (childScope.scopeType() != null) {
|
||||
RowCursors.skip(edit.clone(), row, childScope);
|
||||
}
|
||||
return RowCursors.moveNext(edit.clone(), row);
|
||||
}
|
||||
|
||||
public static boolean moveTo(@Nonnull final RowCursor edit, @Nonnull final RowBuffer row, final int index) {
|
||||
|
||||
checkNotNull(row);
|
||||
checkNotNull(edit);
|
||||
checkArgument(edit.index() <= index);
|
||||
|
||||
edit.writePath(null);
|
||||
edit.writePathToken(null);
|
||||
|
||||
while (edit.index() < index) {
|
||||
if (!row.sparseIteratorMoveNext(edit)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void skip(@Nonnull final RowCursor edit, @Nonnull final RowBuffer row, @Nonnull final RowCursor childScope) {
|
||||
|
||||
checkArgument(childScope.start() == edit.valueOffset());
|
||||
|
||||
if (!(childScope.cellType() instanceof LayoutEndScope)) {
|
||||
//noinspection StatementWithEmptyBody
|
||||
while (row.sparseIteratorMoveNext(childScope)) {
|
||||
}
|
||||
}
|
||||
|
||||
if (childScope.scopeType().isSizedScope()) {
|
||||
edit.endOffset(childScope.metaOffset());
|
||||
} else {
|
||||
edit.endOffset(childScope.metaOffset() + (LayoutCode.SIZE / Byte.SIZE)); // move past end of scope marker
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Describes the desired behavior when mutating a hybrid row.
|
||||
*/
|
||||
public enum RowOptions {
|
||||
None(0),
|
||||
|
||||
/**
|
||||
* Overwrite an existing value.
|
||||
* <p>
|
||||
* An existing value is assumed to exist at the offset provided. The existing value is
|
||||
* replaced inline. The remainder of the row is resized to accomodate either an increase or decrease
|
||||
* in required space.
|
||||
*/
|
||||
Update(1),
|
||||
|
||||
/**
|
||||
* Insert a new value.
|
||||
* <p>
|
||||
* An existing value is assumed NOT to exist at the offset provided. The new value is
|
||||
* inserted immediately at the offset. The remainder of the row is resized to accomodate either an
|
||||
* increase or decrease in required space.
|
||||
*/
|
||||
Insert(2),
|
||||
|
||||
/**
|
||||
* Update an existing value or insert a new value, if no value exists.
|
||||
* <p>
|
||||
* If a value exists, then this operation becomes {@link Update}, otherwise it
|
||||
* becomes {@link Insert}.
|
||||
*/
|
||||
Upsert(3),
|
||||
|
||||
/**
|
||||
* Insert a new value moving existing values to the right.
|
||||
* <p>
|
||||
* Within an array scope, inserts a new value immediately at the index moving all subsequent
|
||||
* items to the right. In any other scope behaves the same as {@link Upsert}.
|
||||
*/
|
||||
InsertAt(4),
|
||||
|
||||
/**
|
||||
* Delete an existing value.
|
||||
* <p>
|
||||
* If a value exists, then it is removed. The remainder of the row is resized to accomodate
|
||||
* a decrease in required space. If no value exists this operation is a no-op.
|
||||
*/
|
||||
Delete(5);
|
||||
|
||||
public static final int SIZE = java.lang.Integer.SIZE;
|
||||
private static HashMap<Integer, RowOptions> mappings;
|
||||
private int value;
|
||||
|
||||
RowOptions(int value) {
|
||||
this.value = value;
|
||||
mappings().put(value, this);
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public static RowOptions from(int value) {
|
||||
return mappings().get(value);
|
||||
}
|
||||
|
||||
private static HashMap<Integer, RowOptions> mappings() {
|
||||
if (mappings == null) {
|
||||
synchronized (RowOptions.class) {
|
||||
if (mappings == null) {
|
||||
mappings = new HashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return mappings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.google.common.base.Strings.lenientFormat;
|
||||
|
||||
/**
|
||||
* The unique identifier for a schema
|
||||
* Identifiers must be unique within the scope of the database in which they are used.
|
||||
*/
|
||||
@JsonDeserialize(using = SchemaId.JsonDeserializer.class)
|
||||
@JsonSerialize(using = SchemaId.JsonSerializer.class)
|
||||
public final class SchemaId {
|
||||
|
||||
public static final SchemaId INVALID = null;
|
||||
public static final SchemaId NONE = new SchemaId(-1);
|
||||
public static final int SIZE = Integer.SIZE / Byte.SIZE;
|
||||
|
||||
private static final long MAX_VALUE = 0x00000000FFFFFFFFL;
|
||||
private static final Int2ReferenceMap<SchemaId> cache = new Int2ReferenceOpenHashMap<>();
|
||||
|
||||
private final int value;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link SchemaId} struct.
|
||||
*
|
||||
* @param value The underlying globally unique identifier of the schema.
|
||||
*/
|
||||
private SchemaId(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return other instanceof SchemaId && this.equals((SchemaId) other);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code true} if this is the same {@link SchemaId} as {@code other}
|
||||
*
|
||||
* @param other The value to compare against.
|
||||
* @return True if the two values are the same.
|
||||
*/
|
||||
public boolean equals(SchemaId other) {
|
||||
if (null == other) {
|
||||
return false;
|
||||
}
|
||||
return this.value() == other.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SchemaId} from a specified underlying integer value
|
||||
*
|
||||
* @return The integer value of this {@link SchemaId}
|
||||
*/
|
||||
public static SchemaId from(int value) {
|
||||
return cache.computeIfAbsent(value, SchemaId::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Integer.valueOf(this.value()).hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(this.value());
|
||||
}
|
||||
|
||||
/**
|
||||
* The underlying integer value of this {@link SchemaId}
|
||||
*
|
||||
* @return The integer value of this {@link SchemaId}
|
||||
*/
|
||||
public int value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
static final class JsonDeserializer extends StdDeserializer<SchemaId> {
|
||||
|
||||
private JsonDeserializer() {
|
||||
super(SchemaId.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchemaId deserialize(final JsonParser parser, final DeserializationContext context) throws IOException, JsonProcessingException {
|
||||
|
||||
final long value = parser.getLongValue();
|
||||
|
||||
if (value < 0 || value > MAX_VALUE) {
|
||||
String message = lenientFormat("expected integer value in [0, 4294967295], not %s", value);
|
||||
throw MismatchedInputException.from(parser, SchemaId.class, message);
|
||||
}
|
||||
|
||||
return new SchemaId((int) value);
|
||||
}
|
||||
}
|
||||
|
||||
static final class JsonSerializer extends StdSerializer<SchemaId> {
|
||||
|
||||
private JsonSerializer() {
|
||||
super(SchemaId.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(final SchemaId value, final JsonGenerator generator, final SerializerProvider provider) throws IOException {
|
||||
generator.writeNumber((long) value.value() & MAX_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow;
|
||||
|
||||
/**
|
||||
* A wall clock time expressed in milliseconds since the Unix Epoch.
|
||||
* <p>
|
||||
* A {@link UnixDateTime} is a fixed length value-type providing millisecond
|
||||
* granularity as a signed offset from the Unix Epoch (midnight, January 1, 1970 UTC).
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [DebuggerDisplay("{" + nameof(UnixDateTime.Milliseconds) + "}")][StructLayout(LayoutKind.Sequential,
|
||||
// Pack = 1)] public readonly struct UnixDateTime : IEquatable<UnixDateTime>
|
||||
//C# TO JAVA CONVERTER WARNING: Java does not allow user-defined value types. The behavior of this class may differ
|
||||
// from the original:
|
||||
//ORIGINAL LINE: [DebuggerDisplay("{" + nameof(UnixDateTime.Milliseconds) + "}")][StructLayout(LayoutKind.Sequential,
|
||||
// Pack = 1)] public readonly struct UnixDateTime : IEquatable<UnixDateTime>
|
||||
//C# TO JAVA CONVERTER WARNING: Java has no equivalent to the C# readonly struct:
|
||||
public final class UnixDateTime implements IEquatable<UnixDateTime> {
|
||||
/**
|
||||
* The unix epoch.
|
||||
* {@link UnixDateTime} values are signed values centered on {@link Epoch}.
|
||||
* <para />
|
||||
* This is the same value as default({@link UnixDateTime}).
|
||||
*/
|
||||
public static final UnixDateTime Epoch = new UnixDateTime();
|
||||
/**
|
||||
* The size (in bytes) of a UnixDateTime.
|
||||
*/
|
||||
public static final int Size = (Long.SIZE / Byte.SIZE);
|
||||
/**
|
||||
* The number of milliseconds since {@link Epoch}.
|
||||
* This value may be negative.
|
||||
*/
|
||||
private long Milliseconds;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link UnixDateTime} struct.
|
||||
*
|
||||
* @param milliseconds The number of milliseconds since {@link Epoch}.
|
||||
*/
|
||||
public UnixDateTime() {
|
||||
}
|
||||
|
||||
public UnixDateTime(long milliseconds) {
|
||||
this.Milliseconds = milliseconds;
|
||||
}
|
||||
|
||||
public long getMilliseconds() {
|
||||
return Milliseconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is the same value as {@link other}.
|
||||
*
|
||||
* @param other The value to compare against.
|
||||
* @return True if the two values are the same.
|
||||
*/
|
||||
public boolean equals(UnixDateTime other) {
|
||||
return this.getMilliseconds() == other.getMilliseconds();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link object.Equals(object)} overload.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (null == obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return obj instanceof UnixDateTime && this.equals((UnixDateTime)obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link object.GetHashCode} overload.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (new Long(this.getMilliseconds())).hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Operator == overload.
|
||||
*/
|
||||
public static boolean opEquals(UnixDateTime left, UnixDateTime right) {
|
||||
return left.equals(right.clone());
|
||||
}
|
||||
|
||||
/**
|
||||
* Operator != overload.
|
||||
*/
|
||||
public static boolean opNotEquals(UnixDateTime left, UnixDateTime right) {
|
||||
return !left.equals(right.clone());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.internal;
|
||||
|
||||
import com.google.common.base.Utf8;
|
||||
import com.google.common.hash.HashCode;
|
||||
import com.google.common.hash.HashFunction;
|
||||
import com.google.common.hash.Hashing;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Strings.lenientFormat;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
/**
|
||||
* Murmur3Hash for x64 (Little Endian).
|
||||
* <p>Reference: https: //en.wikipedia.org/wiki/MurmurHash <br /></p>
|
||||
* <p>
|
||||
* This implementation provides span-based access for hashing content not available in a
|
||||
* {@link T:byte[]}
|
||||
* </p>
|
||||
*/
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@Immutable
|
||||
public final class Murmur3Hash {
|
||||
|
||||
private static final ByteBufAllocator allocator = ByteBufAllocator.DEFAULT;
|
||||
private static final ByteBuf FALSE = Constant.add(false);
|
||||
private static final ByteBuf TRUE = Constant.add(true);
|
||||
private static final ByteBuf EMPTY_STRING = Constant.add("");
|
||||
|
||||
/**
|
||||
* Computes a 128-bit Murmur3Hash 128-bit value for a data item
|
||||
*
|
||||
* @param item The data to hash
|
||||
* @param seed The seed with which to initialize
|
||||
* @return The 128-bit hash represented as two 64-bit words encapsulated by a {@link Code} instance
|
||||
*/
|
||||
public static Code Hash128(@Nonnull final String item, @Nonnull final Code seed) {
|
||||
|
||||
checkNotNull(item, "value: null, seed: %s", seed);
|
||||
checkNotNull(seed, "value: %s, seed: null", item);
|
||||
|
||||
if (item.isEmpty()) {
|
||||
Hash128(EMPTY_STRING, seed);
|
||||
}
|
||||
|
||||
final int encodedLength = Utf8.encodedLength(item);
|
||||
ByteBuf buffer = allocator.buffer(encodedLength, encodedLength);
|
||||
|
||||
try {
|
||||
final int count = buffer.writeCharSequence(item, UTF_8);
|
||||
assert count == encodedLength : lenientFormat("count: %s, encodedLength: %s");
|
||||
return Hash128(buffer, seed);
|
||||
} finally {
|
||||
buffer.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a 128-bit Murmur3Hash 128-bit value for a {@link boolean} data item
|
||||
*
|
||||
* @param item The data to hash
|
||||
* @param seed The seed with which to initialize
|
||||
* @return The 128-bit hash represented as two 64-bit words encapsulated by a {@link Code} instance
|
||||
*/
|
||||
public static Code Hash128(boolean item, Code seed) {
|
||||
return Murmur3Hash.Hash128(item ? TRUE : FALSE, seed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a 128-bit Murmur3Hash 128-bit value for a {@link ByteBuf} data item
|
||||
*
|
||||
* @param item The data to hash
|
||||
* @param seed The seed with which to initialize
|
||||
* @return The 128-bit hash represented as two 64-bit words encapsulated by a {@link Code} instance
|
||||
*/
|
||||
public static Code Hash128(ByteBuf item, Code seed) {
|
||||
// TODO: DANOBLE: Fork and update or hack murmur3_128 to support a 128-bit seed value or push for a 32-bit seed
|
||||
HashFunction hashFunction = Hashing.murmur3_128(Long.valueOf(seed.high | 0xFFFFFFFFL).intValue());
|
||||
HashCode hashCode = hashFunction.hashBytes(item.array());
|
||||
return new Code(hashCode);
|
||||
}
|
||||
|
||||
@Immutable
|
||||
public static final class Code {
|
||||
|
||||
public final long low, high;
|
||||
|
||||
public Code(long low, long high) {
|
||||
this.low = low;
|
||||
this.high = high;
|
||||
}
|
||||
|
||||
private Code(HashCode hashCode) {
|
||||
ByteBuf buffer = Unpooled.wrappedBuffer(hashCode.asBytes());
|
||||
this.low = buffer.readLongLE();
|
||||
this.high = buffer.readLongLE();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Constant {
|
||||
|
||||
private static ByteBuf constants = allocator.heapBuffer();
|
||||
|
||||
private Constant() {
|
||||
}
|
||||
|
||||
static ByteBuf add(final boolean value) {
|
||||
final int start = constants.writerIndex();
|
||||
constants.writeByte(value ? 1 : 0);
|
||||
return constants.slice(start, Byte.BYTES).asReadOnly();
|
||||
}
|
||||
|
||||
static ByteBuf add(final String value) {
|
||||
|
||||
final int start = constants.writerIndex();
|
||||
final int encodedLength = Utf8.encodedLength(value);
|
||||
final ByteBuf buffer = allocator.buffer(encodedLength, encodedLength);
|
||||
|
||||
final int count = buffer.writeCharSequence(value, UTF_8);
|
||||
assert count == encodedLength : lenientFormat("count: %s, encodedLength: %s");
|
||||
|
||||
return constants.slice(start, encodedLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.io;
|
||||
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.TypeArgument;
|
||||
|
||||
/**
|
||||
* A type may implement this interface to support serialization into a HybridRow.
|
||||
*/
|
||||
public interface IRowSerializable {
|
||||
/**
|
||||
* Writes the current instance into the row.
|
||||
*
|
||||
* @param writer A writer for the current row scope.
|
||||
* @param typeArg The schematized layout type, if a schema is available.
|
||||
* @return Success if the write is successful, the error code otherwise.
|
||||
*/
|
||||
Result write(Reference<RowWriter> writer, TypeArgument typeArg);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,99 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.io;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public final class RowReaderExtensions {
|
||||
/**
|
||||
* Read the current field as a nested, structured, sparse scope containing a linear collection of zero or more
|
||||
* items.
|
||||
* <typeparam name="TItem">The type of the items within the collection.</typeparam>
|
||||
*
|
||||
* @param reader A forward-only cursor for reading the collection.
|
||||
* @param deserializer A function that reads one item from the collection.
|
||||
* @param list On success, the collection of materialized items.
|
||||
* @return The result.
|
||||
*/
|
||||
public static <TItem> Result ReadList(Reference<RowReader> reader, DeserializerFunc<TItem> deserializer,
|
||||
Out<ArrayList<TItem>> list) {
|
||||
// Pass the context as a struct by value to avoid allocations.
|
||||
ListContext<TItem> ctx = new ListContext<TItem>();
|
||||
ctx.List = new ArrayList<>();
|
||||
ctx.Deserializer =
|
||||
(Reference<RowReader> reader.argValue, Out<TItem> item) -> deserializer.invoke(reader.get().clone(), item);
|
||||
|
||||
// All lambda's here are static.
|
||||
// TODO: C# TO JAVA CONVERTER: The following lambda contained an unresolved 'ref' keyword - these are not
|
||||
// converted by C# to Java Converter:
|
||||
Result r = reader.get().ReadScope(ctx.clone(), (ref RowReader arrayReader, ListContext<TItem> ctx1) ->
|
||||
{
|
||||
while (arrayReader.Read()) {
|
||||
Result r2 = arrayReader.ReadScope(ctx1.clone(), (ref RowReader itemReader, ListContext<TItem> ctx2) ->
|
||||
{
|
||||
Reference<com.azure.data.cosmos.serialization.hybridrow.io.RowReader> tempReference_itemReader = new Reference<com.azure.data.cosmos.serialization.hybridrow.io.RowReader>(itemReader);
|
||||
TItem op;
|
||||
Out<TItem> tempOut_op = new Out<TItem>();
|
||||
Result r3 = ctx2.Deserializer.invoke(tempReference_itemReader, tempOut_op);
|
||||
op = tempOut_op.get();
|
||||
itemReader = tempReference_itemReader.get();
|
||||
if (r3 != Result.Success) {
|
||||
return r3;
|
||||
}
|
||||
|
||||
ctx2.List.add(op);
|
||||
return Result.Success;
|
||||
});
|
||||
|
||||
if (r2 != Result.Success) {
|
||||
return r2;
|
||||
}
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
});
|
||||
|
||||
if (r != Result.Success) {
|
||||
list.setAndGet(null);
|
||||
return r;
|
||||
}
|
||||
|
||||
list.setAndGet(ctx.List);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function to read content from a {@link RowReader}.
|
||||
* <typeparam name="TItem">The type of the item to read.</typeparam>
|
||||
*
|
||||
* @param reader A forward-only cursor for reading the item.
|
||||
* @param item On success, the item read.
|
||||
* @return The result.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface DeserializerFunc<TItem> {
|
||||
Result invoke(Reference<RowReader> reader, Out<TItem> item);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Java does not allow user-defined value types. The behavior of this class may
|
||||
// differ from the original:
|
||||
//ORIGINAL LINE: private struct ListContext<TItem>
|
||||
private final static class ListContext<TItem> {
|
||||
public DeserializerFunc<TItem> Deserializer;
|
||||
public ArrayList<TItem> List;
|
||||
|
||||
public ListContext clone() {
|
||||
ListContext varCopy = new ListContext();
|
||||
|
||||
varCopy.List = this.List;
|
||||
varCopy.Deserializer = this.Deserializer;
|
||||
|
||||
return varCopy;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,495 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.json;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Float128;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.NullValue;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.UnixDateTime;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.io.RowReader;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public final class RowReaderJsonExtensions {
|
||||
/**
|
||||
* Project a JSON document from a HybridRow {@link RowReader}.
|
||||
*
|
||||
* @param reader The reader to project to JSON.
|
||||
* @param str If successful, the JSON document that corresponds to the <paramref name="reader"/>.
|
||||
* @return The result.
|
||||
*/
|
||||
public static Result ToJson(Reference<RowReader> reader, Out<String> str) {
|
||||
return RowReaderJsonExtensions.ToJson(reader.get().clone(), new RowReaderJsonSettings(" "), str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Project a JSON document from a HybridRow {@link RowReader}.
|
||||
*
|
||||
* @param reader The reader to project to JSON.
|
||||
* @param settings Settings that control how the JSON document is formatted.
|
||||
* @param str If successful, the JSON document that corresponds to the <paramref name="reader"/>.
|
||||
* @return The result.
|
||||
*/
|
||||
public static Result ToJson(Reference<RowReader> reader, RowReaderJsonSettings settings,
|
||||
Out<String> str) {
|
||||
ReaderStringContext ctx = new ReaderStringContext(new StringBuilder(),
|
||||
new RowReaderJsonSettings(settings.IndentChars, settings.QuoteChar == '\'' ? '\'' : '"'), 1);
|
||||
|
||||
ctx.Builder.append("{");
|
||||
Result result = RowReaderJsonExtensions.ToJson(reader, ctx.clone());
|
||||
if (result != Result.Success) {
|
||||
str.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
ctx.Builder.append(ctx.NewLine);
|
||||
ctx.Builder.append("}");
|
||||
str.setAndGet(ctx.Builder.toString());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
private static Result ToJson(Reference<RowReader> reader, ReaderStringContext ctx) {
|
||||
int index = 0;
|
||||
while (reader.get().Read()) {
|
||||
String path = !reader.get().getPath().IsNull ? String.format("%1$s%2$s%3$s:", ctx.Settings.QuoteChar,
|
||||
reader.get().getPath(), ctx.Settings.QuoteChar) : null;
|
||||
if (index != 0) {
|
||||
ctx.Builder.append(',');
|
||||
}
|
||||
|
||||
index++;
|
||||
ctx.Builder.append(ctx.NewLine);
|
||||
ctx.WriteIndent();
|
||||
if (path != null) {
|
||||
ctx.Builder.append(path);
|
||||
ctx.Builder.append(ctx.Separator);
|
||||
}
|
||||
|
||||
Result r;
|
||||
char scopeBracket = '\0';
|
||||
char scopeCloseBracket = '\0';
|
||||
switch (reader.get().getType().LayoutCode) {
|
||||
case Null: {
|
||||
NullValue _;
|
||||
Out<NullValue> tempOut__ =
|
||||
new Out<NullValue>();
|
||||
r = reader.get().ReadNull(tempOut__);
|
||||
_ = tempOut__.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append("null");
|
||||
break;
|
||||
}
|
||||
|
||||
case Boolean: {
|
||||
boolean value;
|
||||
Out<Boolean> tempOut_value = new Out<Boolean>();
|
||||
r = reader.get().ReadBool(tempOut_value);
|
||||
value = tempOut_value.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case Int8: {
|
||||
byte value;
|
||||
Out<Byte> tempOut_value2 = new Out<Byte>();
|
||||
r = reader.get().ReadInt8(tempOut_value2);
|
||||
value = tempOut_value2.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case Int16: {
|
||||
short value;
|
||||
Out<Short> tempOut_value3 = new Out<Short>();
|
||||
r = reader.get().ReadInt16(tempOut_value3);
|
||||
value = tempOut_value3.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case Int32: {
|
||||
int value;
|
||||
Out<Integer> tempOut_value4 = new Out<Integer>();
|
||||
r = reader.get().ReadInt32(tempOut_value4);
|
||||
value = tempOut_value4.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case Int64: {
|
||||
long value;
|
||||
Out<Long> tempOut_value5 = new Out<Long>();
|
||||
r = reader.get().ReadInt64(tempOut_value5);
|
||||
value = tempOut_value5.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case UInt8: {
|
||||
byte value;
|
||||
Out<Byte> tempOut_value6 = new Out<Byte>();
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: r = reader.ReadUInt8(out byte value);
|
||||
r = reader.get().ReadUInt8(tempOut_value6);
|
||||
value = tempOut_value6.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case UInt16: {
|
||||
short value;
|
||||
Out<Short> tempOut_value7 = new Out<Short>();
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: r = reader.ReadUInt16(out ushort value);
|
||||
r = reader.get().ReadUInt16(tempOut_value7);
|
||||
value = tempOut_value7.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case UInt32: {
|
||||
int value;
|
||||
Out<Integer> tempOut_value8 = new Out<Integer>();
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: r = reader.ReadUInt32(out uint value);
|
||||
r = reader.get().ReadUInt32(tempOut_value8);
|
||||
value = tempOut_value8.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case UInt64: {
|
||||
long value;
|
||||
Out<Long> tempOut_value9 = new Out<Long>();
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: r = reader.ReadUInt64(out ulong value);
|
||||
r = reader.get().ReadUInt64(tempOut_value9);
|
||||
value = tempOut_value9.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case VarInt: {
|
||||
long value;
|
||||
Out<Long> tempOut_value10 = new Out<Long>();
|
||||
r = reader.get().ReadVarInt(tempOut_value10);
|
||||
value = tempOut_value10.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case VarUInt: {
|
||||
long value;
|
||||
Out<Long> tempOut_value11 = new Out<Long>();
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: r = reader.ReadVarUInt(out ulong value);
|
||||
r = reader.get().ReadVarUInt(tempOut_value11);
|
||||
value = tempOut_value11.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case Float32: {
|
||||
float value;
|
||||
Out<Float> tempOut_value12 = new Out<Float>();
|
||||
r = reader.get().ReadFloat32(tempOut_value12);
|
||||
value = tempOut_value12.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case Float64: {
|
||||
double value;
|
||||
Out<Double> tempOut_value13 = new Out<Double>();
|
||||
r = reader.get().ReadFloat64(tempOut_value13);
|
||||
value = tempOut_value13.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case Float128: {
|
||||
Float128 _;
|
||||
Out<Float128> tempOut__2 =
|
||||
new Out<Float128>();
|
||||
r = reader.get().ReadFloat128(tempOut__2);
|
||||
_ = tempOut__2.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
// ctx.Builder.AppendFormat("High: {0}, Low: {1}\n", value.High, value.Low);
|
||||
checkState(false, "Float128 are not supported.");
|
||||
break;
|
||||
}
|
||||
|
||||
case Decimal: {
|
||||
java.math.BigDecimal value;
|
||||
Out<BigDecimal> tempOut_value14 = new Out<BigDecimal>();
|
||||
r = reader.get().ReadDecimal(tempOut_value14);
|
||||
value = tempOut_value14.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case DateTime: {
|
||||
java.time.LocalDateTime value;
|
||||
Out<LocalDateTime> tempOut_value15 = new Out<LocalDateTime>();
|
||||
r = reader.get().ReadDateTime(tempOut_value15);
|
||||
value = tempOut_value15.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(ctx.Settings.QuoteChar);
|
||||
ctx.Builder.append(value);
|
||||
ctx.Builder.append(ctx.Settings.QuoteChar);
|
||||
break;
|
||||
}
|
||||
|
||||
case UnixDateTime: {
|
||||
UnixDateTime value;
|
||||
Out<UnixDateTime> tempOut_value16 =
|
||||
new Out<UnixDateTime>();
|
||||
r = reader.get().ReadUnixDateTime(tempOut_value16);
|
||||
value = tempOut_value16.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(value.Milliseconds);
|
||||
break;
|
||||
}
|
||||
|
||||
case Guid: {
|
||||
java.util.UUID value;
|
||||
Out<UUID> tempOut_value17 = new Out<UUID>();
|
||||
r = reader.get().ReadGuid(tempOut_value17);
|
||||
value = tempOut_value17.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(ctx.Settings.QuoteChar);
|
||||
ctx.Builder.append(value.toString());
|
||||
ctx.Builder.append(ctx.Settings.QuoteChar);
|
||||
break;
|
||||
}
|
||||
|
||||
case MongoDbObjectId: {
|
||||
MongoDbObjectId value;
|
||||
Out<azure.data.cosmos.serialization.hybridrow.MongoDbObjectId> tempOut_value18 = new Out<azure.data.cosmos.serialization.hybridrow.MongoDbObjectId>();
|
||||
r = reader.get().ReadMongoDbObjectId(tempOut_value18);
|
||||
value = tempOut_value18.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(ctx.Settings.QuoteChar);
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: ReadOnlyMemory<byte> bytes = value.ToByteArray();
|
||||
ReadOnlyMemory<Byte> bytes = value.ToByteArray();
|
||||
ctx.Builder.append(bytes.Span.ToHexString());
|
||||
ctx.Builder.append(ctx.Settings.QuoteChar);
|
||||
break;
|
||||
}
|
||||
|
||||
case Utf8: {
|
||||
Utf8Span value;
|
||||
// TODO: C# TO JAVA CONVERTER: The following method call contained an unresolved 'out' keyword
|
||||
// - these cannot be converted using the 'Out' helper class unless the method is within the
|
||||
// code being modified:
|
||||
r = reader.get().ReadString(out value);
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(ctx.Settings.QuoteChar);
|
||||
ctx.Builder.append(value.toString());
|
||||
ctx.Builder.append(ctx.Settings.QuoteChar);
|
||||
break;
|
||||
}
|
||||
|
||||
case Binary: {
|
||||
ReadOnlySpan<Byte> value;
|
||||
// TODO: C# TO JAVA CONVERTER: The following method call contained an unresolved 'out' keyword - these cannot be converted using the 'Out' helper class unless the method is within the code being modified:
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: r = reader.ReadBinary(out ReadOnlySpan<byte> value);
|
||||
r = reader.get().ReadBinary(out value);
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
ctx.Builder.append(ctx.Settings.QuoteChar);
|
||||
ctx.Builder.append(value.ToHexString());
|
||||
ctx.Builder.append(ctx.Settings.QuoteChar);
|
||||
break;
|
||||
}
|
||||
|
||||
case NullableScope:
|
||||
case ImmutableNullableScope: {
|
||||
if (!reader.get().getHasValue()) {
|
||||
ctx.Builder.append("null");
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no 'goto' in Java:
|
||||
// goto case LayoutCode.TypedTupleScope;
|
||||
}
|
||||
|
||||
case ArrayScope:
|
||||
case ImmutableArrayScope:
|
||||
case TypedArrayScope:
|
||||
case ImmutableTypedArrayScope:
|
||||
case TypedSetScope:
|
||||
case ImmutableTypedSetScope:
|
||||
case TypedMapScope:
|
||||
case ImmutableTypedMapScope:
|
||||
case TupleScope:
|
||||
case ImmutableTupleScope:
|
||||
case TypedTupleScope:
|
||||
case ImmutableTypedTupleScope:
|
||||
case TaggedScope:
|
||||
case ImmutableTaggedScope:
|
||||
case Tagged2Scope:
|
||||
case ImmutableTagged2Scope:
|
||||
scopeBracket = '[';
|
||||
scopeCloseBracket = ']';
|
||||
// TODO: C# TO JAVA CONVERTER: There is no 'goto' in Java:
|
||||
// goto case LayoutCode.EndScope;
|
||||
case ObjectScope:
|
||||
case ImmutableObjectScope:
|
||||
case Schema:
|
||||
case ImmutableSchema:
|
||||
scopeBracket = '{';
|
||||
scopeCloseBracket = '}';
|
||||
|
||||
case EndScope: {
|
||||
ctx.Builder.append(scopeBracket);
|
||||
int snapshot = ctx.Builder.length();
|
||||
r = reader.get().ReadScope(new ReaderStringContext(ctx.Builder, ctx.Settings.clone(), ctx.Indent + 1), RowReaderJsonExtensions.ToJson);
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (ctx.Builder.length() != snapshot) {
|
||||
ctx.Builder.append(ctx.NewLine);
|
||||
ctx.WriteIndent();
|
||||
}
|
||||
|
||||
ctx.Builder.append(scopeCloseBracket);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
throw new IllegalStateException(lenientFormat("Unknown type will be ignored: %s", reader.get().getType().LayoutCode));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Java does not allow user-defined value types. The behavior of this class may differ from the original:
|
||||
//ORIGINAL LINE: private readonly struct ReaderStringContext
|
||||
//C# TO JAVA CONVERTER WARNING: Java has no equivalent to the C# readonly struct:
|
||||
private final static class ReaderStringContext {
|
||||
public StringBuilder Builder;
|
||||
public int Indent;
|
||||
public String NewLine;
|
||||
public String Separator;
|
||||
public RowReaderJsonSettings Settings = new RowReaderJsonSettings();
|
||||
|
||||
public ReaderStringContext() {
|
||||
}
|
||||
|
||||
public ReaderStringContext(StringBuilder builder, RowReaderJsonSettings settings, int indent) {
|
||||
this.Settings = settings.clone();
|
||||
this.Separator = settings.IndentChars == null ? "" : " ";
|
||||
this.NewLine = settings.IndentChars == null ? "" : "\n";
|
||||
this.Indent = indent;
|
||||
this.Builder = builder;
|
||||
}
|
||||
|
||||
public void WriteIndent() {
|
||||
String indentChars = this.Settings.IndentChars != null ? this.Settings.IndentChars : "";
|
||||
for (int i = 0; i < this.Indent; i++) {
|
||||
this.Builder.append(indentChars);
|
||||
}
|
||||
}
|
||||
|
||||
public ReaderStringContext clone() {
|
||||
ReaderStringContext varCopy = new ReaderStringContext();
|
||||
|
||||
varCopy.Indent = this.Indent;
|
||||
varCopy.Builder = this.Builder;
|
||||
varCopy.Settings = this.Settings.clone();
|
||||
varCopy.Separator = this.Separator;
|
||||
varCopy.NewLine = this.NewLine;
|
||||
|
||||
return varCopy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.json;
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java:
|
||||
///#pragma warning disable CA1051 // Do not declare visible instance fields
|
||||
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Java does not allow user-defined value types. The behavior of this class may differ
|
||||
// from the original:
|
||||
//ORIGINAL LINE: public readonly struct RowReaderJsonSettings
|
||||
//C# TO JAVA CONVERTER WARNING: Java has no equivalent to the C# readonly struct:
|
||||
public final class RowReaderJsonSettings {
|
||||
/**
|
||||
* If non-null then child objects are indented by one copy of this string per level.
|
||||
*/
|
||||
public String IndentChars;
|
||||
|
||||
/**
|
||||
* The quote character to use.
|
||||
* May be <see cref="lang:\""/> or {@link '}.
|
||||
*/
|
||||
public char QuoteChar;
|
||||
|
||||
|
||||
public RowReaderJsonSettings(String indentChars) {
|
||||
this(indentChars, '"');
|
||||
}
|
||||
|
||||
public RowReaderJsonSettings() {
|
||||
this(" ", '"');
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public RowReaderJsonSettings(string indentChars = " ", char quoteChar = '"')
|
||||
public RowReaderJsonSettings(String indentChars, char quoteChar) {
|
||||
this.IndentChars = indentChars;
|
||||
this.QuoteChar = quoteChar;
|
||||
}
|
||||
|
||||
public RowReaderJsonSettings clone() {
|
||||
RowReaderJsonSettings varCopy = new RowReaderJsonSettings();
|
||||
|
||||
varCopy.IndentChars = this.IndentChars;
|
||||
varCopy.QuoteChar = this.QuoteChar;
|
||||
|
||||
return varCopy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
/**
|
||||
* An optional interface that indicates a {@link LayoutType{T}} can also write using a {@link ReadOnlySequence{T}}.
|
||||
*
|
||||
* <typeparam name="TElement">The sub-element type to be written.</typeparam>
|
||||
*/
|
||||
public interface ILayoutSequenceWritable<TElement> extends ILayoutType {
|
||||
|
||||
Result WriteFixed(
|
||||
Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, ReadOnlySequence<TElement> value);
|
||||
|
||||
Result WriteSparse(
|
||||
Reference<RowBuffer> b, Reference<RowCursor> edit, ReadOnlySequence<TElement> value);
|
||||
|
||||
// C# TO JAVA CONVERTER NOTE:
|
||||
// Java does not support optional parameters, hence overloaded method(s) are created
|
||||
// ORIGINAL LINE:
|
||||
// Result WriteSparse(ref RowBuffer b, ref RowCursor edit, ReadOnlySequence<TElement> value, UpdateOptions
|
||||
// options = UpdateOptions.Upsert);
|
||||
|
||||
Result WriteSparse(
|
||||
Reference<RowBuffer> b, Reference<RowCursor> edit, ReadOnlySequence<TElement> value, UpdateOptions options);
|
||||
|
||||
Result WriteVariable(
|
||||
Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, ReadOnlySequence<TElement> value);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
/**
|
||||
* An optional interface that indicates a {@link LayoutType{T}} can also read using a {@link ReadOnlySpan{T}}
|
||||
*
|
||||
* <typeparam name="TElement">The sub-element type to be written.</typeparam>
|
||||
*/
|
||||
public interface ILayoutSpanReadable<TElement> extends ILayoutType {
|
||||
Result ReadFixed(
|
||||
Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, Out<ReadOnlySpan<TElement>> value);
|
||||
|
||||
Result ReadSparse(
|
||||
Reference<RowBuffer> b, Reference<RowCursor> scope, Out<ReadOnlySpan<TElement>> value);
|
||||
|
||||
Result ReadVariable(
|
||||
Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, Out<ReadOnlySpan<TElement>> value);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
/**
|
||||
* An optional interface that indicates a {@link LayoutType{T}} can also write using a
|
||||
* {@link ReadOnlySpan{T}}.
|
||||
*
|
||||
* <typeparam name="TElement">The sub-element type to be written.</typeparam>
|
||||
*/
|
||||
public interface ILayoutSpanWritable<TElement> extends ILayoutType {
|
||||
|
||||
Result WriteFixed(
|
||||
Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, ReadOnlySpan<TElement> value);
|
||||
|
||||
Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, ReadOnlySpan<TElement> value);
|
||||
|
||||
// C# TO JAVA CONVERTER NOTE:
|
||||
// Java does not support optional parameters, hence overloaded method(s) are created.
|
||||
// ORIGINAL LINE:
|
||||
// Result WriteSparse(ref RowBuffer b, ref RowCursor edit, ReadOnlySpan<TElement> value, UpdateOptions options = UpdateOptions.Upsert);
|
||||
|
||||
Result WriteSparse(
|
||||
Reference<RowBuffer> b, Reference<RowCursor> edit, ReadOnlySpan<TElement> value, UpdateOptions options);
|
||||
|
||||
Result WriteVariable(
|
||||
Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, ReadOnlySpan<TElement> value);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
/**
|
||||
* Marker interface for layout types.
|
||||
*/
|
||||
public interface ILayoutType {
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
/**
|
||||
* An optional interface that indicates a {@link LayoutType{T}} can also read using a {@link Utf8Span}.
|
||||
*/
|
||||
public interface ILayoutUtf8SpanReadable extends ILayoutType {
|
||||
|
||||
Result ReadFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, Out<Utf8Span> value);
|
||||
|
||||
Result ReadSparse(Reference<RowBuffer> b, Reference<RowCursor> scope, Out<Utf8Span> value);
|
||||
|
||||
Result ReadVariable(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, Out<Utf8Span> value);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
/**
|
||||
* An optional interface that indicates a {@link LayoutType{T}} can also write using a {@link Utf8Span}.
|
||||
*/
|
||||
public interface ILayoutUtf8SpanWritable extends ILayoutType {
|
||||
|
||||
Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, Utf8Span value);
|
||||
|
||||
Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, Utf8Span value);
|
||||
|
||||
// C# TO JAVA CONVERTER NOTE:
|
||||
// Java does not support optional parameters, hence overloaded method(s) are created.
|
||||
// ORIGINAL LINE:
|
||||
// Result WriteSparse(ref RowBuffer b, ref RowCursor edit, Utf8Span value, UpdateOptions options = UpdateOptions.Upsert);
|
||||
|
||||
Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, Utf8Span value, UpdateOptions options);
|
||||
|
||||
Result WriteVariable(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, Utf8Span value);
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Utf8String;
|
||||
import com.azure.data.cosmos.core.UtfAnyString;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.Namespace;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.Schema;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.StorageKind;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* A Layout describes the structure of a Hybrid Row
|
||||
* <p>
|
||||
* A layout indicates the number, order, and type of all schematized columns to be stored within a hybrid row. The
|
||||
* 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 {@link LayoutBuilder}.
|
||||
*
|
||||
* {@link Layout} is immutable.
|
||||
*/
|
||||
public final class Layout {
|
||||
|
||||
public static final Layout EMPTY = SystemSchema.LayoutResolver.resolve(SystemSchema.EmptySchemaId);
|
||||
|
||||
private final String name;
|
||||
private final int numBitmaskBytes;
|
||||
private final int numFixed;
|
||||
private final int numVariable;
|
||||
private final HashMap<Utf8String, LayoutColumn> pathMap;
|
||||
private final HashMap<String, LayoutColumn> pathStringMap;
|
||||
private final SchemaId schemaId;
|
||||
private final int size;
|
||||
private final StringTokenizer tokenizer;
|
||||
private final LayoutColumn[] topColumns;
|
||||
|
||||
public Layout(
|
||||
@Nonnull final String name, @Nonnull final SchemaId schemaId, final int numBitmaskBytes,
|
||||
final int minRequiredSize, @Nonnull final ArrayList<LayoutColumn> columns
|
||||
) {
|
||||
checkNotNull(name);
|
||||
checkNotNull(schemaId);
|
||||
checkNotNull(columns);
|
||||
|
||||
this.name = name;
|
||||
this.schemaId = schemaId;
|
||||
this.numBitmaskBytes = numBitmaskBytes;
|
||||
this.size = minRequiredSize;
|
||||
this.tokenizer = new StringTokenizer();
|
||||
this.pathMap = new HashMap<>(columns.size());
|
||||
this.pathStringMap = new HashMap<>(columns.size());
|
||||
|
||||
final ArrayList<LayoutColumn> top = new ArrayList<>(columns.size());
|
||||
int numFixed = 0;
|
||||
int numVariable = 0;
|
||||
|
||||
for (LayoutColumn column : columns) {
|
||||
|
||||
this.tokenizer().add(column.path());
|
||||
this.pathMap.put(column.fullPath(), column);
|
||||
this.pathStringMap.put(column.fullPath().toString(), column);
|
||||
|
||||
if (column.storage() == StorageKind.Fixed) {
|
||||
numFixed++;
|
||||
} else if (column.storage() == StorageKind.Variable) {
|
||||
numVariable++;
|
||||
}
|
||||
|
||||
if (column.parent() == null) {
|
||||
top.add(column);
|
||||
}
|
||||
}
|
||||
|
||||
this.numFixed = numFixed;
|
||||
this.numVariable = numVariable;
|
||||
this.topColumns = top.toArray(new LayoutColumn[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a column specification for a column with a matching path
|
||||
*
|
||||
* @param path path of the column to find
|
||||
* @return {@link LayoutColumn}, if a column with the {@code path} is found, {@link Optional#empty()}
|
||||
*/
|
||||
public Optional<LayoutColumn> tryFind(@Nonnull UtfAnyString path) {
|
||||
|
||||
checkNotNull(path);
|
||||
|
||||
if (path.isNull()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (path.isUtf8()) {
|
||||
return Optional.ofNullable(this.pathMap.get(path.toUtf8()));
|
||||
}
|
||||
|
||||
return Optional.ofNullable(this.pathStringMap.get(path.toUtf16()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a column specification for a column with a matching path.
|
||||
*
|
||||
* @param path The path of the column to find.
|
||||
* @return True if a column with the path is found, otherwise false.
|
||||
*/
|
||||
public Optional<LayoutColumn> tryFind(@Nonnull String path) {
|
||||
checkNotNull(path);
|
||||
return Optional.ofNullable(this.pathStringMap.get(path));
|
||||
}
|
||||
|
||||
/**
|
||||
* The set of top level columns defined in the layout (in left-to-right order).
|
||||
*/
|
||||
public ReadOnlySpan<LayoutColumn> columns() {
|
||||
return this.topColumns.AsSpan();
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the layout.
|
||||
* <p>
|
||||
* Usually this is the name of the {@link Schema} from which this {@link Layout} was generated.
|
||||
*/
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of bit mask bytes allocated within the layout.
|
||||
* <p>
|
||||
* A presence bit is allocated for each fixed and variable-length field. Sparse columns never have presence bits.
|
||||
* Fixed boolean allocate an additional bit from the bitmask to store their value.
|
||||
*/
|
||||
public int numBitmaskBytes() {
|
||||
return this.numBitmaskBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of fixed columns.
|
||||
*/
|
||||
public int numFixed() {
|
||||
return this.numFixed;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of variable-length columns.
|
||||
*/
|
||||
public int numVariable() {
|
||||
return this.numVariable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique identifier of the schema from which this {@link Layout} was generated.
|
||||
*/
|
||||
public SchemaId schemaId() {
|
||||
return this.schemaId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimum required size of a row of this layout.
|
||||
* <p>
|
||||
* This size excludes all sparse columns, and assumes all columns (including variable) are
|
||||
* null.
|
||||
*/
|
||||
public int size() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable diagnostic string representation of this {@link Layout}
|
||||
* <p>
|
||||
* This representation should only be used for debugging and diagnostic purposes.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("Layout:\n");
|
||||
sb.append(String.format("\tCount: %1$s\n", this.topColumns.length));
|
||||
sb.append(String.format("\tFixedSize: %1$s\n", this.size()));
|
||||
|
||||
for (LayoutColumn column : this.topColumns) {
|
||||
if (column.type().isFixed()) {
|
||||
if (column.type().isBoolean()) {
|
||||
sb.append(String.format("\t%1$s: %2$s @ %3$s:%4$s:%5$s\n", column.fullPath(), column.type().name(), column.getOffset(), column.getNullBit(), column.getBooleanBit()));
|
||||
} else {
|
||||
sb.append(String.format("\t%1$s: %2$s @ %3$s\n", column.fullPath(), column.type().name(), column.getOffset()));
|
||||
}
|
||||
} else {
|
||||
sb.append(String.format("\t%1$s: %2$s[%4$s] @ %3$s\n", column.fullPath(), column.type().name(), column.getOffset(), column.getSize()));
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A tokenizer for path strings.
|
||||
*/
|
||||
public StringTokenizer tokenizer() {
|
||||
return this.tokenizer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.ARRAY_SCOPE;
|
||||
import static com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.IMMUTABLE_ARRAY_SCOPE;
|
||||
|
||||
public final class LayoutArray extends LayoutIndexedScope {
|
||||
|
||||
public LayoutArray(final boolean immutable) {
|
||||
super(immutable ? IMMUTABLE_ARRAY_SCOPE : ARRAY_SCOPE, immutable, false, false, false, false);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.isImmutable() ? "im_array" : "array";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeScope(
|
||||
@Nonnull final RowBuffer b,
|
||||
@Nonnull final RowCursor edit,
|
||||
@Nonnull final TypeArgumentList typeArgs,
|
||||
@Nonnull Out<RowCursor> value
|
||||
) {
|
||||
return this.writeScope(b, edit, typeArgs, UpdateOptions.Upsert, value);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteScope(ref RowBuffer b, ref RowCursor edit, TypeArgumentList
|
||||
// typeArgs, out RowCursor value, UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, UpdateOptions options, Out<RowCursor> value) {
|
||||
Result result = prepareSparseWrite(b, edit, this.typeArg(), options);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
b.writeSparseArray(edit, this, options, value);
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public sealed class LayoutBinary : LayoutType<byte[]>, ILayoutSpanWritable<byte>,
|
||||
// ILayoutSpanReadable<byte>, ILayoutSequenceWritable<byte>
|
||||
public final class LayoutBinary extends LayoutType<byte[]> implements ILayoutSpanWritable<Byte>,
|
||||
ILayoutSpanReadable<Byte>, ILayoutSequenceWritable<Byte> {
|
||||
public LayoutBinary() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.BINARY, 0);
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "binary";
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, out
|
||||
// byte[] value)
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<byte[]> value) {
|
||||
ReadOnlySpan<Byte> span;
|
||||
// TODO: C# TO JAVA CONVERTER: The following method call contained an unresolved 'out' keyword - these
|
||||
// cannot be converted using the 'Out' helper class unless the method is within the code being modified:
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: Result r = this.ReadFixed(ref b, ref scope, col, out ReadOnlySpan<byte> span);
|
||||
Result r = this.ReadFixed(b, scope, column, out span);
|
||||
value.setAndGet((r == Result.Success) ? span.ToArray() :)
|
||||
default
|
||||
return r;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public Result ReadFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, out
|
||||
// ReadOnlySpan<byte> value)
|
||||
public Result ReadFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
Out<ReadOnlySpan<Byte>> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
checkArgument(col.getSize() >= 0);
|
||||
if (!b.get().readBit(scope.get().start(), col.getNullBit().clone())) {
|
||||
value.setAndGet(null);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadFixedBinary(scope.get().start() + col.getOffset(), col.getSize()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadSparse(ref RowBuffer b, ref RowCursor edit, out byte[] value)
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<byte[]> value) {
|
||||
ReadOnlySpan<Byte> span;
|
||||
// TODO: C# TO JAVA CONVERTER: The following method call contained an unresolved 'out' keyword - these cannot be converted using the 'Out' helper class unless the method is within the code being modified:
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: Result r = this.ReadSparse(ref b, ref edit, out ReadOnlySpan<byte> span);
|
||||
Result r = this.ReadSparse(b, edit, out span);
|
||||
value.setAndGet((r == Result.Success) ? span.ToArray() :)
|
||||
default
|
||||
return r;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public Result ReadSparse(ref RowBuffer b, ref RowCursor edit, out ReadOnlySpan<byte> value)
|
||||
public Result ReadSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, Out<ReadOnlySpan<Byte>> value) {
|
||||
Result result = LayoutType.prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseBinary(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadVariable(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, out
|
||||
// byte[] value)
|
||||
@Override
|
||||
public Result readVariable(RowBuffer b, RowCursor scope, LayoutColumn column
|
||||
, Out<byte[]> value) {
|
||||
ReadOnlySpan<Byte> span;
|
||||
// TODO: C# TO JAVA CONVERTER: The following method call contained an unresolved 'out' keyword - these
|
||||
// cannot be converted using the 'Out' helper class unless the method is within the code being modified:
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: Result r = this.ReadVariable(ref b, ref scope, col, out ReadOnlySpan<byte> span);
|
||||
Result r = this.ReadVariable(b, scope, column, out span);
|
||||
value.setAndGet((r == Result.Success) ? span.ToArray() :)
|
||||
default
|
||||
return r;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public Result ReadVariable(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, out
|
||||
// ReadOnlySpan<byte> value)
|
||||
public Result ReadVariable(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col
|
||||
, Out<ReadOnlySpan<Byte>> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), col.getNullBit().clone())) {
|
||||
value.setAndGet(null);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
int varOffset = b.get().computeVariableValueOffset(scope.get().layout(), scope.get().start(),
|
||||
col.getOffset());
|
||||
value.setAndGet(b.get().ReadVariableBinary(varOffset));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result WriteFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, byte[]
|
||||
// value)
|
||||
@Override
|
||||
public Result writeFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
byte[] value) {
|
||||
checkArgument(value != null);
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: return this.WriteFixed(ref b, ref scope, col, new ReadOnlySpan<byte>(value));
|
||||
return this.WriteFixed(b, scope, column, new ReadOnlySpan<Byte>(value));
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public Result WriteFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col,
|
||||
// ReadOnlySpan<byte> value)
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
ReadOnlySpan<Byte> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
checkArgument(col.getSize() >= 0);
|
||||
checkArgument(value.Length == col.getSize());
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteFixedBinary(scope.get().start() + col.getOffset(), value, col.getSize());
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public Result WriteFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col,
|
||||
// ReadOnlySequence<byte> value)
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
ReadOnlySequence<Byte> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
checkArgument(col.getSize() >= 0);
|
||||
checkArgument(value.Length == col.getSize());
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteFixedBinary(scope.get().start() + col.getOffset(), value, col.getSize());
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit, byte[] value) {
|
||||
return writeSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, byte[] value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit, byte[] value,
|
||||
UpdateOptions options) {
|
||||
checkArgument(value != null);
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: return this.WriteSparse(ref b, ref edit, new ReadOnlySpan<byte>(value), options);
|
||||
return this.WriteSparse(b, edit, new ReadOnlySpan<Byte>(value), options);
|
||||
}
|
||||
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit,
|
||||
ReadOnlySpan<Byte> value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public Result WriteSparse(ref RowBuffer b, ref RowCursor edit, ReadOnlySpan<byte> value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit,
|
||||
ReadOnlySpan<Byte> value, UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseBinary(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit,
|
||||
ReadOnlySequence<Byte> value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public Result WriteSparse(ref RowBuffer b, ref RowCursor edit, ReadOnlySequence<byte> value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit,
|
||||
ReadOnlySequence<Byte> value, UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseBinary(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result WriteVariable(ref RowBuffer b, ref RowCursor scope, LayoutColumn col,
|
||||
// byte[] value)
|
||||
@Override
|
||||
public Result writeVariable(Reference<RowBuffer> b, Reference<RowCursor> scope,
|
||||
LayoutColumn col, byte[] value) {
|
||||
checkArgument(value != null);
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: return this.WriteVariable(ref b, ref scope, col, new ReadOnlySpan<byte>(value));
|
||||
return this.WriteVariable(b, scope, col, new ReadOnlySpan<Byte>(value));
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public Result WriteVariable(ref RowBuffer b, ref RowCursor scope, LayoutColumn col,
|
||||
// ReadOnlySpan<byte> value)
|
||||
public Result WriteVariable(Reference<RowBuffer> b, Reference<RowCursor> scope,
|
||||
LayoutColumn col, ReadOnlySpan<Byte> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
int length = value.Length;
|
||||
if ((col.getSize() > 0) && (length > col.getSize())) {
|
||||
return Result.TooBig;
|
||||
}
|
||||
|
||||
boolean exists = b.get().readBit(scope.get().start(), col.getNullBit().clone());
|
||||
int varOffset = b.get().computeVariableValueOffset(scope.get().layout(), scope.get().start(),
|
||||
col.getOffset());
|
||||
int shift;
|
||||
Out<Integer> tempOut_shift = new Out<Integer>();
|
||||
b.get().WriteVariableBinary(varOffset, value, exists, tempOut_shift);
|
||||
shift = tempOut_shift.get();
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
scope.get().metaOffset(scope.get().metaOffset() + shift);
|
||||
scope.get().valueOffset(scope.get().valueOffset() + shift);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public Result WriteVariable(ref RowBuffer b, ref RowCursor scope, LayoutColumn col,
|
||||
// ReadOnlySequence<byte> value)
|
||||
public Result WriteVariable(Reference<RowBuffer> b, Reference<RowCursor> scope,
|
||||
LayoutColumn col, ReadOnlySequence<Byte> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
int length = (int)value.Length;
|
||||
if ((col.getSize() > 0) && (length > col.getSize())) {
|
||||
return Result.TooBig;
|
||||
}
|
||||
|
||||
boolean exists = b.get().readBit(scope.get().start(), col.getNullBit().clone());
|
||||
int varOffset = b.get().computeVariableValueOffset(scope.get().layout(), scope.get().start(),
|
||||
col.getOffset());
|
||||
int shift;
|
||||
Out<Integer> tempOut_shift = new Out<Integer>();
|
||||
b.get().WriteVariableBinary(varOffset, value, exists, tempOut_shift);
|
||||
shift = tempOut_shift.get();
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
scope.get().metaOffset(scope.get().metaOffset() + shift);
|
||||
scope.get().valueOffset(scope.get().valueOffset() + shift);
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutBit {
|
||||
/**
|
||||
* The empty bit.
|
||||
*/
|
||||
public static final LayoutBit INVALID = new LayoutBit(-1);
|
||||
|
||||
private final int index;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link LayoutBit} struct.
|
||||
*
|
||||
* @param index The zero-based offset into the layout bitmask.
|
||||
*/
|
||||
public LayoutBit(int index) {
|
||||
checkArgument(index >= -1);
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the division rounding up to the next whole number
|
||||
*
|
||||
* @param numerator The numerator to divide.
|
||||
* @param divisor The divisor to divide by.
|
||||
* @return The ceiling(numerator/divisor).
|
||||
*/
|
||||
public static int divCeiling(int numerator, int divisor) {
|
||||
return (numerator + (divisor - 1)) / divisor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero-based bit from the beginning of the byte that contains this bit
|
||||
* <p>
|
||||
* Also see {@link #offset} to identify relevant byte.
|
||||
*
|
||||
* @return The bit of the byte within the bitmask.
|
||||
*/
|
||||
public int bit() {
|
||||
return this.index() % LayoutTypes.BitsPerByte;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero-based offset into the layout bitmask
|
||||
*/
|
||||
public int index() {
|
||||
return this.index;
|
||||
}
|
||||
|
||||
public boolean isInvalid() {
|
||||
return this.index == INVALID.index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the zero-based byte offset from the beginning of the row or scope that contains the bit from the bitmask
|
||||
* <p>
|
||||
* Also see {@link #bit} to identify.
|
||||
*
|
||||
* @param offset The byte offset from the beginning of the row where the scope begins.
|
||||
* @return The byte offset containing this bit.
|
||||
*/
|
||||
public int offset(int offset) {
|
||||
return offset + (this.index() / LayoutTypes.BitsPerByte);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return other instanceof LayoutBit && this.equals((LayoutBit)other);
|
||||
}
|
||||
|
||||
public boolean equals(LayoutBit other) {
|
||||
return other != null && this.index() == other.index();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Integer.valueOf(this.index()).hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates layout bits from a bitmask.
|
||||
*/
|
||||
static class Allocator {
|
||||
/**
|
||||
* The next bit to allocate.
|
||||
*/
|
||||
private int next;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link Allocator} class.
|
||||
*/
|
||||
public Allocator() {
|
||||
this.next = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of bytes needed to hold all bits so far allocated.
|
||||
*/
|
||||
public final int getNumBytes() {
|
||||
return LayoutBit.divCeiling(this.next, LayoutTypes.BitsPerByte);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a new bit from the bitmask.
|
||||
*
|
||||
* @return The allocated bit.
|
||||
*/
|
||||
public final LayoutBit Allocate() {
|
||||
return new LayoutBit(this.next++);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutBoolean extends LayoutType<Boolean> {
|
||||
public LayoutBoolean(boolean value) {
|
||||
super(, 0);
|
||||
}
|
||||
|
||||
public boolean isBoolean() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "bool";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Boolean> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(false);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().readBit(scope.get().start(), column.getBooleanBit().clone()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<Boolean> value) {
|
||||
Result result = LayoutType.prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseBool(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
boolean value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
b.get().SetBit(scope.get().start(), col.getBooleanBit().clone());
|
||||
} else {
|
||||
b.get().UnsetBit(scope.get().start(), col.getBooleanBit().clone());
|
||||
}
|
||||
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, bool value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, boolean value,
|
||||
UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseBool(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, boolean value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.StorageKind;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Stack;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutBuilder {
|
||||
private LayoutBit.Allocator bitAllocator;
|
||||
private ArrayList<LayoutColumn> fixedColumns;
|
||||
private int fixedCount;
|
||||
private int fixedSize;
|
||||
private String name;
|
||||
private SchemaId schemaId;
|
||||
private Stack<LayoutColumn> scope;
|
||||
private ArrayList<LayoutColumn> sparseColumns;
|
||||
private int sparseCount;
|
||||
private ArrayList<LayoutColumn> varColumns;
|
||||
private int varCount;
|
||||
|
||||
// [ <present bits>
|
||||
// <bool bits>
|
||||
// <fixed_1> <fixed_2> ... <fixed_n>
|
||||
// <var_1> <var_2> ... <var_n>
|
||||
// <sparse_1> <sparse_2> ... <sparse_o>
|
||||
// ]
|
||||
public LayoutBuilder(String name, SchemaId schemaId) {
|
||||
this.name = name;
|
||||
this.schemaId = schemaId;
|
||||
this.reset();
|
||||
}
|
||||
|
||||
public void addFixedColumn(String path, LayoutType type, boolean nullable, int length) {
|
||||
|
||||
checkArgument(length >= 0);
|
||||
checkArgument(!type.isVarint());
|
||||
|
||||
LayoutColumn column;
|
||||
if (type.isNull()) {
|
||||
checkArgument(nullable);
|
||||
LayoutBit nullBit = this.bitAllocator.Allocate();
|
||||
column = new LayoutColumn(path, type, TypeArgumentList.EMPTY, StorageKind.Fixed, this.parent(),
|
||||
this.fixedCount, 0, nullBit, LayoutBit.INVALID, 0);
|
||||
} else if (type.isBoolean()) {
|
||||
LayoutBit nullBit = nullable ? this.bitAllocator.Allocate() : LayoutBit.INVALID;
|
||||
LayoutBit boolbit = this.bitAllocator.Allocate();
|
||||
column = new LayoutColumn(path, type, TypeArgumentList.EMPTY, StorageKind.Fixed, this.parent(),
|
||||
this.fixedCount, 0, nullBit, boolbit, 0);
|
||||
} else {
|
||||
LayoutBit nullBit = nullable ? this.bitAllocator.Allocate() : LayoutBit.INVALID;
|
||||
column = new LayoutColumn(path, type, TypeArgumentList.EMPTY, StorageKind.Fixed, this.parent(),
|
||||
this.fixedCount, this.fixedSize, nullBit, LayoutBit.INVALID, length);
|
||||
|
||||
this.fixedSize += type.isFixed() ? type.size() : length;
|
||||
}
|
||||
|
||||
this.fixedCount++;
|
||||
this.fixedColumns.add(column);
|
||||
}
|
||||
|
||||
public void addObjectScope(String path, LayoutType type) {
|
||||
|
||||
LayoutColumn column = new LayoutColumn(path, type, TypeArgumentList.EMPTY, StorageKind.Sparse, this.parent(),
|
||||
this.sparseCount, -1, LayoutBit.INVALID, LayoutBit.INVALID, 0);
|
||||
|
||||
this.sparseCount++;
|
||||
this.sparseColumns.add(column);
|
||||
this.scope.push(column);
|
||||
}
|
||||
|
||||
public void addSparseColumn(String path, LayoutType type) {
|
||||
|
||||
LayoutColumn column = new LayoutColumn(path, type, TypeArgumentList.EMPTY, StorageKind.Sparse, this.parent(),
|
||||
this.sparseCount, -1, LayoutBit.INVALID, LayoutBit.INVALID, 0);
|
||||
|
||||
this.sparseCount++;
|
||||
this.sparseColumns.add(column);
|
||||
}
|
||||
|
||||
public void addTypedScope(String path, LayoutType type, TypeArgumentList typeArgs) {
|
||||
|
||||
LayoutColumn col = new LayoutColumn(path, type, typeArgs, StorageKind.Sparse, this.parent(), this.sparseCount,
|
||||
-1, LayoutBit.INVALID, LayoutBit.INVALID, 0);
|
||||
|
||||
this.sparseCount++;
|
||||
this.sparseColumns.add(col);
|
||||
}
|
||||
|
||||
public void addVariableColumn(String path, LayoutType type, int length) {
|
||||
|
||||
checkArgument(length >= 0);
|
||||
checkArgument(type.allowVariable());
|
||||
|
||||
LayoutColumn column = new LayoutColumn(path, type, TypeArgumentList.EMPTY, StorageKind.Variable, this.parent(),
|
||||
this.varCount, this.varCount, this.bitAllocator.Allocate(), LayoutBit.INVALID, length);
|
||||
|
||||
this.varCount++;
|
||||
this.varColumns.add(column);
|
||||
}
|
||||
|
||||
public Layout build() {
|
||||
// Compute offset deltas. Offset bools by the present byte count, and fixed fields by the sum of the present
|
||||
// and bool count.
|
||||
int fixedDelta = this.bitAllocator.getNumBytes();
|
||||
int varIndexDelta = this.fixedCount;
|
||||
|
||||
// Update the fixedColumns with the delta before freezing them.
|
||||
ArrayList<LayoutColumn> updatedColumns =
|
||||
new ArrayList<LayoutColumn>(this.fixedColumns.size() + this.varColumns.size());
|
||||
|
||||
for (LayoutColumn column : this.fixedColumns) {
|
||||
column.offset(column.offset() + fixedDelta);
|
||||
updatedColumns.add(column);
|
||||
}
|
||||
|
||||
for (LayoutColumn column : this.varColumns) {
|
||||
// Adjust variable column indexes such that they begin immediately following the last fixed column.
|
||||
column.index(column.index() + varIndexDelta);
|
||||
updatedColumns.add(column);
|
||||
}
|
||||
|
||||
updatedColumns.addAll(this.sparseColumns);
|
||||
|
||||
Layout layout = new Layout(this.name, this.schemaId, this.bitAllocator.getNumBytes(), this.fixedSize + fixedDelta, updatedColumns);
|
||||
this.reset();
|
||||
return layout;
|
||||
}
|
||||
|
||||
public void EndObjectScope() {
|
||||
checkArgument(this.scope.size() > 0);
|
||||
this.scope.pop();
|
||||
}
|
||||
|
||||
private LayoutColumn parent() {
|
||||
if (this.scope.empty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.scope.peek();
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
this.bitAllocator = new LayoutBit.Allocator();
|
||||
this.fixedSize = 0;
|
||||
this.fixedCount = 0;
|
||||
this.fixedColumns = new ArrayList<LayoutColumn>();
|
||||
this.varCount = 0;
|
||||
this.varColumns = new ArrayList<LayoutColumn>();
|
||||
this.sparseCount = 0;
|
||||
this.sparseColumns = new ArrayList<LayoutColumn>();
|
||||
this.scope = new Stack<LayoutColumn>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java:
|
||||
///#pragma warning disable CA1028 // Enum Storage should be Int32
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Type coded used in the binary encoding to indicate the formatting of succeeding bytes.
|
||||
*/
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public enum LayoutCode : byte
|
||||
public enum LayoutCode {
|
||||
|
||||
INVALID((byte)0),
|
||||
|
||||
NULL((byte)1),
|
||||
BOOLEAN_FALSE((byte)2),
|
||||
BOOLEAN((byte)3),
|
||||
|
||||
INT_8((byte)5),
|
||||
INT_16((byte)6),
|
||||
INT_32((byte)7),
|
||||
INT_64((byte)8),
|
||||
UINT_8((byte)9),
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: UInt16 = 10,
|
||||
UINT_16((byte)10),
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: UInt32 = 11,
|
||||
UINT_32((byte)11),
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: UInt64 = 12,
|
||||
UINT_64((byte)12),
|
||||
VAR_INT((byte)13),
|
||||
VAR_UINT((byte)14),
|
||||
|
||||
FLOAT_32((byte)15),
|
||||
FLOAT_64((byte)16),
|
||||
DECIMAL((byte)17),
|
||||
|
||||
DATE_TIME((byte)18),
|
||||
GUID((byte)19),
|
||||
|
||||
UTF_8((byte)20),
|
||||
BINARY((byte)21),
|
||||
|
||||
FLOAT_128((byte)22),
|
||||
UNIX_DATE_TIME((byte)23),
|
||||
MONGODB_OBJECT_ID((byte)24),
|
||||
|
||||
OBJECT_SCOPE((byte)30),
|
||||
IMMUTABLE_OBJECT_SCOPE((byte)31),
|
||||
ARRAY_SCOPE((byte)32),
|
||||
IMMUTABLE_ARRAY_SCOPE((byte)33),
|
||||
TYPED_ARRAY_SCOPE((byte)34),
|
||||
IMMUTABLE_TYPED_ARRAY_SCOPE((byte)35),
|
||||
TUPLE_SCOPE((byte)36),
|
||||
IMMUTABLE_TUPLE_SCOPE((byte)37),
|
||||
TYPED_TUPLE_SCOPE((byte)38),
|
||||
IMMUTABLE_TYPED_TUPLE_SCOPE((byte)39),
|
||||
MAP_SCOPE((byte)40),
|
||||
IMMUTABLE_MAP_SCOPE((byte)41),
|
||||
TYPED_MAP_SCOPE((byte)42),
|
||||
IMMUTABLE_TYPED_MAP_SCOPE((byte)43),
|
||||
SET_SCOPE((byte)44),
|
||||
IMMUTABLE_SET_SCOPE((byte)45),
|
||||
TYPED_SET_SCOPE((byte)46),
|
||||
IMMUTABLE_TYPED_SET_SCOPE((byte)47),
|
||||
NULLABLE_SCOPE((byte)48),
|
||||
IMMUTABLE_NULLABLE_SCOPE((byte)49),
|
||||
TAGGED_SCOPE((byte)50),
|
||||
IMMUTABLE_TAGGED_SCOPE((byte)51),
|
||||
TAGGED2_SCOPE((byte)52),
|
||||
IMMUTABLE_TAGGED2_SCOPE((byte)53),
|
||||
|
||||
/**
|
||||
* Nested row.
|
||||
*/
|
||||
SCHEMA((byte)68),
|
||||
IMMUTABLE_SCHEMA((byte)69),
|
||||
|
||||
END_SCOPE((byte)70);
|
||||
|
||||
public static final int SIZE = Byte.SIZE;
|
||||
|
||||
private static Map<Byte, LayoutCode> mappings;
|
||||
private byte value;
|
||||
|
||||
LayoutCode(byte value) {
|
||||
this.value = value;
|
||||
mappings().put(value, this);
|
||||
}
|
||||
|
||||
public byte value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static LayoutCode forValue(byte value) {
|
||||
return mappings().get(value);
|
||||
}
|
||||
|
||||
private static Map<Byte, LayoutCode> mappings() {
|
||||
if (mappings == null) {
|
||||
synchronized (LayoutCode.class) {
|
||||
if (mappings == null) {
|
||||
mappings = new HashMap<Byte, LayoutCode>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return mappings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
public final class LayoutCodeTraits {
|
||||
/**
|
||||
* Returns true if the type code indicates that, even within a typed scope, this element type
|
||||
* always requires a type code (because the value itself is in the type code).
|
||||
*
|
||||
* @param code The element type code.
|
||||
*/
|
||||
public static boolean AlwaysRequiresTypeCode(LayoutCode code) {
|
||||
return (code == LayoutCode.BOOLEAN) || (code == LayoutCode.BOOLEAN_FALSE) || (code == LayoutCode.NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a canonicalized version of the layout code.
|
||||
* <p>
|
||||
* Some codes (e.g. {@link LayoutCode.Boolean} use multiple type codes to also encode
|
||||
* values. This function converts actual value based code into the canonicalized type code for schema
|
||||
* comparisons.
|
||||
*
|
||||
* @param code The code to canonicalize.
|
||||
*/
|
||||
public static LayoutCode Canonicalize(LayoutCode code) {
|
||||
return (code == LayoutCode.BOOLEAN_FALSE) ? LayoutCode.BOOLEAN : code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the same scope code without the immutable bit set.
|
||||
*
|
||||
* @param code The scope type code.
|
||||
*/
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [MethodImpl(MethodImplOptions.AggressiveInlining)] public static LayoutCode ClearImmutableBit
|
||||
// (LayoutCode code)
|
||||
public static LayoutCode ClearImmutableBit(LayoutCode code) {
|
||||
return code.value() & LayoutCode.forValue((byte)0xFE).value();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Utf8String;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.StorageKind;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Strings.lenientFormat;
|
||||
|
||||
public final class LayoutColumn {
|
||||
|
||||
private final LayoutBit booleanBit;
|
||||
private final Utf8String fullPath;
|
||||
private final LayoutBit nullBit;
|
||||
private final LayoutColumn parent;
|
||||
private final Utf8String path;
|
||||
private final int size;
|
||||
private final StorageKind storage;
|
||||
private final LayoutType type;
|
||||
private final TypeArgument typeArg;
|
||||
private final TypeArgumentList typeArgs;
|
||||
|
||||
private int index;
|
||||
private int offset;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link LayoutColumn} class
|
||||
*
|
||||
* @param path The path to the field relative to parent scope.
|
||||
* @param type Type of the field.
|
||||
* @param typeArgs For types with generic parameters (e.g. {@link LayoutTuple}, the type parameters.
|
||||
* @param storage Storage encoding of the field.
|
||||
* @param parent The layout of the parent scope, if a nested column.
|
||||
* @param index zero-based column index.
|
||||
* @param offset zero-based Offset from beginning of serialization.
|
||||
* @param nullBit zero-based index into the bit mask for the null bit.
|
||||
* @param booleanBit For bool fields, zero-based index into the bit mask for the boolean value.
|
||||
* @param length For variable length types the length, otherwise {@code 0}.
|
||||
*/
|
||||
public LayoutColumn(
|
||||
@Nonnull final String path, @Nonnull final LayoutType type, @Nonnull final TypeArgumentList typeArgs,
|
||||
@Nonnull final StorageKind storage, final LayoutColumn parent, int index, int offset,
|
||||
@Nonnull final LayoutBit nullBit, @Nonnull final LayoutBit booleanBit, int length) {
|
||||
|
||||
checkNotNull(path);
|
||||
checkNotNull(type);
|
||||
checkNotNull(typeArgs);
|
||||
checkNotNull(storage);
|
||||
checkNotNull(nullBit);
|
||||
checkNotNull(booleanBit);
|
||||
|
||||
this.path = Utf8String.transcodeUtf16(path);
|
||||
this.fullPath = Utf8String.transcodeUtf16(fullPath(parent, path));
|
||||
this.type = type;
|
||||
this.typeArgs = typeArgs;
|
||||
this.typeArg = new TypeArgument(type, typeArgs);
|
||||
this.storage = storage;
|
||||
this.parent = parent;
|
||||
this.index = index;
|
||||
this.offset = offset;
|
||||
this.nullBit = nullBit;
|
||||
this.booleanBit = booleanBit;
|
||||
this.size = this.typeArg().type().isFixed() ? type.size() : length;
|
||||
}
|
||||
|
||||
/**
|
||||
* For bool fields, zero-based index into the bit mask for the bool value.
|
||||
*/
|
||||
public @Nonnull LayoutBit booleanBit() {
|
||||
return this.booleanBit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full logical path of the field within the row
|
||||
* <p>
|
||||
* Paths are expressed in dotted notation: e.g. a relative {@link #path} of 'b.c' within the scope 'a' yields a
|
||||
* {@link #fullPath} of 'a.b.c'.
|
||||
*/
|
||||
public @Nonnull Utf8String fullPath() {
|
||||
return this.fullPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero-based index of the column within the structure
|
||||
* <p>
|
||||
* This value also indicates which presence bit controls this column.
|
||||
*/
|
||||
public int index() {
|
||||
return this.index;
|
||||
}
|
||||
|
||||
/**
|
||||
* For nullable fields, the zero-based index into the bit mask for the null bit
|
||||
*/
|
||||
public @Nonnull LayoutBit nullBit() {
|
||||
return this.nullBit;
|
||||
}
|
||||
|
||||
/**
|
||||
* If {@link #storage} equals {@link StorageKind#Fixed} then the byte offset to the field location.
|
||||
* <p>
|
||||
* If {@link #storage} equals {@link StorageKind#Variable} then the zero-based index of the field from the
|
||||
* beginning of the variable length segment.
|
||||
* <p>
|
||||
* For all other values of {@link #storage}, {@link #offset} is ignored.
|
||||
*/
|
||||
public int offset() {
|
||||
return this.offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Layout of the parent scope, if a nested column, otherwise null.
|
||||
*/
|
||||
public LayoutColumn parent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* The relative path of the field within its parent scope.
|
||||
* <p>
|
||||
* Paths are expressed in dotted notation: e.g. a relative {@link #path} of 'b.c' within the scope 'a' yields a
|
||||
* {@link #fullPath} of 'a.b.c'.
|
||||
*/
|
||||
public @Nonnull Utf8String path() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
/**
|
||||
* If {@link LayoutType#isBoolean} then the zero-based extra index within the bool byte
|
||||
* holding the value of this type, otherwise must be 0.
|
||||
*/
|
||||
public int size() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* The storage kind of the field.
|
||||
*/
|
||||
public @Nonnull StorageKind storage() {
|
||||
return this.storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* The physical layout type of the field.
|
||||
*/
|
||||
public @Nonnull LayoutType type() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The full logical type
|
||||
*/
|
||||
public @Nonnull TypeArgument typeArg() {
|
||||
return this.typeArg;
|
||||
}
|
||||
|
||||
/**
|
||||
* For types with generic parameters (e.g. {@link LayoutTuple}, the type parameters.
|
||||
*/
|
||||
public @Nonnull TypeArgumentList typeArgs() {
|
||||
return this.typeArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* The physical layout type of the field cast to the specified type.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public @Nonnull <T extends ILayoutType> T typeAs() {
|
||||
return (T) this.type().typeAs();
|
||||
}
|
||||
|
||||
LayoutColumn index(int value) {
|
||||
this.index = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
LayoutColumn offset(int value) {
|
||||
this.offset = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the full logical path to the column
|
||||
*
|
||||
* @param parent The layout of the parent scope, if a nested column, otherwise null
|
||||
* @param path The path to the field relative to parent scope
|
||||
* @return The full logical path
|
||||
*/
|
||||
private static @Nonnull String fullPath(final LayoutColumn parent, @Nonnull final String path) {
|
||||
|
||||
if (parent != null) {
|
||||
switch (LayoutCodeTraits.ClearImmutableBit(parent.type().layoutCode())) {
|
||||
case OBJECT_SCOPE:
|
||||
case SCHEMA:
|
||||
return parent.fullPath().toString() + "." + path;
|
||||
case ARRAY_SCOPE:
|
||||
case TYPED_ARRAY_SCOPE:
|
||||
case TYPED_SET_SCOPE:
|
||||
case TYPED_MAP_SCOPE:
|
||||
return parent.fullPath().toString() + "[]" + path;
|
||||
default:
|
||||
final String message = lenientFormat("Parent scope type not supported: %s", parent.type().layoutCode());
|
||||
throw new IllegalStateException(message);
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [Serializable][ExcludeFromCodeCoverage] public sealed class LayoutCompilationException : Exception
|
||||
public final class LayoutCompilationException extends RuntimeException implements Serializable {
|
||||
public LayoutCompilationException() {
|
||||
}
|
||||
|
||||
public LayoutCompilationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public LayoutCompilationException(String message, RuntimeException innerException) {
|
||||
super(message, innerException);
|
||||
}
|
||||
|
||||
private LayoutCompilationException(SerializationInfo info, StreamingContext context) {
|
||||
super(info, context);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,368 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.ArrayPropertyType;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.MapPropertyType;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.Namespace;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.ObjectPropertyType;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.PrimitivePropertyType;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.Property;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.PropertyType;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.Schema;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.ScopePropertyType;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.SetPropertyType;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.TaggedPropertyType;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.TuplePropertyType;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.TypeKind;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.UdtPropertyType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
/**
|
||||
* Converts a logical schema into a physical layout.
|
||||
*/
|
||||
public final class LayoutCompiler {
|
||||
/**
|
||||
* Compiles a logical schema into a physical layout that can be used to read and write rows.
|
||||
*
|
||||
* @param ns The namespace within which <paramref name="schema" /> is defined.
|
||||
* @param schema The logical schema to produce a layout for.
|
||||
* @return The layout for the schema.
|
||||
*/
|
||||
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));
|
||||
|
||||
LayoutBuilder builder = new LayoutBuilder(schema.getName(), schema.getSchemaId().clone());
|
||||
LayoutCompiler.AddProperties(builder, ns, LayoutCode.SCHEMA, schema.getProperties());
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static void AddProperties(LayoutBuilder builder, Namespace ns, LayoutCode scope,
|
||||
ArrayList<Property> properties) {
|
||||
for (Property p : properties) {
|
||||
TypeArgumentList typeArgs = new TypeArgumentList();
|
||||
Out<TypeArgumentList> tempOut_typeArgs =
|
||||
new Out<TypeArgumentList>();
|
||||
LayoutType type = LayoutCompiler.LogicalToPhysicalType(ns, p.getPropertyType(), tempOut_typeArgs);
|
||||
typeArgs = tempOut_typeArgs.get();
|
||||
switch (LayoutCodeTraits.ClearImmutableBit(type.LayoutCode)) {
|
||||
case OBJECT_SCOPE: {
|
||||
if (!p.getPropertyType().getNullable()) {
|
||||
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());
|
||||
builder.EndObjectScope();
|
||||
break;
|
||||
}
|
||||
|
||||
case ARRAY_SCOPE:
|
||||
case TYPED_ARRAY_SCOPE:
|
||||
case SET_SCOPE:
|
||||
case TYPED_SET_SCOPE:
|
||||
case MAP_SCOPE:
|
||||
case TYPED_MAP_SCOPE:
|
||||
case TUPLE_SCOPE:
|
||||
case TYPED_TUPLE_SCOPE:
|
||||
case TAGGED_SCOPE:
|
||||
case TAGGED2_SCOPE:
|
||||
case SCHEMA: {
|
||||
if (!p.getPropertyType().getNullable()) {
|
||||
throw new LayoutCompilationException("Non-nullable sparse column are not supported.");
|
||||
}
|
||||
|
||||
builder.addTypedScope(p.getPath(), type, typeArgs.clone());
|
||||
break;
|
||||
}
|
||||
|
||||
case NULLABLE_SCOPE: {
|
||||
throw new LayoutCompilationException("Nullables cannot be explicitly declared as columns.");
|
||||
}
|
||||
|
||||
default: {
|
||||
PropertyType tempVar = p.getPropertyType();
|
||||
PrimitivePropertyType pp = tempVar instanceof PrimitivePropertyType ?
|
||||
(PrimitivePropertyType)tempVar : null;
|
||||
if (pp != null) {
|
||||
switch (pp.getStorage()) {
|
||||
case Fixed:
|
||||
if (LayoutCodeTraits.ClearImmutableBit(scope) != LayoutCode.SCHEMA) {
|
||||
throw new LayoutCompilationException("Cannot have fixed storage within a sparse " +
|
||||
"scope.");
|
||||
}
|
||||
|
||||
if (type.getIsNull() && !pp.getNullable()) {
|
||||
throw new LayoutCompilationException("Non-nullable null columns are not supported" +
|
||||
".");
|
||||
}
|
||||
|
||||
builder.addFixedColumn(p.getPath(), type, pp.getNullable(), pp.getLength());
|
||||
break;
|
||||
case Variable:
|
||||
if (LayoutCodeTraits.ClearImmutableBit(scope) != LayoutCode.SCHEMA) {
|
||||
throw new LayoutCompilationException("Cannot have variable storage within a " +
|
||||
"sparse scope.");
|
||||
}
|
||||
|
||||
if (!pp.getNullable()) {
|
||||
throw new LayoutCompilationException("Non-nullable variable columns are not " +
|
||||
"supported.");
|
||||
}
|
||||
|
||||
builder.addVariableColumn(p.getPath(), type, pp.getLength());
|
||||
break;
|
||||
case Sparse:
|
||||
if (!pp.getNullable()) {
|
||||
throw new LayoutCompilationException("Non-nullable sparse columns are not " +
|
||||
"supported.");
|
||||
}
|
||||
|
||||
builder.addSparseColumn(p.getPath(), type);
|
||||
break;
|
||||
default:
|
||||
throw new LayoutCompilationException(String.format("Unknown storage specification: " +
|
||||
"%1$s", pp.getStorage()));
|
||||
}
|
||||
} else {
|
||||
throw new LayoutCompilationException(String.format("Unknown property type: %1$s",
|
||||
type.getName()));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static LayoutType LogicalToPhysicalType(Namespace ns, PropertyType logicalType,
|
||||
Out<TypeArgumentList> typeArgs) {
|
||||
typeArgs.setAndGet(TypeArgumentList.EMPTY);
|
||||
boolean tempVar =
|
||||
(logicalType instanceof ScopePropertyType ? (ScopePropertyType)logicalType : null).getImmutable();
|
||||
boolean immutable =
|
||||
(logicalType instanceof ScopePropertyType ? (ScopePropertyType)logicalType : null) == null ? null :
|
||||
tempVar != null && tempVar;
|
||||
|
||||
switch (logicalType.getType()) {
|
||||
case Null:
|
||||
return LayoutType.Null;
|
||||
case Boolean:
|
||||
return LayoutType.Boolean;
|
||||
case Int8:
|
||||
return LayoutType.Int8;
|
||||
case Int16:
|
||||
return LayoutType.Int16;
|
||||
case Int32:
|
||||
return LayoutType.Int32;
|
||||
case Int64:
|
||||
return LayoutType.Int64;
|
||||
case UInt8:
|
||||
return LayoutType.UInt8;
|
||||
case UInt16:
|
||||
return LayoutType.UInt16;
|
||||
case UInt32:
|
||||
return LayoutType.UInt32;
|
||||
case UInt64:
|
||||
return LayoutType.UInt64;
|
||||
case Float32:
|
||||
return LayoutType.Float32;
|
||||
case Float64:
|
||||
return LayoutType.Float64;
|
||||
case Float128:
|
||||
return LayoutType.Float128;
|
||||
case Decimal:
|
||||
return LayoutType.Decimal;
|
||||
case DateTime:
|
||||
return LayoutType.DateTime;
|
||||
case UnixDateTime:
|
||||
return LayoutType.UnixDateTime;
|
||||
case Guid:
|
||||
return LayoutType.Guid;
|
||||
case MongoDbObjectId:
|
||||
return LayoutType.MongoDbObjectId;
|
||||
case Utf8:
|
||||
return LayoutType.Utf8;
|
||||
case Binary:
|
||||
return LayoutType.Binary;
|
||||
case VarInt:
|
||||
return LayoutType.VarInt;
|
||||
case VarUInt:
|
||||
return LayoutType.VarUInt;
|
||||
|
||||
case Object:
|
||||
return immutable ? LayoutType.ImmutableObject : LayoutType.Object;
|
||||
case Array:
|
||||
ArrayPropertyType ap = (ArrayPropertyType)logicalType;
|
||||
if ((ap.getItems() != null) && (ap.getItems().getType() != TypeKind.Any)) {
|
||||
TypeArgumentList itemTypeArgs = new TypeArgumentList();
|
||||
Out<TypeArgumentList> tempOut_itemTypeArgs = new Out<TypeArgumentList>();
|
||||
LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, ap.getItems(), tempOut_itemTypeArgs);
|
||||
itemTypeArgs = tempOut_itemTypeArgs.get();
|
||||
if (ap.getItems().getNullable()) {
|
||||
itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
|
||||
itemTypeArgs.clone()) });
|
||||
itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
|
||||
}
|
||||
|
||||
typeArgs.setAndGet(new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
|
||||
itemTypeArgs.clone()) }));
|
||||
return immutable ? LayoutType.ImmutableTypedArray : LayoutType.TypedArray;
|
||||
}
|
||||
|
||||
return immutable ? LayoutType.ImmutableArray : LayoutType.Array;
|
||||
case Set:
|
||||
SetPropertyType sp = (SetPropertyType)logicalType;
|
||||
if ((sp.getItems() != null) && (sp.getItems().getType() != TypeKind.Any)) {
|
||||
TypeArgumentList itemTypeArgs = new TypeArgumentList();
|
||||
Out<TypeArgumentList> tempOut_itemTypeArgs2 = new Out<TypeArgumentList>();
|
||||
LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, sp.getItems(),
|
||||
tempOut_itemTypeArgs2);
|
||||
itemTypeArgs = tempOut_itemTypeArgs2.get();
|
||||
if (sp.getItems().getNullable()) {
|
||||
itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
|
||||
itemTypeArgs.clone()) });
|
||||
itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
|
||||
}
|
||||
|
||||
typeArgs.setAndGet(new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
|
||||
itemTypeArgs.clone()) }));
|
||||
return immutable ? LayoutType.ImmutableTypedSet : LayoutType.TypedSet;
|
||||
}
|
||||
|
||||
// TODO(283638): implement sparse set.
|
||||
throw new LayoutCompilationException(String.format("Unknown property type: %1$s",
|
||||
logicalType.getType()));
|
||||
|
||||
case Map:
|
||||
MapPropertyType mp = (MapPropertyType)logicalType;
|
||||
if ((mp.getKeys() != null) && (mp.getKeys().getType() != TypeKind.Any) && (mp.getValues() != null) && (mp.getValues().getType() != TypeKind.Any)) {
|
||||
TypeArgumentList keyTypeArgs = new TypeArgumentList();
|
||||
Out<TypeArgumentList> tempOut_keyTypeArgs = new Out<TypeArgumentList>();
|
||||
LayoutType keyType = LayoutCompiler.LogicalToPhysicalType(ns, mp.getKeys(), tempOut_keyTypeArgs);
|
||||
keyTypeArgs = tempOut_keyTypeArgs.get();
|
||||
if (mp.getKeys().getNullable()) {
|
||||
keyTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(keyType,
|
||||
keyTypeArgs.clone()) });
|
||||
keyType = keyType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
|
||||
}
|
||||
|
||||
TypeArgumentList valueTypeArgs = new TypeArgumentList();
|
||||
Out<TypeArgumentList> tempOut_valueTypeArgs = new Out<TypeArgumentList>();
|
||||
LayoutType valueType = LayoutCompiler.LogicalToPhysicalType(ns, mp.getValues(),
|
||||
tempOut_valueTypeArgs);
|
||||
valueTypeArgs = tempOut_valueTypeArgs.get();
|
||||
if (mp.getValues().getNullable()) {
|
||||
valueTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(valueType,
|
||||
valueTypeArgs.clone()) });
|
||||
valueType = valueType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
|
||||
}
|
||||
|
||||
typeArgs.setAndGet(new TypeArgumentList(new TypeArgument[]
|
||||
{
|
||||
new TypeArgument(keyType, keyTypeArgs.clone()),
|
||||
new TypeArgument(valueType, valueTypeArgs.clone())
|
||||
}));
|
||||
return immutable ? LayoutType.ImmutableTypedMap : LayoutType.TypedMap;
|
||||
}
|
||||
|
||||
// TODO(283638): implement sparse map.
|
||||
throw new LayoutCompilationException(String.format("Unknown property type: %1$s",
|
||||
logicalType.getType()));
|
||||
|
||||
case Tuple:
|
||||
TuplePropertyType tp = (TuplePropertyType)logicalType;
|
||||
TypeArgument[] args = new TypeArgument[tp.getItems().size()];
|
||||
for (int i = 0; i < tp.getItems().size(); i++) {
|
||||
TypeArgumentList itemTypeArgs = new TypeArgumentList();
|
||||
Out<TypeArgumentList> tempOut_itemTypeArgs3 = new Out<TypeArgumentList>();
|
||||
LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, tp.getItems().get(i),
|
||||
tempOut_itemTypeArgs3);
|
||||
itemTypeArgs = tempOut_itemTypeArgs3.get();
|
||||
if (tp.getItems().get(i).getNullable()) {
|
||||
itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
|
||||
itemTypeArgs.clone()) });
|
||||
itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
|
||||
}
|
||||
|
||||
args[i] = new TypeArgument(itemType, itemTypeArgs.clone());
|
||||
}
|
||||
|
||||
typeArgs.setAndGet(new TypeArgumentList(args));
|
||||
return immutable ? LayoutType.ImmutableTypedTuple : LayoutType.TypedTuple;
|
||||
|
||||
case Tagged:
|
||||
TaggedPropertyType tg = (TaggedPropertyType)logicalType;
|
||||
if ((tg.getItems().size() < TaggedPropertyType.MinTaggedArguments) || (tg.getItems().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(),
|
||||
TaggedPropertyType.MaxTaggedArguments));
|
||||
}
|
||||
|
||||
TypeArgument[] tgArgs = new TypeArgument[tg.getItems().size() + 1];
|
||||
tgArgs[0] = new TypeArgument(LayoutType.UInt8, TypeArgumentList.EMPTY);
|
||||
for (int i = 0; i < tg.getItems().size(); i++) {
|
||||
TypeArgumentList itemTypeArgs = new TypeArgumentList();
|
||||
Out<TypeArgumentList> tempOut_itemTypeArgs4 = new Out<TypeArgumentList>();
|
||||
LayoutType itemType = LayoutCompiler.LogicalToPhysicalType(ns, tg.getItems().get(i),
|
||||
tempOut_itemTypeArgs4);
|
||||
itemTypeArgs = tempOut_itemTypeArgs4.get();
|
||||
if (tg.getItems().get(i).getNullable()) {
|
||||
itemTypeArgs = new TypeArgumentList(new TypeArgument[] { new TypeArgument(itemType,
|
||||
itemTypeArgs.clone()) });
|
||||
itemType = itemType.Immutable ? LayoutType.ImmutableNullable : LayoutType.Nullable;
|
||||
}
|
||||
|
||||
tgArgs[i + 1] = new TypeArgument(itemType, itemTypeArgs.clone());
|
||||
}
|
||||
|
||||
typeArgs.setAndGet(new TypeArgumentList(tgArgs));
|
||||
switch (tg.getItems().size()) {
|
||||
case 1:
|
||||
return immutable ? LayoutType.ImmutableTagged : LayoutType.Tagged;
|
||||
case 2:
|
||||
return immutable ? LayoutType.ImmutableTagged2 : LayoutType.Tagged2;
|
||||
default:
|
||||
throw new LayoutCompilationException("Unexpected tagged arity");
|
||||
}
|
||||
|
||||
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))
|
||||
} else {
|
||||
udtSchema = tangible.ListHelper.find(ns.getSchemas(), s =
|
||||
SchemaId.opEquals( > s.SchemaId, up.getSchemaId().clone()))
|
||||
if (!udtSchema.getName().equals(up.getName())) {
|
||||
throw new LayoutCompilationException(String.format("Ambiguous schema reference: '%1$s:%2$s'",
|
||||
up.getName(), up.getSchemaId().clone()));
|
||||
}
|
||||
}
|
||||
|
||||
if (udtSchema == null) {
|
||||
throw new LayoutCompilationException(String.format("Cannot resolve schema reference '%1$s:%2$s'",
|
||||
up.getName(), up.getSchemaId().clone()));
|
||||
}
|
||||
|
||||
typeArgs.setAndGet(new TypeArgumentList(udtSchema.getSchemaId().clone()));
|
||||
return immutable ? LayoutType.ImmutableUDT : LayoutType.UDT;
|
||||
|
||||
default:
|
||||
throw new LayoutCompilationException(String.format("Unknown property type: %1$s",
|
||||
logicalType.getType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutDateTime extends LayoutType<DateTime> {
|
||||
public LayoutDateTime() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.DATE_TIME, 8);
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "datetime";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result ReadFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
Out<LocalDateTime> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), col.getNullBit().clone())) {
|
||||
value.setAndGet(LocalDateTime.MIN);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadDateTime(scope.get().start() + col.getOffset()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result ReadSparse(Reference<RowBuffer> b, Reference<RowCursor> edit,
|
||||
Out<LocalDateTime> value) {
|
||||
Result result = LayoutType.prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(LocalDateTime.MIN);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseDateTime(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
LocalDateTime value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteDateTime(scope.get().start() + col.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, DateTime value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
public Result writeSparse(Reference<RowBuffer> b, Reference<RowCursor> edit,
|
||||
LocalDateTime value, UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseDateTime(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit, DateTime value) {
|
||||
return writeSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutDecimal extends LayoutType<BigDecimal> {
|
||||
public LayoutDecimal() {
|
||||
// TODO: C# TO JAVA CONVERTER: There is no Java equivalent to 'sizeof':
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.DECIMAL, sizeof(BigDecimal));
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "decimal";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<BigDecimal> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(new BigDecimal(0));
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadDecimal(scope.get().start() + column.getOffset()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<BigDecimal> value) {
|
||||
Result result = LayoutType.prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(new BigDecimal(0));
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseDecimal(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
BigDecimal value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteDecimal(scope.get().start() + column.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), column.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, decimal value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit, BigDecimal value,
|
||||
UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseDecimal(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit,
|
||||
BigDecimal value) {
|
||||
return writeSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
public final class LayoutEndScope extends LayoutScope {
|
||||
public LayoutEndScope() {
|
||||
// TODO: C# TO JAVA CONVERTER: C# to Java Converter could not resolve the named parameters in the
|
||||
// following line:
|
||||
//ORIGINAL LINE: base(LayoutCode.EndScope, false, isSizedScope: false, isIndexedScope: false, isFixedArity:
|
||||
// false, isUniqueScope: false, isTypedScope: false);
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.END_SCOPE, false, isSizedScope():false, isIndexedScope():false, isFixedArity():false, isUniqueScope():
|
||||
false, isTypedScope():false)
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "end";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor scope,
|
||||
TypeArgumentList typeArgs, Out<RowCursor> value) {
|
||||
return writeScope(b, scope, typeArgs, UpdateOptions.Upsert, value);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteScope(ref RowBuffer b, ref RowCursor scope, TypeArgumentList
|
||||
// typeArgs, out RowCursor value, UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor scope,
|
||||
TypeArgumentList typeArgs, UpdateOptions options, Out<RowCursor> value) {
|
||||
Contract.Fail("Cannot write an EndScope directly");
|
||||
value.setAndGet(null);
|
||||
return Result.Failure;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Float128;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutFloat128 extends LayoutType<com.azure.data.cosmos.serialization.hybridrow.Float128> {
|
||||
public LayoutFloat128() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.FLOAT_128, HybridRow.Float128.Size);
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "float128";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Float128> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(null);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadFloat128(scope.get().start() + column.getOffset()).clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<Float128> value) {
|
||||
Result result = LayoutType.prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseFloat128(edit).clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Float128 value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().writeFloat128(scope.get().start() + column.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), column.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, Float128 value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit, Float128 value,
|
||||
UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseFloat128(edit, value.clone(), options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit, Float128 value) {
|
||||
return writeSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutFloat32 extends LayoutType<Float> {
|
||||
public LayoutFloat32() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.FLOAT_32, (Float.SIZE / Byte.SIZE));
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "float32";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Float> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(0);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadFloat32(scope.get().start() + column.getOffset()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<Float> value) {
|
||||
Result result = prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseFloat32(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
float value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteFloat32(scope.get().start() + col.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, float value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, float value,
|
||||
UpdateOptions options) {
|
||||
Result result = prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().writeSparseFloat32(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, float value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutFloat64 extends LayoutType<Double> {
|
||||
public LayoutFloat64() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.FLOAT_64, (Double.SIZE / Byte.SIZE));
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "float64";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Double> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(0);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadFloat64(scope.get().start() + column.getOffset()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<Double> value) {
|
||||
Result result = LayoutType.prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseFloat64(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
double value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteFloat64(scope.get().start() + col.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, double value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, double value,
|
||||
UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseFloat64(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, double value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutGuid extends LayoutType<UUID> {
|
||||
public LayoutGuid() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.GUID, 16);
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "guid";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<UUID> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(null);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadGuid(scope.get().start() + column.getOffset()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<UUID> value) {
|
||||
Result result = prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseGuid(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
UUID value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteGuid(scope.get().start() + column.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), column.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, Guid value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit, UUID value,
|
||||
UpdateOptions options) {
|
||||
Result result = prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseGuid(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit,
|
||||
UUID value) {
|
||||
return writeSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public abstract class LayoutIndexedScope extends LayoutScope {
|
||||
|
||||
protected LayoutIndexedScope(
|
||||
@Nonnull final LayoutCode code, final boolean immutable, final boolean isSizedScope, final boolean isFixedArity,
|
||||
final boolean isUniqueScope, final boolean isTypedScope) {
|
||||
|
||||
super(code, immutable, isSizedScope, true, isFixedArity, isUniqueScope, isTypedScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSparsePath(@Nonnull final RowBuffer row, @Nonnull final RowCursor edit) {
|
||||
edit.pathToken(0);
|
||||
edit.pathOffset(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutInt16 extends LayoutType<Short> {
|
||||
public LayoutInt16() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.INT_16, (Short.SIZE / Byte.SIZE));
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "int16";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Short> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(0);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadInt16(scope.get().start() + column.getOffset()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<Short> value) {
|
||||
Result result = prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseInt16(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
short value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().writeInt16(scope.get().start() + col.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, short value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, short value,
|
||||
UpdateOptions options) {
|
||||
Result result = prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseInt16(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, short value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutInt32 extends LayoutType<Integer> {
|
||||
public LayoutInt32() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.INT_32, (Integer.SIZE / Byte.SIZE));
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "int32";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Integer> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(0);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadInt32(scope.get().start() + column.getOffset()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<Integer> value) {
|
||||
Result result = LayoutType.prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseInt32(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
int value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().writeInt32(scope.get().start() + col.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, int value, UpdateOptions
|
||||
// options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, int value,
|
||||
UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseInt32(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, int value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutInt64 extends LayoutType<Long> {
|
||||
public LayoutInt64() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.INT_64, (Long.SIZE / Byte.SIZE));
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "int64";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Long> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(0);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadInt64(scope.get().start() + column.getOffset()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<Long> value) {
|
||||
Result result = LayoutType.prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseInt64(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
long value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().writeInt64(scope.get().start() + col.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, long value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, long value,
|
||||
UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseInt64(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, long value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutInt8 extends LayoutType<Byte> {
|
||||
public LayoutInt8() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.INT_8, (Byte.SIZE / Byte.SIZE));
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "int8";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Byte> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(0);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadInt8(scope.get().start() + column.getOffset()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<Byte> value) {
|
||||
Result result = LayoutType.prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseInt8(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
byte value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().writeInt8(scope.get().start() + col.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, sbyte value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, byte value,
|
||||
UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseInt8(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, byte value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutMongoDbObjectId extends LayoutType<MongoDbObjectId> {
|
||||
public LayoutMongoDbObjectId() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.MONGODB_OBJECT_ID, azure.data.cosmos.serialization.hybridrow.MongoDbObjectId.Size);
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ReSharper disable once StringLiteralTypo
|
||||
public String name() {
|
||||
return "mongodbobjectid";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<MongoDbObjectId> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(null);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadMongoDbObjectId(scope.get().start() + column.getOffset()).clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<MongoDbObjectId> value) {
|
||||
Result result = LayoutType.prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseMongoDbObjectId(edit).clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
MongoDbObjectId value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteMongoDbObjectId(scope.get().start() + column.getOffset(), value.clone());
|
||||
b.get().SetBit(scope.get().start(), column.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, MongoDbObjectId value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit,
|
||||
MongoDbObjectId value, UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseMongoDbObjectId(edit, value.clone(), options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit,
|
||||
MongoDbObjectId value) {
|
||||
return writeSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.NullValue;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutNull extends LayoutType<NullValue> {
|
||||
public LayoutNull() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.NULL, 0);
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isNull() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<NullValue> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
value.setAndGet(NullValue.Default);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<NullValue> value) {
|
||||
Result result = prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().readSparseNull(edit).clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
NullValue value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().SetBit(scope.get().start(), column.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, NullValue value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit, NullValue value,
|
||||
UpdateOptions options) {
|
||||
Result result = prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseNull(edit, value.clone(), options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit, NullValue value) {
|
||||
return writeSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
public final class LayoutNullable extends LayoutIndexedScope {
|
||||
public LayoutNullable(boolean immutable) {
|
||||
super(immutable ? com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.IMMUTABLE_NULLABLE_SCOPE :
|
||||
com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.NULLABLE_SCOPE, immutable, true, true, false, true);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.Immutable ? "im_nullable" : "nullable";
|
||||
}
|
||||
|
||||
public int countTypeArgument(@Nonnull final TypeArgumentList value) {
|
||||
checkNotNull(value, "expected non-null value");
|
||||
checkArgument(value.count() == 1);
|
||||
return (LayoutCode.SIZE / Byte.SIZE) + value.get(0).type().countTypeArgument(value.get(0).typeArgs());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasImplicitTypeCode(@Nonnull final RowCursor edit) {
|
||||
checkNotNull(edit, "expected non-null edit");
|
||||
checkArgument(edit.index() >= 0);
|
||||
checkArgument(edit.scopeTypeArgs().count() == 1);
|
||||
checkArgument(edit.index() == 1);
|
||||
return !LayoutCodeTraits.AlwaysRequiresTypeCode(edit.scopeTypeArgs().get(0).type().layoutCode());
|
||||
}
|
||||
|
||||
public static Result hasValue(@Nonnull final RowBuffer b, @Nonnull final RowCursor scope) {
|
||||
checkNotNull(b);
|
||||
checkNotNull(scope);
|
||||
checkArgument(scope.scopeType() instanceof LayoutNullable);
|
||||
checkArgument(scope.index() == 1 || scope.index() == 2);
|
||||
checkArgument(scope.scopeTypeArgs().count() == 1);
|
||||
boolean hasValue = b.readInt8(scope.start()) != 0;
|
||||
return hasValue ? Result.Success : Result.NotFound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeArgumentList readTypeArgumentList(
|
||||
@Nonnull final RowBuffer row, int offset, @Nonnull final Out<Integer> lenInBytes) {
|
||||
return new TypeArgumentList(LayoutType.readTypeArgument(row, offset, lenInBytes));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitTypeCode(RowCursor edit) {
|
||||
checkState(edit.index() == 1);
|
||||
edit.get().cellType(edit.get().scopeTypeArgs().get(0).type());
|
||||
edit.get().cellTypeArgs(edit.get().scopeTypeArgs().get(0).typeArgs());
|
||||
}
|
||||
|
||||
public Result writeScope(Reference<RowBuffer> b, Reference<RowCursor> edit,
|
||||
TypeArgumentList typeArgs, boolean hasValue, Out<RowCursor> value) {
|
||||
return writeScope(b, edit, typeArgs, hasValue, value, UpdateOptions.Upsert);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public Result WriteScope(ref RowBuffer b, ref RowCursor edit, TypeArgumentList typeArgs, bool
|
||||
// hasValue, out RowCursor value, UpdateOptions options = UpdateOptions.Upsert)
|
||||
public Result writeScope(Reference<RowBuffer> b, Reference<RowCursor> edit,
|
||||
TypeArgumentList typeArgs, boolean hasValue, Out<RowCursor> value,
|
||||
UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, new TypeArgument(this, typeArgs.clone()), options);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteNullable(edit, this, typeArgs.clone(), options, hasValue, value.clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, Out<RowCursor> value) {
|
||||
return writeScope(b, edit, typeArgs, UpdateOptions.Upsert, value);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteScope(ref RowBuffer b, ref RowCursor edit, TypeArgumentList
|
||||
// typeArgs, out RowCursor value, UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, UpdateOptions options, Out<RowCursor> value) {
|
||||
return this.WriteScope(b, edit, typeArgs.clone(), true, value, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeTypeArgument(Reference<RowBuffer> row, int offset, TypeArgumentList value) {
|
||||
checkState(value.count() == 1);
|
||||
row.get().writeSparseTypeCode(offset, this.LayoutCode);
|
||||
int lenInBytes = (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
lenInBytes += value.get(0).type().writeTypeArgument(row, offset + lenInBytes,
|
||||
value.get(0).typeArgs().clone());
|
||||
return lenInBytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
public final class LayoutObject extends LayoutPropertyScope {
|
||||
private TypeArgument TypeArg = new TypeArgument();
|
||||
|
||||
public LayoutObject(boolean immutable) {
|
||||
super(immutable ? com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.IMMUTABLE_OBJECT_SCOPE :
|
||||
com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.OBJECT_SCOPE, immutable);
|
||||
this.TypeArg = new TypeArgument(this);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.Immutable ? "im_object" : "object";
|
||||
}
|
||||
|
||||
public TypeArgument typeArg() {
|
||||
return TypeArg;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, Out<RowCursor> value) {
|
||||
return writeScope(b, edit, typeArgs, UpdateOptions.Upsert, value);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteScope(ref RowBuffer b, ref RowCursor edit, TypeArgumentList
|
||||
// typeArgs, out RowCursor value, UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, UpdateOptions options, Out<RowCursor> value) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseObject(edit, this, options, value.clone());
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
public abstract class LayoutPropertyScope extends LayoutScope {
|
||||
protected LayoutPropertyScope(LayoutCode code, boolean immutable) {
|
||||
// TODO: C# TO JAVA CONVERTER: C# to Java Converter could not resolve the named parameters in the
|
||||
// following line:
|
||||
// base(code, immutable, isSizedScope: false, isIndexedScope: false, isFixedArity: false, isUniqueScope: false, isTypedScope: false);
|
||||
super(code, immutable, false, false, false, false, false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
|
||||
|
||||
public abstract class LayoutResolver {
|
||||
public abstract Layout resolve(SchemaId schemaId);
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.Namespace;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.schemas.Schema;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.base.Strings.lenientFormat;
|
||||
|
||||
/**
|
||||
* An implementation of {@link LayoutResolver} which dynamically compiles schema from
|
||||
* a {@link Namespace}.
|
||||
* <p>
|
||||
* <p>
|
||||
* This resolver assumes that {@link Schema} within the {@link Namespace} have
|
||||
* their {@link Schema.SchemaId} properly populated. The resolver caches compiled schema.
|
||||
* <p>
|
||||
* All members of this class are multi-thread safe.
|
||||
*/
|
||||
public final class LayoutResolverNamespace extends LayoutResolver {
|
||||
private java.util.concurrent.ConcurrentHashMap<Integer, Layout> layoutCache;
|
||||
private LayoutResolver parent;
|
||||
private Namespace schemaNamespace;
|
||||
|
||||
|
||||
public LayoutResolverNamespace(Namespace schemaNamespace) {
|
||||
this(schemaNamespace, null);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public LayoutResolverNamespace(Namespace schemaNamespace, LayoutResolver parent = default)
|
||||
public LayoutResolverNamespace(Namespace schemaNamespace, LayoutResolver parent) {
|
||||
this.schemaNamespace = schemaNamespace;
|
||||
this.parent = parent;
|
||||
this.layoutCache = new java.util.concurrent.ConcurrentHashMap<Integer, Layout>();
|
||||
}
|
||||
|
||||
public Namespace getNamespace() {
|
||||
return this.schemaNamespace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Layout resolve(SchemaId schemaId) {
|
||||
Layout layout;
|
||||
// TODO: C# TO JAVA CONVERTER: There is no Java ConcurrentHashMap equivalent to this .NET
|
||||
// ConcurrentDictionary method:
|
||||
// TODO: C# TO JAVA CONVERTER: The following method call contained an unresolved 'out' keyword - these
|
||||
// cannot be converted using the 'Out' helper class unless the method is within the code being modified:
|
||||
if (this.layoutCache.TryGetValue(schemaId.value(), out layout)) {
|
||||
return layout;
|
||||
}
|
||||
|
||||
for (Schema s : this.schemaNamespace.getSchemas()) {
|
||||
if (SchemaId.opEquals(s.getSchemaId().clone(),
|
||||
schemaId.clone())) {
|
||||
layout = s.Compile(this.schemaNamespace);
|
||||
layout = this.layoutCache.putIfAbsent(schemaId.value(), layout);
|
||||
return layout;
|
||||
}
|
||||
}
|
||||
|
||||
layout = this.parent == null ? null : this.parent.resolve(schemaId.clone());
|
||||
if (layout != null) {
|
||||
// TODO: C# TO JAVA CONVERTER: There is no Java ConcurrentHashMap equivalent to this .NET
|
||||
// ConcurrentDictionary method:
|
||||
boolean succeeded = this.layoutCache.TryAdd(schemaId.value(), layout);
|
||||
checkState(succeeded);
|
||||
return layout;
|
||||
}
|
||||
|
||||
throw new IllegalStateException(lenientFormat("Failed to resolve schema %s", schemaId.clone()));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
|
||||
|
||||
public final class LayoutResolverSimple extends LayoutResolver {
|
||||
private tangible.Func1Param<SchemaId, Layout> resolver;
|
||||
|
||||
public LayoutResolverSimple(tangible.Func1Param<SchemaId, Layout> resolver) {
|
||||
this.resolver = (SchemaId arg) -> resolver.invoke(arg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Layout resolve(SchemaId schemaId) {
|
||||
return this.resolver.invoke(schemaId.clone());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursors;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public abstract class LayoutScope extends LayoutType {
|
||||
|
||||
private final boolean isFixedArity;
|
||||
private final boolean isIndexedScope;
|
||||
private final boolean isSizedScope;
|
||||
private final boolean isTypedScope;
|
||||
private final boolean isUniqueScope;
|
||||
|
||||
protected LayoutScope(
|
||||
@Nonnull final LayoutCode code, final boolean immutable, final boolean isSizedScope,
|
||||
final boolean isIndexedScope, final boolean isFixedArity, final boolean isUniqueScope, boolean isTypedScope) {
|
||||
|
||||
super(code, immutable, 0);
|
||||
this.isSizedScope = isSizedScope;
|
||||
this.isIndexedScope = isIndexedScope;
|
||||
this.isFixedArity = isFixedArity;
|
||||
this.isUniqueScope = isUniqueScope;
|
||||
this.isTypedScope = isTypedScope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a fixed arity scope.
|
||||
*/
|
||||
public boolean isFixedArity() {
|
||||
return this.isFixedArity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is an indexed scope.
|
||||
*/
|
||||
public boolean isIndexedScope() {
|
||||
return this.isIndexedScope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a sized scope.
|
||||
*/
|
||||
public boolean isSizedScope() {
|
||||
return this.isSizedScope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a typed scope.
|
||||
*/
|
||||
public boolean isTypedScope() {
|
||||
return this.isTypedScope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the scope's elements cannot be updated directly.
|
||||
*/
|
||||
public boolean isUniqueScope() {
|
||||
return this.isUniqueScope;
|
||||
}
|
||||
|
||||
public final Result deleteScope(@Nonnull final RowBuffer b, @Nonnull final RowCursor edit) {
|
||||
|
||||
checkNotNull(b);
|
||||
checkNotNull(edit);
|
||||
|
||||
Result result = LayoutType.prepareSparseDelete(b, edit, this.layoutCode());
|
||||
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.deleteSparse(edit);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code true} if writing an item in the specified typed scope would elide the type code because it is implied by
|
||||
* the type arguments
|
||||
*
|
||||
* @param edit a non-null {@link RowCursor} specifying a typed scope
|
||||
* @return {@code true} if the type code is implied (not written); {@code false} otherwise.
|
||||
*/
|
||||
public boolean hasImplicitTypeCode(@Nonnull final RowCursor edit) {
|
||||
checkNotNull(edit, "expected non-null edit");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public final Result readScope(
|
||||
@Nonnull final RowBuffer b, @Nonnull final RowCursor edit, @Nonnull final Out<RowCursor> value) {
|
||||
|
||||
checkNotNull(b);
|
||||
checkNotNull(edit);
|
||||
checkNotNull(value);
|
||||
|
||||
Result result = LayoutType.prepareSparseRead(b, edit, this.layoutCode());
|
||||
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean immutable = this.isImmutable() || edit.immutable() || edit.scopeType().isUniqueScope();
|
||||
value.set(b.sparseIteratorReadScope(edit, immutable));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public void readSparsePath(@Nonnull final RowBuffer row, @Nonnull final RowCursor edit) {
|
||||
Out<Integer> pathLenInBytes = new Out<>();
|
||||
Out<Integer> pathOffset = new Out<>();
|
||||
edit.pathToken(row.readSparsePathLen(edit.layout(), edit.valueOffset(), pathLenInBytes, pathOffset));
|
||||
edit.pathOffset(pathOffset.get());
|
||||
edit.valueOffset(edit.valueOffset() + pathLenInBytes.get());
|
||||
}
|
||||
|
||||
public void setImplicitTypeCode(final RowCursor edit) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public abstract Result writeScope(
|
||||
RowBuffer b,
|
||||
RowCursor scope,
|
||||
TypeArgumentList typeArgs, Out<RowCursor> value);
|
||||
|
||||
public abstract Result writeScope(
|
||||
RowBuffer b,
|
||||
RowCursor scope,
|
||||
TypeArgumentList typeArgs,
|
||||
UpdateOptions options, Out<RowCursor> value);
|
||||
|
||||
public <TContext> Result writeScope(
|
||||
RowBuffer b,
|
||||
RowCursor scope,
|
||||
TypeArgumentList typeArgs,
|
||||
TContext context, WriterFunc<TContext> func) {
|
||||
return this.writeScope(b, scope, typeArgs, context, func, UpdateOptions.Upsert);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public virtual Result WriteScope<TContext>(ref RowBuffer b, ref RowCursor scope,
|
||||
// TypeArgumentList typeArgs, TContext context, WriterFunc<TContext> func, UpdateOptions options = UpdateOptions
|
||||
// .Upsert)
|
||||
public <TContext> Result writeScope(
|
||||
RowBuffer b,
|
||||
RowCursor scope,
|
||||
TypeArgumentList typeArgs,
|
||||
TContext context, WriterFunc<TContext> func, UpdateOptions options) {
|
||||
|
||||
final Out<RowCursor> out = new Out<>();
|
||||
Result result = this.writeScope(b, scope, typeArgs, options, out);
|
||||
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
final RowCursor childScope = out.get();
|
||||
|
||||
if (func != null) {
|
||||
result = func.invoke(b, childScope, context);
|
||||
if (result != Result.Success) {
|
||||
this.deleteScope(b, scope);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
RowCursors.skip(scope, b, childScope);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function to write content into a {@link RowBuffer}.
|
||||
* <typeparam name="TContext">The type of the context value passed by the caller.</typeparam>
|
||||
*
|
||||
* @param b The row to write to.
|
||||
* @param scope The type of the scope to write into.
|
||||
* @param context A context value provided by the caller.
|
||||
* @return The result.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface WriterFunc<TContext> {
|
||||
@Nonnull Result invoke(RowBuffer b, RowCursor scope, TContext context);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.IMMUTABLE_TAGGED_SCOPE;
|
||||
import static com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.TAGGED_SCOPE;
|
||||
|
||||
public final class LayoutTagged extends LayoutIndexedScope {
|
||||
public LayoutTagged(boolean immutable) {
|
||||
super(immutable ? IMMUTABLE_TAGGED_SCOPE : TAGGED_SCOPE, immutable, true, true, false, true);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.Immutable ? "im_tagged_t" : "tagged_t";
|
||||
}
|
||||
|
||||
public int countTypeArgument(TypeArgumentList value) {
|
||||
checkState(value.count() == 2);
|
||||
return (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE) + value.get(1).type().CountTypeArgument(value.get(1).typeArgs().clone());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean HasImplicitTypeCode(Reference<RowCursor> edit) {
|
||||
checkArgument(edit.get().index() >= 0);
|
||||
checkArgument(edit.get().scopeTypeArgs().count() > edit.get().index());
|
||||
return !LayoutCodeTraits.AlwaysRequiresTypeCode(edit.get().scopeTypeArgs().get(edit.get().index()).type().LayoutCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeArgumentList readTypeArgumentList(Reference<RowBuffer> row, int offset,
|
||||
Out<Integer> lenInBytes) {
|
||||
TypeArgument[] retval = new TypeArgument[2];
|
||||
retval[0] = new TypeArgument(UInt8, TypeArgumentList.EMPTY);
|
||||
retval[1] = readTypeArgument(row, offset, lenInBytes);
|
||||
return new TypeArgumentList(retval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitTypeCode(RowCursor edit) {
|
||||
edit.get().cellType = edit.get().scopeTypeArgs().get(edit.get().index()).type();
|
||||
edit.get().cellTypeArgs = edit.get().scopeTypeArgs().get(edit.get().index()).typeArgs().clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, Out<RowCursor> value) {
|
||||
return writeScope(b, edit, typeArgs, UpdateOptions.Upsert, value);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteScope(ref RowBuffer b, ref RowCursor edit, TypeArgumentList
|
||||
// typeArgs, out RowCursor value, UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, UpdateOptions options, Out<RowCursor> value) {
|
||||
Result result = prepareSparseWrite(b, edit, new TypeArgument(this, typeArgs.clone()), options);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteTypedTuple(edit, this, typeArgs.clone(), options, value.clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeTypeArgument(Reference<RowBuffer> row, int offset, TypeArgumentList value) {
|
||||
checkArgument(value.count() == 2);
|
||||
row.get().writeSparseTypeCode(offset, this.LayoutCode);
|
||||
int lenInBytes = (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
lenInBytes += value.get(1).type().writeTypeArgument(row, offset + lenInBytes,
|
||||
value.get(1).typeArgs().clone());
|
||||
return lenInBytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
public final class LayoutTagged2 extends LayoutIndexedScope {
|
||||
public LayoutTagged2(boolean immutable) {
|
||||
super(immutable ? com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.IMMUTABLE_TAGGED2_SCOPE :
|
||||
com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.TAGGED2_SCOPE, immutable, isSizedScope():
|
||||
true, isFixedArity():true, isUniqueScope():false, isTypedScope():true)
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.Immutable ? "im_tagged2_t" : "tagged2_t";
|
||||
}
|
||||
|
||||
public int countTypeArgument(TypeArgumentList value) {
|
||||
checkState(value.count() == 3);
|
||||
int lenInBytes = (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
for (int i = 1; i < value.count(); i++) {
|
||||
TypeArgument arg = value.get(i).clone();
|
||||
lenInBytes += arg.type().CountTypeArgument(arg.typeArgs().clone());
|
||||
}
|
||||
|
||||
return lenInBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean HasImplicitTypeCode(Reference<RowCursor> edit) {
|
||||
checkState(edit.get().index() >= 0);
|
||||
checkState(edit.get().scopeTypeArgs().count() > edit.get().index());
|
||||
return !LayoutCodeTraits.AlwaysRequiresTypeCode(edit.get().scopeTypeArgs().get(edit.get().index()).type().LayoutCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeArgumentList readTypeArgumentList(Reference<RowBuffer> row, int offset,
|
||||
Out<Integer> lenInBytes) {
|
||||
lenInBytes.setAndGet(0);
|
||||
TypeArgument[] retval = new TypeArgument[3];
|
||||
retval[0] = new TypeArgument(UInt8, TypeArgumentList.EMPTY);
|
||||
for (int i = 1; i < 3; i++) {
|
||||
int itemLenInBytes;
|
||||
Out<Integer> tempOut_itemLenInBytes = new Out<Integer>();
|
||||
retval[i] = readTypeArgument(row, offset + lenInBytes.get(), tempOut_itemLenInBytes);
|
||||
itemLenInBytes = tempOut_itemLenInBytes.get();
|
||||
lenInBytes.setAndGet(lenInBytes.get() + itemLenInBytes);
|
||||
}
|
||||
|
||||
return new TypeArgumentList(retval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitTypeCode(RowCursor edit) {
|
||||
edit.get().cellType = edit.get().scopeTypeArgs().get(edit.get().index()).type();
|
||||
edit.get().cellTypeArgs = edit.get().scopeTypeArgs().get(edit.get().index()).typeArgs().clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, Out<RowCursor> value) {
|
||||
return writeScope(b, edit, typeArgs, UpdateOptions.Upsert, value);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteScope(ref RowBuffer b, ref RowCursor edit, TypeArgumentList
|
||||
// typeArgs, out RowCursor value, UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, UpdateOptions options, Out<RowCursor> value) {
|
||||
Result result = prepareSparseWrite(b, edit, new TypeArgument(this, typeArgs.clone()), options);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteTypedTuple(edit, this, typeArgs.clone(), options, value.clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeTypeArgument(Reference<RowBuffer> row, int offset, TypeArgumentList value) {
|
||||
checkState(value.count() == 3);
|
||||
row.get().writeSparseTypeCode(offset, this.LayoutCode);
|
||||
int lenInBytes = (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
for (int i = 1; i < value.count(); i++) {
|
||||
TypeArgument arg = value.get(i).clone();
|
||||
lenInBytes += arg.type().writeTypeArgument(row, offset + lenInBytes, arg.typeArgs().clone());
|
||||
}
|
||||
|
||||
return lenInBytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.IMMUTABLE_TUPLE_SCOPE;
|
||||
import static com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.TUPLE_SCOPE;
|
||||
|
||||
public final class LayoutTuple extends LayoutIndexedScope {
|
||||
public LayoutTuple(boolean immutable) {
|
||||
super(immutable ? IMMUTABLE_TUPLE_SCOPE : TUPLE_SCOPE, immutable, false, true, false, false);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.Immutable ? "im_tuple" : "tuple";
|
||||
}
|
||||
|
||||
public int countTypeArgument(TypeArgumentList value) {
|
||||
int lenInBytes = (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: lenInBytes += RowBuffer.Count7BitEncodedUInt((ulong)value.Count);
|
||||
lenInBytes += RowBuffer.count7BitEncodedUInt(value.count());
|
||||
for (TypeArgument arg : value) {
|
||||
lenInBytes += arg.type().CountTypeArgument(arg.typeArgs().clone());
|
||||
}
|
||||
|
||||
return lenInBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeArgumentList readTypeArgumentList(Reference<RowBuffer> row, int offset,
|
||||
Out<Integer> lenInBytes) {
|
||||
int numTypeArgs = row.get().intValue().Read7BitEncodedUInt(offset, lenInBytes);
|
||||
TypeArgument[] retval = new TypeArgument[numTypeArgs];
|
||||
for (int i = 0; i < numTypeArgs; i++) {
|
||||
int itemLenInBytes;
|
||||
Out<Integer> tempOut_itemLenInBytes = new Out<Integer>();
|
||||
retval[i] = readTypeArgument(row, offset + lenInBytes.get(), tempOut_itemLenInBytes);
|
||||
itemLenInBytes = tempOut_itemLenInBytes.get();
|
||||
lenInBytes.setAndGet(lenInBytes.get() + itemLenInBytes);
|
||||
}
|
||||
|
||||
return new TypeArgumentList(retval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, Out<RowCursor> value) {
|
||||
return writeScope(b, edit, typeArgs, UpdateOptions.Upsert, value);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteScope(ref RowBuffer b, ref RowCursor edit, TypeArgumentList
|
||||
// typeArgs, out RowCursor value, UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, UpdateOptions options, Out<RowCursor> value) {
|
||||
Result result = prepareSparseWrite(b, edit, new TypeArgument(this, typeArgs.clone()), options);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseTuple(edit, this, typeArgs.clone(), options, value.clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeTypeArgument(Reference<RowBuffer> row, int offset, TypeArgumentList value) {
|
||||
row.get().writeSparseTypeCode(offset, this.LayoutCode);
|
||||
int lenInBytes = (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: lenInBytes += row.Write7BitEncodedUInt(offset + lenInBytes, (ulong)value.Count);
|
||||
lenInBytes += row.get().write7BitEncodedUInt(offset + lenInBytes, value.count());
|
||||
for (TypeArgument arg : value) {
|
||||
lenInBytes += arg.type().writeTypeArgument(row, offset + lenInBytes, arg.typeArgs().clone());
|
||||
}
|
||||
|
||||
return lenInBytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,409 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Strings.lenientFormat;
|
||||
|
||||
/**
|
||||
* Describes the physical byte layout of a hybrid row field of a specific physical type {@code T}
|
||||
*
|
||||
* {@link LayoutType<T>} is an immutable, stateless, helper class. It provides methods for manipulating hybrid row
|
||||
* fields of a particular type, and properties that describe the layout of fields of that type.
|
||||
* <p>
|
||||
* {@param <T>} The specific physical type whose byte layout is represented by this class.
|
||||
*/
|
||||
public abstract class LayoutType<T> implements ILayoutType {
|
||||
|
||||
private static final LayoutType[] CodeIndex = new LayoutType[LayoutCode.END_SCOPE.value() + 1];
|
||||
|
||||
private final boolean immutable;
|
||||
private final LayoutCode layoutCode;
|
||||
private final int size;
|
||||
private final TypeArgument typeArg;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link LayoutType<T>} class.
|
||||
*/
|
||||
protected LayoutType(LayoutCode code, boolean immutable, int size) {
|
||||
this.layoutCode = code;
|
||||
this.immutable = immutable;
|
||||
this.size = size;
|
||||
this.typeArg = new TypeArgument(this);
|
||||
CodeIndex[code.value()] = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link LayoutType<T>} class.
|
||||
*/
|
||||
protected LayoutType(LayoutCode code, int size) {
|
||||
this(code, false, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* True if this type is a boolean.
|
||||
*/
|
||||
public boolean isBoolean() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if this type is always fixed length.
|
||||
*/
|
||||
public abstract boolean isFixed();
|
||||
|
||||
/**
|
||||
* If true, this edit's nested fields cannot be updated individually.
|
||||
* The entire edit can still be replaced.
|
||||
*/
|
||||
public boolean isImmutable() {
|
||||
return this.immutable;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if this type is a literal null.
|
||||
*/
|
||||
public boolean isNull() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if this type is a variable-length encoded integer type (either signed or unsigned).
|
||||
*/
|
||||
public boolean isVarint() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if this type can be used in the variable-length segment.
|
||||
*/
|
||||
public final boolean allowVariable() {
|
||||
return !this.isFixed();
|
||||
}
|
||||
|
||||
public int countTypeArgument(TypeArgumentList value) {
|
||||
return (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
}
|
||||
|
||||
public final Result deleteFixed(RowBuffer b, RowCursor scope, LayoutColumn column) {
|
||||
|
||||
checkArgument(scope.scopeType() instanceof LayoutUDT);
|
||||
|
||||
if (scope.immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
if (column.nullBit().isInvalid()) {
|
||||
// Cannot delete a non-nullable fixed column.
|
||||
return Result.TypeMismatch;
|
||||
}
|
||||
|
||||
b.UnsetBit(scope.start(), column.nullBit());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an existing value.
|
||||
* <p>
|
||||
* If a value exists, then it is removed. The remainder of the row is resized to accomodate
|
||||
* a decrease in required space. If no value exists this operation is a no-op.
|
||||
* @param b
|
||||
* @param edit
|
||||
*/
|
||||
public final Result deleteSparse(RowBuffer b, RowCursor edit) {
|
||||
|
||||
Result result = LayoutType.prepareSparseDelete(b, edit, this.layoutCode());
|
||||
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.deleteSparse(edit);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an existing value.
|
||||
* <p>
|
||||
* If a value exists, then it is removed. The remainder of the row is resized to accommodate a decrease in
|
||||
* required space. If no value exists this operation is a no-op.
|
||||
*/
|
||||
public final Result deleteVariable(RowBuffer b, RowCursor scope, LayoutColumn column) {
|
||||
|
||||
checkArgument(scope.scopeType() instanceof LayoutUDT);
|
||||
|
||||
if (scope.immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
boolean exists = b.readBit(scope.start(), column.nullBit());
|
||||
|
||||
if (exists) {
|
||||
int varOffset = b.computeVariableValueOffset(scope.layout(), scope.start(), column.offset());
|
||||
b.deleteVariable(varOffset, this.isVarint());
|
||||
b.UnsetBit(scope.start(), column.nullBit());
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public static LayoutType fromCode(LayoutCode code) {
|
||||
LayoutType type = LayoutType.CodeIndex[code.value()];
|
||||
assert type != null : lenientFormat("Not Implemented: %s", code);
|
||||
return type;
|
||||
}
|
||||
|
||||
public final Result hasValue(RowBuffer b, RowCursor scope, LayoutColumn column) {
|
||||
if (!b.readBit(scope.start(), column.nullBit())) {
|
||||
return Result.NotFound;
|
||||
}
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* The physical layout code used to represent the type within the serialization.
|
||||
*/
|
||||
public LayoutCode layoutCode() {
|
||||
return this.layoutCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Human readable name of the type.
|
||||
*/
|
||||
public abstract String name();
|
||||
|
||||
/**
|
||||
* Helper for preparing the delete of a sparse field.
|
||||
*
|
||||
* @param b The row to delete from.
|
||||
* @param edit The parent edit containing the field to delete.
|
||||
* @param code The expected type of the field.
|
||||
* @return Success if the delete is permitted, the error code otherwise.
|
||||
*/
|
||||
public static Result prepareSparseDelete(RowBuffer b, RowCursor edit, LayoutCode code) {
|
||||
|
||||
if (edit.scopeType().isFixedArity()) {
|
||||
return Result.TypeConstraint;
|
||||
}
|
||||
|
||||
if (edit.immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
if (edit.exists() && LayoutCodeTraits.Canonicalize(edit.cellType().layoutCode()) != code) {
|
||||
return Result.TypeMismatch;
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for preparing the move of a sparse field into an existing restricted edit.
|
||||
*
|
||||
* @param b The row to read from.
|
||||
* @param destinationScope The parent set edit into which the field should be moved.
|
||||
* @param destinationCode The expected type of the edit moving within.
|
||||
* @param elementType The expected type of the elements within the edit.
|
||||
* @param srcEdit The field to be moved.
|
||||
* @param options The move options.
|
||||
* @param dstEdit If successful, a prepared insertion cursor for the destination.
|
||||
* @return Success if the move is permitted, the error code otherwise.
|
||||
* The source field is delete if the move prepare fails with a destination error.
|
||||
*/
|
||||
public static Result prepareSparseMove(
|
||||
RowBuffer b,
|
||||
RowCursor destinationScope,
|
||||
LayoutScope destinationCode,
|
||||
TypeArgument elementType,
|
||||
RowCursor srcEdit,
|
||||
UpdateOptions options,
|
||||
Out<RowCursor> dstEdit
|
||||
) {
|
||||
checkArgument(destinationScope.scopeType() == destinationCode);
|
||||
checkArgument(destinationScope.index() == 0, "Can only insert into a edit at the root");
|
||||
|
||||
// Prepare the delete of the source
|
||||
Result result = LayoutType.prepareSparseDelete(b, srcEdit, elementType.type().layoutCode());
|
||||
|
||||
if (result != Result.Success) {
|
||||
dstEdit.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!srcEdit.exists()) {
|
||||
dstEdit.setAndGet(null);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
if (destinationScope.immutable()) {
|
||||
b.deleteSparse(srcEdit);
|
||||
dstEdit.setAndGet(null);
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
if (!srcEdit.cellTypeArgs().equals(elementType.typeArgs())) {
|
||||
b.deleteSparse(srcEdit);
|
||||
dstEdit.setAndGet(null);
|
||||
return Result.TypeConstraint;
|
||||
}
|
||||
|
||||
if (options == UpdateOptions.InsertAt) {
|
||||
b.deleteSparse(srcEdit);
|
||||
dstEdit.setAndGet(null);
|
||||
return Result.TypeConstraint;
|
||||
}
|
||||
|
||||
// Prepare the insertion at the destination.
|
||||
dstEdit.setAndGet(b.prepareSparseMove(destinationScope, srcEdit));
|
||||
if ((options == UpdateOptions.Update) && (!dstEdit.get().exists())) {
|
||||
b.deleteSparse(srcEdit);
|
||||
dstEdit.setAndGet(null);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
if ((options == UpdateOptions.Insert) && dstEdit.get().exists()) {
|
||||
b.deleteSparse(srcEdit);
|
||||
dstEdit.setAndGet(null);
|
||||
return Result.Exists;
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for preparing the read of a sparse field.
|
||||
*
|
||||
* @param b The row to read from.
|
||||
* @param edit The parent edit containing the field to read.
|
||||
* @param code The expected type of the field.
|
||||
* @return Success if the read is permitted, the error code otherwise.
|
||||
*/
|
||||
public static Result prepareSparseRead(
|
||||
@Nonnull final RowBuffer b, @Nonnull final RowCursor edit, @Nonnull LayoutCode code) {
|
||||
|
||||
if (!edit.exists()) {
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
if (LayoutCodeTraits.Canonicalize(edit.cellType().layoutCode()) != code) {
|
||||
return Result.TypeMismatch;
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for preparing the write of a sparse field.
|
||||
*
|
||||
* @param b The row to write to.
|
||||
* @param edit The cursor for the field to write.
|
||||
* @param typeArg The (optional) type constraints.
|
||||
* @param options The write options.
|
||||
* @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 UpdateOptions options) {
|
||||
|
||||
if (edit.immutable() || (edit.scopeType().isUniqueScope() && !edit.deferUniqueIndex())) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
if (edit.scopeType().isFixedArity() && !(edit.scopeType() instanceof LayoutNullable)) {
|
||||
if ((edit.index() < edit.scopeTypeArgs().count()) && !typeArg.equals(edit.scopeTypeArgs().get(edit.index()))) {
|
||||
return Result.TypeConstraint;
|
||||
}
|
||||
} else if (edit.scopeType() instanceof LayoutTypedMap) {
|
||||
if (!((typeArg.type() instanceof LayoutTypedTuple) && typeArg.typeArgs().equals(edit.scopeTypeArgs()))) {
|
||||
return Result.TypeConstraint;
|
||||
}
|
||||
} else if (edit.scopeType().isTypedScope() && !typeArg.equals(edit.scopeTypeArgs().get(0))) {
|
||||
return Result.TypeConstraint;
|
||||
}
|
||||
|
||||
if ((options == UpdateOptions.InsertAt) && edit.scopeType().isFixedArity()) {
|
||||
return Result.TypeConstraint;
|
||||
}
|
||||
|
||||
if ((options == UpdateOptions.InsertAt) && !edit.scopeType().isFixedArity()) {
|
||||
edit.exists(false); // InsertAt never overwrites an existing item.
|
||||
}
|
||||
|
||||
if ((options == UpdateOptions.Update) && (!edit.exists())) {
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
if ((options == UpdateOptions.Insert) && edit.exists()) {
|
||||
return Result.Exists;
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public abstract Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column, Out<T> value);
|
||||
|
||||
public abstract Result readSparse(RowBuffer b, RowCursor edit, Out<T> value);
|
||||
|
||||
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);
|
||||
argsLenInBytes = tempOut_argsLenInBytes.get();
|
||||
lenInBytes.setAndGet((com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE) + argsLenInBytes);
|
||||
return new TypeArgument(itemCode, itemTypeArgs);
|
||||
}
|
||||
|
||||
public TypeArgumentList readTypeArgumentList(RowBuffer row, int offset, Out<Integer> lenInBytes) {
|
||||
lenInBytes.setAndGet(0);
|
||||
return TypeArgumentList.EMPTY;
|
||||
}
|
||||
|
||||
public Result readVariable(RowBuffer b, RowCursor scope, LayoutColumn column, Out<T> value) {
|
||||
value.setAndGet(null);
|
||||
return Result.Failure;
|
||||
}
|
||||
|
||||
/**
|
||||
* If fixed, the fixed size of the type's serialization in bytes, otherwise undefined.
|
||||
*/
|
||||
public int size() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* The physical layout type of the field cast to the specified type.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final <Value extends ILayoutType> Value typeAs() {
|
||||
return (Value)this;
|
||||
}
|
||||
|
||||
public abstract Result writeFixed(RowBuffer b, RowCursor scope, LayoutColumn column, T value);
|
||||
|
||||
public abstract Result writeSparse(RowBuffer b, RowCursor edit, T value);
|
||||
|
||||
public abstract Result writeSparse(RowBuffer b, RowCursor edit, T value, UpdateOptions options);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public Result writeVariable(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col, T value) {
|
||||
return Result.Failure;
|
||||
}
|
||||
|
||||
TypeArgument typeArg() {
|
||||
return this.typeArg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
public final class LayoutTypedArray extends LayoutIndexedScope {
|
||||
public LayoutTypedArray(boolean immutable) {
|
||||
super(immutable ? com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.IMMUTABLE_TYPED_ARRAY_SCOPE :
|
||||
com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.TYPED_ARRAY_SCOPE, immutable, true, false, false, true);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.Immutable ? "im_array_t" : "array_t";
|
||||
}
|
||||
|
||||
public int countTypeArgument(TypeArgumentList value) {
|
||||
checkState(value.count() == 1);
|
||||
return (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE) + value.get(0).type().CountTypeArgument(value.get(0).typeArgs().clone());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean HasImplicitTypeCode(Reference<RowCursor> edit) {
|
||||
checkState(edit.get().index() >= 0);
|
||||
checkState(edit.get().scopeTypeArgs().count() == 1);
|
||||
return !LayoutCodeTraits.AlwaysRequiresTypeCode(edit.get().scopeTypeArgs().get(0).type().LayoutCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeArgumentList readTypeArgumentList(Reference<RowBuffer> row, int offset,
|
||||
Out<Integer> lenInBytes) {
|
||||
return new TypeArgumentList(new TypeArgument[] { LayoutType.readTypeArgument(row, offset, lenInBytes) });
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitTypeCode(RowCursor edit) {
|
||||
edit.get().cellType = edit.get().scopeTypeArgs().get(0).type();
|
||||
edit.get().cellTypeArgs = edit.get().scopeTypeArgs().get(0).typeArgs().clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, Out<RowCursor> value) {
|
||||
return writeScope(b, edit, typeArgs, UpdateOptions.Upsert, value);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteScope(ref RowBuffer b, ref RowCursor edit, TypeArgumentList
|
||||
// typeArgs, out RowCursor value, UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, UpdateOptions options, Out<RowCursor> value) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, new TypeArgument(this, typeArgs.clone()), options);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteTypedArray(edit, this, typeArgs.clone(), options, value.clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeTypeArgument(Reference<RowBuffer> row, int offset, TypeArgumentList value) {
|
||||
checkState(value.count() == 1);
|
||||
row.get().writeSparseTypeCode(offset, this.LayoutCode);
|
||||
int lenInBytes = (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
lenInBytes += value.get(0).type().writeTypeArgument(row, offset + lenInBytes,
|
||||
value.get(0).typeArgs().clone());
|
||||
return lenInBytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
public final class LayoutTypedMap extends LayoutUniqueScope {
|
||||
public LayoutTypedMap(boolean immutable) {
|
||||
super(immutable ? com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.IMMUTABLE_TYPED_MAP_SCOPE :
|
||||
com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.TYPED_MAP_SCOPE, immutable, isSizedScope():
|
||||
true, isTypedScope():true)
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.Immutable ? "im_map_t" : "map_t";
|
||||
}
|
||||
|
||||
public int countTypeArgument(TypeArgumentList value) {
|
||||
checkState(value.count() == 2);
|
||||
int lenInBytes = (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
for (TypeArgument arg : value) {
|
||||
lenInBytes += arg.type().CountTypeArgument(arg.typeArgs().clone());
|
||||
}
|
||||
|
||||
return lenInBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeArgument FieldType(Reference<RowCursor> scope) {
|
||||
return new TypeArgument(scope.get().scopeType().Immutable ? ImmutableTypedTuple :
|
||||
TypedTuple, scope.get().scopeTypeArgs().clone());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean HasImplicitTypeCode(Reference<RowCursor> edit) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeArgumentList readTypeArgumentList(Reference<RowBuffer> row, int offset,
|
||||
Out<Integer> lenInBytes) {
|
||||
lenInBytes.setAndGet(0);
|
||||
TypeArgument[] retval = new TypeArgument[2];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
int itemLenInBytes;
|
||||
Out<Integer> tempOut_itemLenInBytes = new Out<Integer>();
|
||||
retval[i] = readTypeArgument(row, offset + lenInBytes.get(), tempOut_itemLenInBytes);
|
||||
itemLenInBytes = tempOut_itemLenInBytes.get();
|
||||
lenInBytes.setAndGet(lenInBytes.get() + itemLenInBytes);
|
||||
}
|
||||
|
||||
return new TypeArgumentList(retval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitTypeCode(RowCursor edit) {
|
||||
edit.get().cellType = edit.get().scopeType().Immutable ? ImmutableTypedTuple :
|
||||
TypedTuple;
|
||||
edit.get().cellTypeArgs = edit.get().scopeTypeArgs().clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, Out<RowCursor> value) {
|
||||
return writeScope(b, edit, typeArgs, UpdateOptions.Upsert, value);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteScope(ref RowBuffer b, ref RowCursor edit, TypeArgumentList
|
||||
// typeArgs, out RowCursor value, UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, UpdateOptions options, Out<RowCursor> value) {
|
||||
Result result = prepareSparseWrite(b, edit, new TypeArgument(this, typeArgs.clone()), options);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteTypedMap(edit, this, typeArgs.clone(), options, value.clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeTypeArgument(Reference<RowBuffer> row, int offset, TypeArgumentList value) {
|
||||
checkState(value.count() == 2);
|
||||
row.get().writeSparseTypeCode(offset, this.LayoutCode);
|
||||
int lenInBytes = (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
for (TypeArgument arg : value) {
|
||||
lenInBytes += arg.type().writeTypeArgument(row, offset + lenInBytes, arg.typeArgs().clone());
|
||||
}
|
||||
|
||||
return lenInBytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.IMMUTABLE_TYPED_SET_SCOPE;
|
||||
import static com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.TYPED_SET_SCOPE;
|
||||
|
||||
public final class LayoutTypedSet extends LayoutUniqueScope {
|
||||
public LayoutTypedSet(boolean immutable) {
|
||||
super(immutable ? IMMUTABLE_TYPED_SET_SCOPE : TYPED_SET_SCOPE, immutable, true, true);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.Immutable ? "im_set_t" : "set_t";
|
||||
}
|
||||
|
||||
public int countTypeArgument(TypeArgumentList value) {
|
||||
checkState(value.count() == 1);
|
||||
return (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE) + value.get(0).type().CountTypeArgument(value.get(0).typeArgs().clone());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeArgument FieldType(Reference<RowCursor> scope) {
|
||||
return scope.get().scopeTypeArgs().get(0).clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean HasImplicitTypeCode(Reference<RowCursor> edit) {
|
||||
checkState(edit.get().index() >= 0);
|
||||
checkState(edit.get().scopeTypeArgs().count() == 1);
|
||||
return !LayoutCodeTraits.AlwaysRequiresTypeCode(edit.get().scopeTypeArgs().get(0).type().LayoutCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeArgumentList readTypeArgumentList(Reference<RowBuffer> row, int offset,
|
||||
Out<Integer> lenInBytes) {
|
||||
return new TypeArgumentList(new TypeArgument[] { readTypeArgument(row, offset, lenInBytes) });
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitTypeCode(RowCursor edit) {
|
||||
edit.get().cellType = edit.get().scopeTypeArgs().get(0).type();
|
||||
edit.get().cellTypeArgs = edit.get().scopeTypeArgs().get(0).typeArgs().clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, Out<RowCursor> value) {
|
||||
return writeScope(b, edit, typeArgs, UpdateOptions.Upsert, value);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteScope(ref RowBuffer b, ref RowCursor edit, TypeArgumentList
|
||||
// typeArgs, out RowCursor value, UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, UpdateOptions options, Out<RowCursor> value) {
|
||||
Result result = prepareSparseWrite(b, edit, new TypeArgument(this, typeArgs.clone()), options);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteTypedSet(edit, this, typeArgs.clone(), options, value.clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeTypeArgument(Reference<RowBuffer> row, int offset, TypeArgumentList value) {
|
||||
checkArgument(value.count() == 1);
|
||||
row.get().writeSparseTypeCode(offset, this.LayoutCode);
|
||||
int lenInBytes = (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
lenInBytes += value.get(0).type().writeTypeArgument(row, offset + lenInBytes,
|
||||
value.get(0).typeArgs().clone());
|
||||
return lenInBytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutTypedTuple extends LayoutIndexedScope {
|
||||
public LayoutTypedTuple(boolean immutable) {
|
||||
super(immutable ? com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.IMMUTABLE_TYPED_TUPLE_SCOPE :
|
||||
com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.TYPED_TUPLE_SCOPE, immutable, true, true, false, true);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.Immutable ? "im_tuple_t" : "tuple_t";
|
||||
}
|
||||
|
||||
public int countTypeArgument(TypeArgumentList value) {
|
||||
int lenInBytes = (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: lenInBytes += RowBuffer.Count7BitEncodedUInt((ulong)value.Count);
|
||||
lenInBytes += RowBuffer.count7BitEncodedUInt(value.count());
|
||||
for (TypeArgument arg : value) {
|
||||
lenInBytes += arg.type().CountTypeArgument(arg.typeArgs().clone());
|
||||
}
|
||||
|
||||
return lenInBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean HasImplicitTypeCode(Reference<RowCursor> edit) {
|
||||
checkArgument(edit.get().index() >= 0);
|
||||
checkArgument(edit.get().scopeTypeArgs().count() > edit.get().index());
|
||||
return !LayoutCodeTraits.AlwaysRequiresTypeCode(edit.get().scopeTypeArgs().get(edit.get().index()).type().LayoutCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeArgumentList readTypeArgumentList(Reference<RowBuffer> row, int offset,
|
||||
Out<Integer> lenInBytes) {
|
||||
int numTypeArgs = row.get().intValue().Read7BitEncodedUInt(offset, lenInBytes);
|
||||
TypeArgument[] retval = new TypeArgument[numTypeArgs];
|
||||
for (int i = 0; i < numTypeArgs; i++) {
|
||||
int itemLenInBytes;
|
||||
Out<Integer> tempOut_itemLenInBytes = new Out<Integer>();
|
||||
retval[i] = LayoutType.readTypeArgument(row, offset + lenInBytes.get(), tempOut_itemLenInBytes);
|
||||
itemLenInBytes = tempOut_itemLenInBytes.get();
|
||||
lenInBytes.setAndGet(lenInBytes.get() + itemLenInBytes);
|
||||
}
|
||||
|
||||
return new TypeArgumentList(retval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitTypeCode(RowCursor edit) {
|
||||
edit.get().cellType = edit.get().scopeTypeArgs().get(edit.get().index()).type();
|
||||
edit.get().cellTypeArgs = edit.get().scopeTypeArgs().get(edit.get().index()).typeArgs().clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, Out<RowCursor> value) {
|
||||
return writeScope(b, edit, typeArgs, UpdateOptions.Upsert, value);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteScope(ref RowBuffer b, ref RowCursor edit, TypeArgumentList
|
||||
// typeArgs, out RowCursor value, UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, UpdateOptions options, Out<RowCursor> value) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, new TypeArgument(this, typeArgs.clone()), options);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteTypedTuple(edit, this, typeArgs.clone(), options, value.clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeTypeArgument(Reference<RowBuffer> row, int offset, TypeArgumentList value) {
|
||||
row.get().writeSparseTypeCode(offset, this.LayoutCode);
|
||||
int lenInBytes = (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE);
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: lenInBytes += row.Write7BitEncodedUInt(offset + lenInBytes, (ulong)value.Count);
|
||||
lenInBytes += row.get().write7BitEncodedUInt(offset + lenInBytes, value.count());
|
||||
for (TypeArgument arg : value) {
|
||||
lenInBytes += arg.type().writeTypeArgument(row, offset + lenInBytes, arg.typeArgs().clone());
|
||||
}
|
||||
|
||||
return lenInBytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
/**
|
||||
* Layout type definitions
|
||||
*/
|
||||
public abstract class LayoutTypes {
|
||||
public static final LayoutArray ARRAY = new LayoutArray(false);
|
||||
public static final LayoutBinary BINARY = new LayoutBinary();
|
||||
public static final int BitsPerByte = 8;
|
||||
public static final LayoutBoolean BOOLEAN = new LayoutBoolean(true);
|
||||
public static final LayoutBoolean BooleanFalse = new LayoutBoolean(false);
|
||||
public static final LayoutDateTime DATE_TIME = new LayoutDateTime();
|
||||
public static final LayoutDecimal DECIMAL = new LayoutDecimal();
|
||||
public static final LayoutEndScope END_SCOPE = new LayoutEndScope();
|
||||
public static final LayoutFloat128 FLOAT_128 = new LayoutFloat128();
|
||||
public static final LayoutFloat32 FLOAT_32 = new LayoutFloat32();
|
||||
public static final LayoutFloat64 FLOAT_64 = new LayoutFloat64();
|
||||
public static final LayoutGuid GUID = new LayoutGuid();
|
||||
public static final LayoutArray ImmutableArray = new LayoutArray(true);
|
||||
public static final LayoutNullable ImmutableNullable = new LayoutNullable(true);
|
||||
public static final LayoutObject ImmutableObject = new LayoutObject(true);
|
||||
public static final LayoutTagged ImmutableTagged = new LayoutTagged(true);
|
||||
public static final LayoutTagged2 ImmutableTagged2 = new LayoutTagged2(true);
|
||||
public static final LayoutTuple ImmutableTuple = new LayoutTuple(true);
|
||||
public static final LayoutTypedArray ImmutableTypedArray = new LayoutTypedArray(true);
|
||||
public static final LayoutTypedMap ImmutableTypedMap = new LayoutTypedMap(true);
|
||||
public static final LayoutTypedSet ImmutableTypedSet = new LayoutTypedSet(true);
|
||||
public static final LayoutTypedTuple ImmutableTypedTuple = new LayoutTypedTuple(true);
|
||||
public static final LayoutUDT ImmutableUDT = new LayoutUDT(true);
|
||||
public static final LayoutInt16 INT_16 = new LayoutInt16();
|
||||
public static final LayoutInt32 INT_32 = new LayoutInt32();
|
||||
public static final LayoutInt64 INT_64 = new LayoutInt64();
|
||||
public static final LayoutInt8 INT_8 = new LayoutInt8();
|
||||
public static final LayoutMongoDbObjectId MONGODB_OBJECT_ID = new LayoutMongoDbObjectId();
|
||||
public static final LayoutNull NULL = new LayoutNull();
|
||||
public static final LayoutNullable NULLABLE = new LayoutNullable(false);
|
||||
public static final LayoutObject OBJECT = new LayoutObject(false);
|
||||
public static final LayoutTagged TAGGED = new LayoutTagged(false);
|
||||
public static final LayoutTagged2 TAGGED_2 = new LayoutTagged2(false);
|
||||
public static final LayoutTuple TUPLE = new LayoutTuple(false);
|
||||
public static final LayoutTypedArray TYPED_ARRAY = new LayoutTypedArray(false);
|
||||
public static final LayoutTypedMap TypedMap = new LayoutTypedMap(false);
|
||||
public static final LayoutTypedSet TypedSet = new LayoutTypedSet(false);
|
||||
public static final LayoutTypedTuple TYPED_TUPLE = new LayoutTypedTuple(false);
|
||||
public static final LayoutUDT UDT = new LayoutUDT(false);
|
||||
public static final LayoutUInt16 UINT_16 = new LayoutUInt16();
|
||||
public static final LayoutUInt32 UINT_32 = new LayoutUInt32();
|
||||
public static final LayoutUInt64 UINT_64 = new LayoutUInt64();
|
||||
public static final LayoutUInt8 UINT_8 = new LayoutUInt8();
|
||||
public static final LayoutUnixDateTime UNIX_DATE_TIME = new LayoutUnixDateTime();
|
||||
public static final LayoutUtf8 UTF_8 = new LayoutUtf8();
|
||||
public static final LayoutVarInt VAR_INT = new LayoutVarInt();
|
||||
public static final LayoutVarUInt VAR_UINT = new LayoutVarUInt();
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
|
||||
|
||||
public final class LayoutUDT extends LayoutPropertyScope {
|
||||
public LayoutUDT(boolean immutable) {
|
||||
super(immutable ? com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.IMMUTABLE_SCHEMA :
|
||||
com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SCHEMA, immutable);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this.Immutable ? "im_udt" : "udt";
|
||||
}
|
||||
|
||||
public int countTypeArgument(TypeArgumentList value) {
|
||||
return (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE) + SchemaId.SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeArgumentList readTypeArgumentList(Reference<RowBuffer> row, int offset,
|
||||
Out<Integer> lenInBytes) {
|
||||
SchemaId schemaId = row.get().ReadSchemaId(offset).clone();
|
||||
lenInBytes.setAndGet(SchemaId.SIZE);
|
||||
return new TypeArgumentList(schemaId.clone());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, Out<RowCursor> value) {
|
||||
return writeScope(b, edit, typeArgs, UpdateOptions.Upsert, value);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteScope(ref RowBuffer b, ref RowCursor edit, TypeArgumentList
|
||||
// typeArgs, out RowCursor value, UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeScope(RowBuffer b, RowCursor edit,
|
||||
TypeArgumentList typeArgs, UpdateOptions options, Out<RowCursor> value) {
|
||||
Layout udt = b.get().resolver().resolve(typeArgs.schemaId().clone());
|
||||
Result result = prepareSparseWrite(b, edit, new TypeArgument(this, typeArgs.clone()), options);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseUDT(edit, this, udt, options, value.clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeTypeArgument(Reference<RowBuffer> row, int offset, TypeArgumentList value) {
|
||||
row.get().writeSparseTypeCode(offset, this.LayoutCode);
|
||||
row.get().WriteSchemaId(offset + (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE), value.schemaId().clone());
|
||||
return (com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.SIZE / Byte.SIZE) + SchemaId.SIZE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public sealed class LayoutUInt16 : LayoutType<ushort>
|
||||
public final class LayoutUInt16 extends LayoutType<Short> {
|
||||
public LayoutUInt16() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.UINT_16, (Short.SIZE / Byte.SIZE));
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "uint16";
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, out
|
||||
// ushort value)
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Short> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(0);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadUInt16(scope.get().start() + column.getOffset()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadSparse(ref RowBuffer b, ref RowCursor edit, out ushort value)
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<Short> value) {
|
||||
Result result = prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseUInt16(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result WriteFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, ushort
|
||||
// value)
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
short value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteUInt16(scope.get().start() + col.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, ushort value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, short value,
|
||||
UpdateOptions options) {
|
||||
Result result = prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseUInt16(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, short value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public sealed class LayoutUInt32 : LayoutType<uint>
|
||||
public final class LayoutUInt32 extends LayoutType<Integer> {
|
||||
public LayoutUInt32() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.UINT_32, (Integer.SIZE / Byte.SIZE));
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "uint32";
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, out
|
||||
// uint value)
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Integer> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(0);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadUInt32(scope.get().start() + column.getOffset()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadSparse(ref RowBuffer b, ref RowCursor edit, out uint value)
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<Integer> value) {
|
||||
Result result = prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseUInt32(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result WriteFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, uint
|
||||
// value)
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
int value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteUInt32(scope.get().start() + col.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, uint value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, int value,
|
||||
UpdateOptions options) {
|
||||
Result result = prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseUInt32(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, int value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public sealed class LayoutUInt64 : LayoutType<ulong>
|
||||
public final class LayoutUInt64 extends LayoutType<Long> {
|
||||
public LayoutUInt64() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.UINT_64, (Long.SIZE / Byte.SIZE));
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "uint64";
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, out
|
||||
// ulong value)
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Long> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(0);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadUInt64(scope.get().start() + column.getOffset()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadSparse(ref RowBuffer b, ref RowCursor edit, out ulong value)
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<Long> value) {
|
||||
Result result = prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseUInt64(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result WriteFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, ulong
|
||||
// value)
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
long value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteUInt64(scope.get().start() + col.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, ulong value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, long value,
|
||||
UpdateOptions options) {
|
||||
Result result = prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseUInt64(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, long value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public sealed class LayoutUInt8 : LayoutType<byte>
|
||||
public final class LayoutUInt8 extends LayoutType<Byte> {
|
||||
public LayoutUInt8() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.UINT_8, 1);
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "uint8";
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, out
|
||||
// byte value)
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Byte> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(0);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadUInt8(scope.get().start() + column.getOffset()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadSparse(ref RowBuffer b, ref RowCursor edit, out byte value)
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<Byte> value) {
|
||||
Result result = prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseUInt8(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result WriteFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, byte
|
||||
// value)
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
byte value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteUInt8(scope.get().start() + col.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, byte value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, byte value,
|
||||
UpdateOptions options) {
|
||||
Result result = prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseUInt8(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, byte value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowOptions;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursors;
|
||||
|
||||
public abstract class LayoutUniqueScope extends LayoutIndexedScope {
|
||||
protected LayoutUniqueScope(LayoutCode code, boolean immutable, boolean isSizedScope, boolean isTypedScope) {
|
||||
// TODO: C# TO JAVA CONVERTER: C# to Java Converter could not resolve the named parameters in the
|
||||
// following line:
|
||||
//ORIGINAL LINE: base(code, immutable, isSizedScope, isFixedArity: false, isUniqueScope: true, isTypedScope:
|
||||
// isTypedScope);
|
||||
super(code, immutable, isSizedScope, false, true, isTypedScope);
|
||||
}
|
||||
|
||||
public abstract TypeArgument FieldType(Reference<RowCursor> scope);
|
||||
|
||||
/**
|
||||
* Search for a matching field within a unique index.
|
||||
*
|
||||
* @param b The row to search.
|
||||
* @param scope The parent unique index edit to search.
|
||||
* @param patternScope The parent edit from which the match pattern is read.
|
||||
* @param value If successful, the updated edit.
|
||||
* @return Success a matching field exists in the unique index, NotFound if no match is found, the
|
||||
* error code otherwise.
|
||||
* <p>
|
||||
* The pattern field is delete whether the find succeeds or fails.
|
||||
*/
|
||||
public final Result Find(Reference<RowBuffer> b, Reference<RowCursor> scope,
|
||||
Reference<RowCursor> patternScope, Out<RowCursor> value) {
|
||||
Result result = LayoutType.prepareSparseMove(b, scope, this, this.FieldType(scope).clone(), patternScope, UpdateOptions.Update, value.clone());
|
||||
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if the search found the result.
|
||||
b.get().deleteSparse(patternScope);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public Result MoveField(ref RowBuffer b, ref RowCursor destinationScope, ref RowCursor
|
||||
// sourceEdit, UpdateOptions options = UpdateOptions.Upsert)
|
||||
public final Result MoveField(Reference<RowBuffer> b, Reference<RowCursor> destinationScope,
|
||||
Reference<RowCursor> sourceEdit, UpdateOptions options) {
|
||||
RowCursor dstEdit;
|
||||
Out<RowCursor> tempOut_dstEdit =
|
||||
new Out<RowCursor>();
|
||||
Result result = LayoutType.prepareSparseMove(b, destinationScope, this,
|
||||
this.FieldType(destinationScope).clone(), sourceEdit, options, tempOut_dstEdit);
|
||||
dstEdit = tempOut_dstEdit.get();
|
||||
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Perform the move.
|
||||
Reference<RowCursor> tempReference_dstEdit =
|
||||
new Reference<RowCursor>(dstEdit);
|
||||
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
|
||||
// highest item seen. Then we would avoid the maximum reparse.
|
||||
destinationScope.get().count(dstEdit.count());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves an existing sparse field into the unique index.
|
||||
*
|
||||
* @param b The row to move within.
|
||||
* @param destinationScope The parent unique indexed edit into which the field should be moved.
|
||||
* @param sourceEdit The field to be moved.
|
||||
* @param options The move options.
|
||||
* @return Success if the field is permitted within the unique index, the error code otherwise.
|
||||
* <p>
|
||||
* The source field MUST be a field whose type arguments match the element type of the
|
||||
* destination unique index.
|
||||
* <para />
|
||||
* The source field is delete whether the move succeeds or fails.
|
||||
*/
|
||||
|
||||
public final Result MoveField(Reference<RowBuffer> b, Reference<RowCursor> destinationScope,
|
||||
Reference<RowCursor> sourceEdit) {
|
||||
return MoveField(b, destinationScope, sourceEdit, UpdateOptions.Upsert);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteScope<TContext>(ref RowBuffer b, ref RowCursor scope,
|
||||
// TypeArgumentList typeArgs, TContext context, WriterFunc<TContext> func, UpdateOptions options = UpdateOptions
|
||||
// .Upsert)
|
||||
@Override
|
||||
public <TContext> Result writeScope(RowBuffer b, RowCursor scope,
|
||||
TypeArgumentList typeArgs, TContext context, WriterFunc<TContext> func,
|
||||
UpdateOptions options) {
|
||||
RowCursor uniqueScope;
|
||||
// TODO: C# TO JAVA CONVERTER: The following method call contained an unresolved 'out' keyword - these
|
||||
// cannot be converted using the 'Out' helper class unless the method is within the code being modified:
|
||||
Result r = this.WriteScope(b, scope, typeArgs.clone(), out uniqueScope, options);
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
RowCursor childScope;
|
||||
// TODO: C# TO JAVA CONVERTER: The following method call contained an unresolved 'out' keyword - these
|
||||
// cannot be converted using the 'Out' helper class unless the method is within the code being modified:
|
||||
uniqueScope.Clone(out childScope);
|
||||
childScope.deferUniqueIndex = true;
|
||||
Reference<RowCursor> tempReference_childScope =
|
||||
new Reference<RowCursor>(childScope);
|
||||
// TODO: C# TO JAVA CONVERTER: The following line could not be converted:
|
||||
r = func == null ? null : func.Invoke(ref b, ref childScope, context) ??Result.Success;
|
||||
childScope = tempReference_childScope.get();
|
||||
if (r != Result.Success) {
|
||||
this.deleteScope(b, scope);
|
||||
return r;
|
||||
}
|
||||
|
||||
uniqueScope.count(childScope.count());
|
||||
Reference<RowCursor> tempReference_uniqueScope =
|
||||
new Reference<RowCursor>(uniqueScope);
|
||||
r = b.get().TypedCollectionUniqueIndexRebuild(tempReference_uniqueScope);
|
||||
uniqueScope = tempReference_uniqueScope.get();
|
||||
if (r != Result.Success) {
|
||||
this.deleteScope(b, scope);
|
||||
return r;
|
||||
}
|
||||
|
||||
Reference<RowCursor> tempReference_childScope2 =
|
||||
new Reference<RowCursor>(childScope);
|
||||
RowCursors.skip(scope.get().clone(), b,
|
||||
tempReference_childScope2);
|
||||
childScope = tempReference_childScope2.get();
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <TContext> Result writeScope(RowBuffer b, RowCursor scope,
|
||||
TypeArgumentList typeArgs, TContext context, WriterFunc<TContext> func) {
|
||||
return writeScope(b, scope, typeArgs, context, func, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.UnixDateTime;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutUnixDateTime extends LayoutType<com.azure.data.cosmos.serialization.hybridrow.UnixDateTime> {
|
||||
public LayoutUnixDateTime() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.UNIX_DATE_TIME,
|
||||
com.azure.data.cosmos.serialization.hybridrow.UnixDateTime.Size);
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "unixdatetime";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<UnixDateTime> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(null);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadUnixDateTime(scope.get().start() + column.getOffset()).clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<UnixDateTime> value) {
|
||||
Result result = prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseUnixDateTime(edit).clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
UnixDateTime value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteUnixDateTime(scope.get().start() + column.getOffset(), value.clone());
|
||||
b.get().SetBit(scope.get().start(), column.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, UnixDateTime value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit, UnixDateTime value
|
||||
, UpdateOptions options) {
|
||||
Result result = prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseUnixDateTime(edit, value.clone(), options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit, UnixDateTime value) {
|
||||
return writeSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutUtf8 extends LayoutType<String> implements ILayoutUtf8SpanWritable, ILayoutUtf8SpanReadable {
|
||||
public LayoutUtf8() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.UTF_8, 0);
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "utf8";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<String> value) {
|
||||
Utf8Span span;
|
||||
// TODO: C# TO JAVA CONVERTER: The following method call contained an unresolved 'out' keyword - these
|
||||
// cannot be converted using the 'Out' helper class unless the method is within the code being modified:
|
||||
Result r = this.ReadFixed(b, scope, column, out span);
|
||||
value.setAndGet((r == Result.Success) ? span.toString() :)
|
||||
default
|
||||
return r;
|
||||
}
|
||||
|
||||
public Result ReadFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
Out<Utf8Span> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
checkArgument(col.getSize() >= 0);
|
||||
if (!b.get().readBit(scope.get().start(), col.getNullBit().clone())) {
|
||||
value.setAndGet(null);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadFixedString(scope.get().start() + col.getOffset(), col.getSize()));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit,
|
||||
Out<String> value) {
|
||||
Utf8Span span;
|
||||
// TODO: C# TO JAVA CONVERTER: The following method call contained an unresolved 'out' keyword - these
|
||||
// cannot be converted using the 'Out' helper class unless the method is within the code being modified:
|
||||
Result r = this.ReadSparse(b, edit, out span);
|
||||
value.setAndGet((r == Result.Success) ? span.toString() :)
|
||||
default
|
||||
return r;
|
||||
}
|
||||
|
||||
public Result ReadSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, Out<Utf8Span> value) {
|
||||
Result result = LayoutType.prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseString(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readVariable(RowBuffer b, RowCursor scope, LayoutColumn column
|
||||
, Out<String> value) {
|
||||
Utf8Span span;
|
||||
// TODO: C# TO JAVA CONVERTER: The following method call contained an unresolved 'out' keyword - these
|
||||
// cannot be converted using the 'Out' helper class unless the method is within the code being modified:
|
||||
Result r = this.ReadVariable(b, scope, column, out span);
|
||||
value.setAndGet((r == Result.Success) ? span.toString() :)
|
||||
default
|
||||
return r;
|
||||
}
|
||||
|
||||
public Result ReadVariable(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col
|
||||
, Out<Utf8Span> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), col.getNullBit().clone())) {
|
||||
value.setAndGet(null);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
int varOffset = b.get().computeVariableValueOffset(scope.get().layout(), scope.get().start(),
|
||||
col.getOffset());
|
||||
value.setAndGet(b.get().ReadVariableString(varOffset));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
String value) {
|
||||
checkArgument(value != null);
|
||||
return this.WriteFixed(b, scope, column, Utf8Span.TranscodeUtf16(value));
|
||||
}
|
||||
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
Utf8Span value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
checkArgument(col.getSize() >= 0);
|
||||
checkArgument(value.Length == col.getSize());
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
b.get().WriteFixedString(scope.get().start() + col.getOffset(), value);
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit, String value) {
|
||||
return writeSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, string value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result writeSparse(RowBuffer b, RowCursor edit, String value,
|
||||
UpdateOptions options) {
|
||||
checkArgument(value != null);
|
||||
return this.WriteSparse(b, edit, Utf8Span.TranscodeUtf16(value), options);
|
||||
}
|
||||
|
||||
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, Utf8Span value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public Result WriteSparse(ref RowBuffer b, ref RowCursor edit, Utf8Span value, UpdateOptions
|
||||
// options = UpdateOptions.Upsert)
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, Utf8Span value,
|
||||
UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseString(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result writeVariable(Reference<RowBuffer> b, Reference<RowCursor> scope,
|
||||
LayoutColumn col, String value) {
|
||||
checkArgument(value != null);
|
||||
return this.WriteVariable(b, scope, col, Utf8Span.TranscodeUtf16(value));
|
||||
}
|
||||
|
||||
public Result WriteVariable(Reference<RowBuffer> b, Reference<RowCursor> scope,
|
||||
LayoutColumn col, Utf8Span value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
int length = value.Length;
|
||||
if ((col.getSize() > 0) && (length > col.getSize())) {
|
||||
return Result.TooBig;
|
||||
}
|
||||
|
||||
boolean exists = b.get().readBit(scope.get().start(), col.getNullBit().clone());
|
||||
int varOffset = b.get().computeVariableValueOffset(scope.get().layout(), scope.get().start(),
|
||||
col.getOffset());
|
||||
int shift;
|
||||
Out<Integer> tempOut_shift = new Out<Integer>();
|
||||
b.get().WriteVariableString(varOffset, value, exists, tempOut_shift);
|
||||
shift = tempOut_shift.get();
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
scope.get().metaOffset(scope.get().metaOffset() + shift);
|
||||
scope.get().valueOffset(scope.get().valueOffset() + shift);
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public final class LayoutVarInt extends LayoutType<Long> {
|
||||
public LayoutVarInt() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.VAR_INT, 0);
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isVarint() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "varint";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Long> value) {
|
||||
Contract.Fail("Not Implemented");
|
||||
value.setAndGet(0);
|
||||
return Result.Failure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit, Out<Long> value) {
|
||||
Result result = LayoutType.prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().ReadSparseVarInt(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result readVariable(RowBuffer b, RowCursor scope, LayoutColumn column, Out<Long> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(0);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
int varOffset = b.get().computeVariableValueOffset(scope.get().layout(), scope.get().start(),
|
||||
column.getOffset());
|
||||
value.setAndGet(b.get().ReadVariableInt(varOffset));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
long value) {
|
||||
Contract.Fail("Not Implemented");
|
||||
return Result.Failure;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, long value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, long value,
|
||||
UpdateOptions options) {
|
||||
Result result = LayoutType.prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseVarInt(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, long value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteVariable(Reference<RowBuffer> b, Reference<RowCursor> scope,
|
||||
LayoutColumn col, long value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
boolean exists = b.get().readBit(scope.get().start(), col.getNullBit().clone());
|
||||
int varOffset = b.get().computeVariableValueOffset(scope.get().layout(), scope.get().start(),
|
||||
col.getOffset());
|
||||
int shift;
|
||||
Out<Integer> tempOut_shift = new Out<Integer>();
|
||||
b.get().WriteVariableInt(varOffset, value, exists, tempOut_shift);
|
||||
shift = tempOut_shift.get();
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
scope.get().metaOffset(scope.get().metaOffset() + shift);
|
||||
scope.get().valueOffset(scope.get().valueOffset() + shift);
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public sealed class LayoutVarUInt : LayoutType<ulong>
|
||||
public final class LayoutVarUInt extends LayoutType<Long> {
|
||||
public LayoutVarUInt() {
|
||||
super(com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutCode.VAR_UINT, 0);
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isVarint() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "varuint";
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, out
|
||||
// ulong value)
|
||||
@Override
|
||||
public Result readFixed(RowBuffer b, RowCursor scope, LayoutColumn column,
|
||||
Out<Long> value) {
|
||||
Contract.Fail("Not Implemented");
|
||||
value.setAndGet(0);
|
||||
return Result.Failure;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadSparse(ref RowBuffer b, ref RowCursor edit, out ulong value)
|
||||
@Override
|
||||
public Result readSparse(RowBuffer b, RowCursor edit, Out<Long> value) {
|
||||
Result result = prepareSparseRead(b, edit, this.LayoutCode);
|
||||
if (result != Result.Success) {
|
||||
value.setAndGet(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
value.setAndGet(b.get().readSparseVarUInt(edit));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result ReadVariable(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, out
|
||||
// ulong value)
|
||||
@Override
|
||||
public Result readVariable(RowBuffer b, RowCursor scope, LayoutColumn column, Out<Long> value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (!b.get().readBit(scope.get().start(), column.getNullBit().clone())) {
|
||||
value.setAndGet(0);
|
||||
return Result.NotFound;
|
||||
}
|
||||
|
||||
int varOffset = b.get().computeVariableValueOffset(scope.get().layout(), scope.get().start(),
|
||||
column.getOffset());
|
||||
value.setAndGet(b.get().ReadVariableUInt(varOffset));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result WriteFixed(ref RowBuffer b, ref RowCursor scope, LayoutColumn col, ulong
|
||||
// value)
|
||||
@Override
|
||||
public Result WriteFixed(Reference<RowBuffer> b, Reference<RowCursor> scope, LayoutColumn col,
|
||||
long value) {
|
||||
Contract.Fail("Not Implemented");
|
||||
return Result.Failure;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public override Result WriteSparse(ref RowBuffer b, ref RowCursor edit, ulong value,
|
||||
// UpdateOptions options = UpdateOptions.Upsert)
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, long value,
|
||||
UpdateOptions options) {
|
||||
Result result = prepareSparseWrite(b, edit, this.typeArg().clone(), options);
|
||||
if (result != Result.Success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b.get().WriteSparseVarUInt(edit, value, options);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result WriteSparse(Reference<RowBuffer> b, Reference<RowCursor> edit, long value) {
|
||||
return WriteSparse(b, edit, value, UpdateOptions.Upsert);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public override Result WriteVariable(ref RowBuffer b, ref RowCursor scope, LayoutColumn col,
|
||||
// ulong value)
|
||||
@Override
|
||||
public Result WriteVariable(Reference<RowBuffer> b, Reference<RowCursor> scope,
|
||||
LayoutColumn col, long value) {
|
||||
checkArgument(scope.get().scopeType() instanceof LayoutUDT);
|
||||
if (scope.get().immutable()) {
|
||||
return Result.InsufficientPermissions;
|
||||
}
|
||||
|
||||
boolean exists = b.get().readBit(scope.get().start(), col.getNullBit().clone());
|
||||
int varOffset = b.get().computeVariableValueOffset(scope.get().layout(), scope.get().start(),
|
||||
col.getOffset());
|
||||
int shift;
|
||||
Out<Integer> tempOut_shift = new Out<Integer>();
|
||||
b.get().WriteVariableUInt(varOffset, value, exists, tempOut_shift);
|
||||
shift = tempOut_shift.get();
|
||||
b.get().SetBit(scope.get().start(), col.getNullBit().clone());
|
||||
scope.get().metaOffset(scope.get().metaOffset() + shift);
|
||||
scope.get().valueOffset(scope.get().valueOffset() + shift);
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
public class SamplingStringComparer implements IEqualityComparer<String> {
|
||||
public static final SamplingStringComparer Default = new SamplingStringComparer();
|
||||
|
||||
public final boolean equals(String x, String y) {
|
||||
checkArgument(x != null);
|
||||
checkArgument(y != null);
|
||||
|
||||
return x.equals(y);
|
||||
}
|
||||
|
||||
public final int hashCode(String obj) {
|
||||
checkArgument(obj != null);
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no equivalent to an 'unchecked' block in Java:
|
||||
unchecked
|
||||
{
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: uint hash1 = 5381;
|
||||
int hash1 = 5381;
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: uint hash2 = hash1;
|
||||
int hash2 = hash1;
|
||||
final int numSamples = 4;
|
||||
final int modulus = 13;
|
||||
|
||||
ReadOnlySpan<Character> utf16 = obj.AsSpan();
|
||||
int max = Math.min(utf16.Length, numSamples);
|
||||
for (int i = 0; i < max; i++) {
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: uint c = utf16[(i * modulus) % utf16.Length];
|
||||
int c = utf16[(i * modulus) % utf16.Length];
|
||||
if (i % 2 == 0) {
|
||||
hash1 = ((hash1 << 5) + hash1) ^ c;
|
||||
} else {
|
||||
hash2 = ((hash2 << 5) + hash2) ^ c;
|
||||
}
|
||||
}
|
||||
|
||||
return hash1 + (hash2 * 1566083941);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
public class SamplingUtf8StringComparer implements IEqualityComparer<Utf8String> {
|
||||
public static final SamplingUtf8StringComparer Default = new SamplingUtf8StringComparer();
|
||||
|
||||
public final boolean equals(Utf8String x, Utf8String y) {
|
||||
checkArgument(x != null);
|
||||
checkArgument(y != null);
|
||||
|
||||
return x.Span.equals(y.Span);
|
||||
}
|
||||
|
||||
public final int hashCode(Utf8String obj) {
|
||||
checkArgument(obj != null);
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no equivalent to an 'unchecked' block in Java:
|
||||
unchecked
|
||||
{
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: uint hash1 = 5381;
|
||||
int hash1 = 5381;
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: uint hash2 = hash1;
|
||||
int hash2 = hash1;
|
||||
final int numSamples = 4;
|
||||
final int modulus = 13;
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: ReadOnlySpan<byte> utf8 = obj.Span.Span;
|
||||
ReadOnlySpan<Byte> utf8 = obj.Span.Span;
|
||||
int max = Math.min(utf8.Length, numSamples);
|
||||
for (int i = 0; i < max; i++) {
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: uint c = utf8[(i * modulus) % utf8.Length];
|
||||
int c = utf8[(i * modulus) % utf8.Length];
|
||||
if (i % 2 == 0) {
|
||||
hash1 = ((hash1 << 5) + hash1) ^ c;
|
||||
} else {
|
||||
hash2 = ((hash2 << 5) + hash2) ^ c;
|
||||
}
|
||||
}
|
||||
|
||||
return hash1 + (hash2 * 1566083941);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Utf8String;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public final class StringToken implements Cloneable {
|
||||
|
||||
public static final StringToken NONE = new StringToken();
|
||||
|
||||
private final long id;
|
||||
private final Utf8String path;
|
||||
private final ByteBuf varint;
|
||||
|
||||
public StringToken(long id, @Nonnull Utf8String path) {
|
||||
|
||||
checkNotNull(path);
|
||||
|
||||
byte[] buffer = new byte[count7BitEncodedUInt(id)];
|
||||
StringToken.write7BitEncodedUInt(buffer, id);
|
||||
|
||||
this.varint = Unpooled.wrappedBuffer(buffer).asReadOnly();
|
||||
this.path = path;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
private StringToken() {
|
||||
this.id = 0L;
|
||||
this.path = Utf8String.EMPTY;
|
||||
this.varint = Unpooled.wrappedBuffer(new byte[1]).setInt(0, 0).asReadOnly();
|
||||
}
|
||||
|
||||
public boolean isNull() {
|
||||
return this.varint() == null;
|
||||
}
|
||||
|
||||
public long id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public Utf8String path() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public ByteBuf varint() {
|
||||
return this.varint;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StringToken clone() {
|
||||
|
||||
try {
|
||||
return (StringToken) super.clone();
|
||||
} catch (CloneNotSupportedException error) {
|
||||
assert false : error;
|
||||
throw new IllegalStateException(error);
|
||||
}
|
||||
}
|
||||
|
||||
private static int count7BitEncodedUInt(long value) {
|
||||
|
||||
// Count the number of bytes needed to write out an int 7 bits at a time.
|
||||
int i = 0;
|
||||
|
||||
while (value >= 0x80L) {
|
||||
i++;
|
||||
value >>>= 7;
|
||||
}
|
||||
|
||||
return ++i;
|
||||
}
|
||||
|
||||
private static int write7BitEncodedUInt(byte[] buffer, long value) {
|
||||
|
||||
// Write an unsigned long 7 bits at a time. The high bit of the byte, when set, indicates there are more bytes.
|
||||
int i = 0;
|
||||
|
||||
while (value >= 0x80L) {
|
||||
buffer[i++] = (byte) (value | 0x80);
|
||||
value >>>= 7;
|
||||
}
|
||||
|
||||
buffer[i++] = (byte) value;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Utf8String;
|
||||
import com.azure.data.cosmos.core.UtfAnyString;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
public final class StringTokenizer {
|
||||
|
||||
private final HashMap<String, StringToken> stringTokens;
|
||||
private final ArrayList<Utf8String> strings;
|
||||
private final HashMap<Utf8String, StringToken> tokens;
|
||||
|
||||
private int count;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link StringTokenizer} class.
|
||||
*/
|
||||
public StringTokenizer() {
|
||||
|
||||
this.tokens = new HashMap<>();
|
||||
this.tokens.put(Utf8String.EMPTY, new StringToken(0, Utf8String.EMPTY));
|
||||
|
||||
this.stringTokens = new HashMap<>();
|
||||
this.stringTokens.put("", new StringToken(0, Utf8String.EMPTY));
|
||||
|
||||
this.strings = new ArrayList<>();
|
||||
this.strings.add(Utf8String.EMPTY);
|
||||
|
||||
this.count = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up a token's corresponding string.
|
||||
*
|
||||
* @param token The token to look up.
|
||||
* @return True if successful, false otherwise.
|
||||
*/
|
||||
public Optional<Utf8String> tryFindString(long token) {
|
||||
return token >= (long)this.strings.size() ? Optional.empty() : Optional.of(this.strings.get((int) token));
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up a string's corresponding token.
|
||||
*
|
||||
* @param path The string to look up.
|
||||
* @return {@code true} if successful, {@code false} otherwise.
|
||||
*/
|
||||
public Optional<StringToken> findToken(UtfAnyString path) {
|
||||
|
||||
if (path.isNull()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (path.isUtf8()) {
|
||||
return Optional.ofNullable(this.tokens.get(path.toUtf8()));
|
||||
}
|
||||
|
||||
return Optional.ofNullable(this.stringTokens.get(path.toUtf16()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a token to a string
|
||||
* <p>
|
||||
* If the string already has a token, that token is returned instead.
|
||||
*
|
||||
* @param path The string to assign a new token.
|
||||
* @return The token assigned to the string.
|
||||
*/
|
||||
public StringToken add(Utf8String path) {
|
||||
checkArgument(path != null);
|
||||
final StringToken token = this.tokens.get(path);
|
||||
return token == null ? this.allocateToken(path) : token;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of unique tokens described by the encoding.
|
||||
*/
|
||||
public int count() {
|
||||
return this.count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a new token and assigns the string to it.
|
||||
*
|
||||
* @param path The string that needs a new token.
|
||||
* @return The new allocated token.
|
||||
*/
|
||||
private StringToken allocateToken(Utf8String path) {
|
||||
|
||||
final StringToken token = new StringToken(this.count++, path);
|
||||
|
||||
this.stringTokens.put(path.toUtf16(), token);
|
||||
this.tokens.put(path, token);
|
||||
this.strings.add(path);
|
||||
|
||||
checkState((long)this.strings.size() - 1 == token.id());
|
||||
return token;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
|
||||
|
||||
public final class SystemSchema {
|
||||
/**
|
||||
* SchemaId of the empty schema. This schema has no defined cells but can accomodate
|
||||
* unschematized sparse content.
|
||||
*/
|
||||
public static final SchemaId EmptySchemaId = new SchemaId(2147473650);
|
||||
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
|
||||
//ORIGINAL LINE: [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes",
|
||||
// Justification = "Type is immutable.")] public static readonly LayoutResolver LayoutResolver = SystemSchema
|
||||
// .LoadSchema();
|
||||
public static final LayoutResolver LayoutResolver = SystemSchema.LoadSchema();
|
||||
/**
|
||||
* SchemaId of HybridRow RecordIO Record Headers.
|
||||
*/
|
||||
public static final SchemaId RecordSchemaId = new SchemaId(2147473649);
|
||||
/**
|
||||
* SchemaId of HybridRow RecordIO Segments.
|
||||
*/
|
||||
public static final SchemaId SegmentSchemaId = new SchemaId(2147473648);
|
||||
|
||||
private static String FormatResourceName(Assembly assembly, String resourceName) {
|
||||
return assembly.GetName().Name + "." + resourceName.replace(" ", "_").replace("\\", ".").replace("/", ".");
|
||||
}
|
||||
|
||||
private static String GetEmbeddedResource(String resourceName) {
|
||||
Assembly assembly = Assembly.GetAssembly(RecordIOFormatter.class);
|
||||
resourceName = SystemSchema.FormatResourceName(assembly, resourceName);
|
||||
try (Stream resourceStream = assembly.GetManifestResourceStream(resourceName)) {
|
||||
if (resourceStream == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try (InputStreamReader reader = new InputStreamReader(resourceStream)) {
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static LayoutResolver LoadSchema() {
|
||||
String json = SystemSchema.GetEmbeddedResource("SystemSchemas\\SystemSchema.json");
|
||||
Namespace ns = Namespace.Parse(json);
|
||||
LayoutResolverNamespace resolver = new LayoutResolverNamespace(ns);
|
||||
return resolver;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public final class TypeArgument {
|
||||
|
||||
public static final TypeArgument NONE = new TypeArgument();
|
||||
private final LayoutType type;
|
||||
private final TypeArgumentList typeArgs;
|
||||
|
||||
private TypeArgument() {
|
||||
this.type = null;
|
||||
this.typeArgs = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link TypeArgument} struct.
|
||||
*
|
||||
* @param type The type of the constraint.
|
||||
*/
|
||||
public TypeArgument(LayoutType type) {
|
||||
checkNotNull(type);
|
||||
this.type = type;
|
||||
this.typeArgs = TypeArgumentList.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link TypeArgument} struct.
|
||||
*
|
||||
* @param type The type of the constraint.
|
||||
* @param typeArgs For generic types the type parameters.
|
||||
*/
|
||||
public TypeArgument(LayoutType type, TypeArgumentList typeArgs) {
|
||||
checkNotNull(type);
|
||||
this.type = type;
|
||||
this.typeArgs = typeArgs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
|
||||
if (null == other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return other instanceof TypeArgument && this.equals((TypeArgument) other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (this.type.hashCode() * 397) ^ this.typeArgs.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(TypeArgument other) {
|
||||
return this.type.equals(other.type) && this.typeArgs.equals(other.typeArgs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (this.type == null) {
|
||||
return "";
|
||||
}
|
||||
return this.type.name() + this.typeArgs.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* The physical layout type.
|
||||
*/
|
||||
public LayoutType type() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the type argument is itself generic, then its type arguments.
|
||||
*/
|
||||
public TypeArgumentList typeArgs() {
|
||||
return this.typeArgs;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import com.azure.data.cosmos.core.Json;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
@JsonSerialize(using = TypeArgumentList.JsonSerializer.class)
|
||||
public final class TypeArgumentList {
|
||||
|
||||
public static final TypeArgumentList EMPTY = new TypeArgumentList();
|
||||
|
||||
private final TypeArgument[] args;
|
||||
private final SchemaId schemaId;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link TypeArgumentList} class
|
||||
*
|
||||
* @param args arguments in the list
|
||||
*/
|
||||
public TypeArgumentList(@Nonnull final TypeArgument... args) {
|
||||
checkNotNull(args);
|
||||
this.args = args;
|
||||
this.schemaId = SchemaId.INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link TypeArgumentList} class
|
||||
*
|
||||
* @param schemaId for UDT fields, the schema id of the nested layout
|
||||
*/
|
||||
public TypeArgumentList(@Nonnull final SchemaId schemaId) {
|
||||
checkNotNull(schemaId);
|
||||
this.args = EMPTY.args;
|
||||
this.schemaId = schemaId;
|
||||
}
|
||||
|
||||
private TypeArgumentList() {
|
||||
this.args = new TypeArgument[] {};
|
||||
this.schemaId = SchemaId.INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of elements in this {@link TypeArgumentList}
|
||||
* <p>
|
||||
* @return number of arguments in the list
|
||||
*/
|
||||
public int count() {
|
||||
return this.args.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stream for iterating over elements in this {@link TypeArgumentList}
|
||||
* <p>
|
||||
* @return a stream for iterating over elements in this {@link TypeArgumentList}
|
||||
*/
|
||||
public Stream<TypeArgument> elements() {
|
||||
if (this.args.length == 0) {
|
||||
return Stream.empty();
|
||||
}
|
||||
return StreamSupport.stream(Arrays.spliterator(this.args), false);
|
||||
}
|
||||
|
||||
public boolean equals(TypeArgumentList other) {
|
||||
if (null == other) {
|
||||
return false;
|
||||
}
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
return this.schemaId().equals(other.schemaId()) && Arrays.equals(this.args, other.args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return other instanceof TypeArgumentList && this.equals((TypeArgumentList) other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Element at the specified position in this {@link TypeArgumentList}
|
||||
* <p>
|
||||
* @param index index of the element to return
|
||||
* @return element at the specified position in this {@link TypeArgumentList}
|
||||
*/
|
||||
public TypeArgument get(int index) {
|
||||
return this.args[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int hash = 19;
|
||||
hash = (hash * 397) ^ this.schemaId().hashCode();
|
||||
|
||||
for (TypeArgument a : this.args) {
|
||||
hash = (hash * 397) ^ a.hashCode();
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* For UDT fields, the schema id of the nested layout.
|
||||
*/
|
||||
public SchemaId schemaId() {
|
||||
return this.schemaId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Json.toString(this);
|
||||
}
|
||||
|
||||
static class JsonSerializer extends StdSerializer<TypeArgumentList> {
|
||||
|
||||
private JsonSerializer() {
|
||||
super(TypeArgumentList.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(TypeArgumentList value, JsonGenerator generator, SerializerProvider provider) throws IOException {
|
||||
|
||||
generator.writeStartObject();
|
||||
generator.writeObjectField("schemaId", value.schemaId);
|
||||
generator.writeArrayFieldStart("args");
|
||||
|
||||
for (TypeArgument element : value.args) {
|
||||
generator.writeString(element.toString());
|
||||
}
|
||||
|
||||
generator.writeEndArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.layouts;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Describes the desired behavior when writing a {@link LayoutType}.
|
||||
*/
|
||||
public enum UpdateOptions {
|
||||
|
||||
None(0),
|
||||
|
||||
/**
|
||||
* Overwrite an existing value.
|
||||
* <p>
|
||||
* An existing value is assumed to exist at the offset provided. The existing value is
|
||||
* replaced inline. The remainder of the row is resized to accomodate either an increase or decrease
|
||||
* in required space.
|
||||
*/
|
||||
Update(1),
|
||||
|
||||
/**
|
||||
* Insert a new value.
|
||||
* <p>
|
||||
* An existing value is assumed NOT to exist at the offset provided. The new value is
|
||||
* inserted immediately at the offset. The remainder of the row is resized to accomodate either an
|
||||
* increase or decrease in required space.
|
||||
*/
|
||||
Insert(2),
|
||||
|
||||
/**
|
||||
* Update an existing value or insert a new value, if no value exists.
|
||||
* <p>
|
||||
* If a value exists, then this operation becomes {@link Update}, otherwise it becomes
|
||||
* {@link Insert}.
|
||||
*/
|
||||
Upsert(3),
|
||||
|
||||
/**
|
||||
* Insert a new value moving existing values to the right.
|
||||
* <p>
|
||||
* Within an array scope, inserts a new value immediately at the index moving all subsequent
|
||||
* items to the right. In any other scope behaves the same as {@link Upsert}.
|
||||
*/
|
||||
InsertAt(4);
|
||||
|
||||
public static final int SIZE = java.lang.Integer.SIZE;
|
||||
private static java.util.HashMap<Integer, UpdateOptions> mappings;
|
||||
private int value;
|
||||
|
||||
UpdateOptions(int value) {
|
||||
this.value = value;
|
||||
mappings().put(value, this);
|
||||
}
|
||||
|
||||
public int value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public static UpdateOptions from(int value) {
|
||||
return mappings().get(value);
|
||||
}
|
||||
|
||||
private static java.util.HashMap<Integer, UpdateOptions> mappings() {
|
||||
if (mappings == null) {
|
||||
synchronized (UpdateOptions.class) {
|
||||
if (mappings == null) {
|
||||
mappings = new HashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return mappings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.recordio;
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java:
|
||||
///#pragma warning disable CA1051 // Do not declare visible instance fields
|
||||
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Java does not allow user-defined value types. The behavior of this class may differ
|
||||
// from the original:
|
||||
//ORIGINAL LINE: public struct Record
|
||||
public final class Record {
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public uint Crc32;
|
||||
public int Crc32;
|
||||
public int Length;
|
||||
|
||||
public Record() {
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public Record(int length, uint crc32)
|
||||
public Record(int length, int crc32) {
|
||||
this.Length = length;
|
||||
this.Crc32 = crc32;
|
||||
}
|
||||
|
||||
public Record clone() {
|
||||
Record varCopy = new Record();
|
||||
|
||||
varCopy.Length = this.Length;
|
||||
varCopy.Crc32 = this.Crc32;
|
||||
|
||||
return varCopy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.recordio;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.HybridRowHeader;
|
||||
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;
|
||||
|
||||
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 Result FormatRecord(ReadOnlyMemory<Byte> body, Out<RowBuffer> row) {
|
||||
return FormatRecord(body, row, null);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public static Result FormatRecord(ReadOnlyMemory<byte> body, out RowBuffer row,
|
||||
// ISpanResizer<byte> resizer = default)
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
public static Result FormatRecord(ReadOnlyMemory<Byte> body, Out<RowBuffer> row,
|
||||
ISpanResizer<Byte> resizer) {
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: resizer = resizer != null ? resizer : DefaultSpanResizer<byte>.Default;
|
||||
resizer = resizer != null ? resizer : DefaultSpanResizer < Byte >.Default;
|
||||
int estimatedSize = HybridRowHeader.SIZE + RecordIOFormatter.RecordLayout.getSize() + body.Length;
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: uint crc32 = Crc32.Update(0, body.Span);
|
||||
int crc32 = Crc32.Update(0, body.Span);
|
||||
Record record = new Record(body.Length, crc32);
|
||||
return RecordIOFormatter.FormatObject(resizer, estimatedSize, RecordIOFormatter.RecordLayout, record.clone(),
|
||||
RecordSerializer.Write, row.clone());
|
||||
}
|
||||
|
||||
public static Result FormatSegment(Segment segment, Out<RowBuffer> row) {
|
||||
return FormatSegment(segment, row, null);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public static Result FormatSegment(Segment segment, out RowBuffer row, ISpanResizer<byte>
|
||||
// resizer = default)
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
public static Result FormatSegment(Segment segment, Out<RowBuffer> row, ISpanResizer<Byte> resizer) {
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: resizer = resizer != null ? resizer : DefaultSpanResizer<byte>.Default;
|
||||
resizer = resizer != null ? resizer : DefaultSpanResizer < Byte >.Default;
|
||||
int estimatedSize =
|
||||
HybridRowHeader.SIZE + RecordIOFormatter.SegmentLayout.getSize() + segment.Comment == null ? null :
|
||||
segment.Comment.length() != null ? segment.Comment.length() : 0 + segment.SDL == null ? null :
|
||||
segment.SDL.length() != null ? segment.SDL.length() : 0 + 20;
|
||||
|
||||
return RecordIOFormatter.FormatObject(resizer, estimatedSize, RecordIOFormatter.SegmentLayout,
|
||||
segment.clone(), SegmentSerializer.Write, row.clone());
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: private static Result FormatObject<T>(ISpanResizer<byte> resizer, int initialCapacity, Layout
|
||||
// layout, T obj, RowWriter.WriterFunc<T> writer, out RowBuffer row)
|
||||
private static <T> Result FormatObject(ISpanResizer<Byte> resizer, int initialCapacity, Layout layout, T obj,
|
||||
RowWriter.WriterFunc<T> writer, Out<RowBuffer> row) {
|
||||
row.setAndGet(new RowBuffer(initialCapacity, resizer));
|
||||
row.get().initLayout(HybridRowVersion.V1, layout, SystemSchema.LayoutResolver);
|
||||
Result r = RowWriter.WriteBuffer(row.clone(), obj, writer);
|
||||
if (r != Result.Success) {
|
||||
row.setAndGet(null);
|
||||
return r;
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.recordio;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.HybridRowHeader;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.HybridRowVersion;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.io.RowReader;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.layouts.SystemSchema;
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Java does not allow user-defined value types. The behavior of this class may differ
|
||||
// from the original:
|
||||
//ORIGINAL LINE: public struct RecordIOParser
|
||||
public final class RecordIOParser {
|
||||
private Record record = new Record();
|
||||
private Segment segment = new Segment();
|
||||
private State state = State.values()[0];
|
||||
|
||||
/**
|
||||
* True if a valid segment has been parsed.
|
||||
*/
|
||||
public boolean getHaveSegment() {
|
||||
return this.state.getValue() >= State.NeedHeader.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* If a valid segment has been parsed then current active segment, otherwise undefined.
|
||||
*/
|
||||
public Segment getSegment() {
|
||||
checkArgument(this.getHaveSegment());
|
||||
return this.segment.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes one buffers worth of data possibly advancing the parser state.
|
||||
*
|
||||
* @param buffer The buffer to consume.
|
||||
* @param type Indicates the type of Hybrid Row produced in <paramref name="record" />.
|
||||
* @param record If non-empty, then the body of the next record in the sequence.
|
||||
* @param need The smallest number of bytes needed to advanced the parser state further. It is
|
||||
* recommended that Process not be called again until at least this number of bytes are available.
|
||||
* @param consumed The number of bytes consumed from the input buffer. This number may be less
|
||||
* than the total buffer size if the parser moved to a new state.
|
||||
* @return {@link azure.data.cosmos.serialization.hybridrow.Result.Success} if no error
|
||||
* has occurred, otherwise a valid
|
||||
* {@link azure.data.cosmos.serialization.hybridrow.Result} of the last error encountered
|
||||
* during parsing.
|
||||
* <p>
|
||||
* >
|
||||
*/
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public Result Process(Memory<byte> buffer, out ProductionType type, out Memory<byte> record, out
|
||||
// int need, out int consumed)
|
||||
public Result Process(Memory<Byte> buffer, Out<ProductionType> type,
|
||||
Out<Memory<Byte>> record, Out<Integer> need,
|
||||
Out<Integer> consumed) {
|
||||
Result r = Result.Failure;
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: Memory<byte> b = buffer;
|
||||
Memory<Byte> b = buffer;
|
||||
type.setAndGet(ProductionType.None);
|
||||
record.setAndGet(null);
|
||||
switch (this.state) {
|
||||
case Start:
|
||||
this.state = State.NeedSegmentLength;
|
||||
// TODO: C# TO JAVA CONVERTER: There is no 'goto' in Java:
|
||||
case NeedSegmentLength: {
|
||||
int minimalSegmentRowSize = HybridRowHeader.SIZE + RecordIOFormatter.SegmentLayout.getSize();
|
||||
if (b.Length < minimalSegmentRowSize) {
|
||||
need.setAndGet(minimalSegmentRowSize);
|
||||
consumed.setAndGet(buffer.Length - b.Length);
|
||||
return Result.InsufficientBuffer;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: Span<byte> span = b.Span.Slice(0, minimalSegmentRowSize);
|
||||
Span<Byte> span = b.Span.Slice(0, minimalSegmentRowSize);
|
||||
RowBuffer row = new RowBuffer(span, HybridRowVersion.V1, SystemSchema.LayoutResolver);
|
||||
Reference<RowBuffer> tempReference_row =
|
||||
new Reference<RowBuffer>(row);
|
||||
RowReader reader = new RowReader(tempReference_row);
|
||||
row = tempReference_row.get();
|
||||
Reference<RowReader> tempReference_reader =
|
||||
new Reference<RowReader>(reader);
|
||||
Out<Segment> tempOut_segment =
|
||||
new Out<Segment>();
|
||||
r = SegmentSerializer.Read(tempReference_reader, tempOut_segment);
|
||||
this.segment = tempOut_segment.get();
|
||||
reader = tempReference_reader.get();
|
||||
if (r != Result.Success) {
|
||||
break;
|
||||
}
|
||||
|
||||
this.state = State.NeedSegment;
|
||||
// TODO: C# TO JAVA CONVERTER: There is no 'goto' in Java:
|
||||
goto case State.NeedSegment
|
||||
}
|
||||
|
||||
case NeedSegment: {
|
||||
if (b.Length < this.segment.Length) {
|
||||
need.setAndGet(this.segment.Length);
|
||||
consumed.setAndGet(buffer.Length - b.Length);
|
||||
return Result.InsufficientBuffer;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: Span<byte> span = b.Span.Slice(0, this.segment.Length);
|
||||
Span<Byte> span = b.Span.Slice(0, this.segment.Length);
|
||||
RowBuffer row = new RowBuffer(span, HybridRowVersion.V1, SystemSchema.LayoutResolver);
|
||||
Reference<RowBuffer> tempReference_row2 =
|
||||
new Reference<RowBuffer>(row);
|
||||
RowReader reader = new RowReader(tempReference_row2);
|
||||
row = tempReference_row2.get();
|
||||
Reference<RowReader> tempReference_reader2 =
|
||||
new Reference<RowReader>(reader);
|
||||
Out<Segment> tempOut_segment2
|
||||
= new Out<Segment>();
|
||||
r = SegmentSerializer.Read(tempReference_reader2, tempOut_segment2);
|
||||
this.segment = tempOut_segment2.get();
|
||||
reader = tempReference_reader2.get();
|
||||
if (r != Result.Success) {
|
||||
break;
|
||||
}
|
||||
|
||||
record.setAndGet(b.Slice(0, span.Length));
|
||||
b = b.Slice(span.Length);
|
||||
need.setAndGet(0);
|
||||
this.state = State.NeedHeader;
|
||||
consumed.setAndGet(buffer.Length - b.Length);
|
||||
type.setAndGet(ProductionType.Segment);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
case NeedHeader: {
|
||||
if (b.Length < HybridRowHeader.SIZE) {
|
||||
need.setAndGet(HybridRowHeader.SIZE);
|
||||
consumed.setAndGet(buffer.Length - b.Length);
|
||||
return Result.InsufficientBuffer;
|
||||
}
|
||||
|
||||
HybridRowHeader header;
|
||||
// TODO: C# TO JAVA CONVERTER: The following method call contained an unresolved 'out' keyword -
|
||||
// these cannot be converted using the 'Out' helper class unless the method is within the code
|
||||
// being modified:
|
||||
MemoryMarshal.TryRead(b.Span, out header);
|
||||
if (header.Version != HybridRowVersion.V1) {
|
||||
r = Result.InvalidRow;
|
||||
break;
|
||||
}
|
||||
|
||||
if (SchemaId.opEquals(header.SchemaId,
|
||||
SystemSchema.SegmentSchemaId)) {
|
||||
// TODO: C# TO JAVA CONVERTER: There is no 'goto' in Java:
|
||||
goto case State.NeedSegment
|
||||
}
|
||||
|
||||
if (SchemaId.opEquals(header.SchemaId,
|
||||
SystemSchema.RecordSchemaId)) {
|
||||
// TODO: C# TO JAVA CONVERTER: There is no 'goto' in Java:
|
||||
goto case State.NeedRecord
|
||||
}
|
||||
|
||||
r = Result.InvalidRow;
|
||||
break;
|
||||
}
|
||||
|
||||
case NeedRecord: {
|
||||
int minimalRecordRowSize = HybridRowHeader.SIZE + RecordIOFormatter.RecordLayout.getSize();
|
||||
if (b.Length < minimalRecordRowSize) {
|
||||
need.setAndGet(minimalRecordRowSize);
|
||||
consumed.setAndGet(buffer.Length - b.Length);
|
||||
return Result.InsufficientBuffer;
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: Span<byte> span = b.Span.Slice(0, minimalRecordRowSize);
|
||||
Span<Byte> span = b.Span.Slice(0, minimalRecordRowSize);
|
||||
RowBuffer row = new RowBuffer(span, HybridRowVersion.V1, SystemSchema.LayoutResolver);
|
||||
Reference<RowBuffer> tempReference_row3 =
|
||||
new Reference<RowBuffer>(row);
|
||||
RowReader reader = new RowReader(tempReference_row3);
|
||||
row = tempReference_row3.get();
|
||||
Reference<RowReader> tempReference_reader3 = new Reference<RowReader>(reader);
|
||||
Out<Record> tempOut_record = new Out<Record>();
|
||||
r = RecordSerializer.Read(tempReference_reader3, tempOut_record);
|
||||
this.record = tempOut_record.get();
|
||||
reader = tempReference_reader3.get();
|
||||
if (r != Result.Success) {
|
||||
break;
|
||||
}
|
||||
|
||||
b = b.Slice(span.Length);
|
||||
this.state = State.NeedRow;
|
||||
// TODO: C# TO JAVA CONVERTER: There is no 'goto' in Java:
|
||||
goto case State.NeedRow
|
||||
}
|
||||
|
||||
case NeedRow: {
|
||||
if (b.Length < this.record.Length) {
|
||||
need.setAndGet(this.record.Length);
|
||||
consumed.setAndGet(buffer.Length - b.Length);
|
||||
return Result.InsufficientBuffer;
|
||||
}
|
||||
|
||||
record.setAndGet(b.Slice(0, this.record.Length));
|
||||
|
||||
// Validate that the record has not been corrupted.
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: uint crc32 = Crc32.Update(0, record.Span);
|
||||
int crc32 = Crc32.Update(0, record.get().Span);
|
||||
if (crc32 != this.record.Crc32) {
|
||||
r = Result.InvalidRow;
|
||||
break;
|
||||
}
|
||||
|
||||
b = b.Slice(this.record.Length);
|
||||
need.setAndGet(0);
|
||||
this.state = State.NeedHeader;
|
||||
consumed.setAndGet(buffer.Length - b.Length);
|
||||
type.setAndGet(ProductionType.Record);
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
|
||||
this.state = State.Error;
|
||||
need.setAndGet(0);
|
||||
consumed.setAndGet(buffer.Length - b.Length);
|
||||
return r;
|
||||
}
|
||||
|
||||
public RecordIOParser clone() {
|
||||
RecordIOParser varCopy = new RecordIOParser();
|
||||
|
||||
varCopy.state = this.state;
|
||||
varCopy.segment = this.segment.clone();
|
||||
varCopy.record = this.record.clone();
|
||||
|
||||
return varCopy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the type of Hybrid Rows produced by the parser.
|
||||
*/
|
||||
public enum ProductionType {
|
||||
/**
|
||||
* No hybrid row was produced. The parser needs more data.
|
||||
*/
|
||||
None(0),
|
||||
|
||||
/**
|
||||
* A new segment row was produced.
|
||||
*/
|
||||
Segment(1),
|
||||
|
||||
/**
|
||||
* A record in the current segment was produced.
|
||||
*/
|
||||
Record(2);
|
||||
|
||||
public static final int SIZE = java.lang.Integer.SIZE;
|
||||
private static java.util.HashMap<Integer, ProductionType> mappings;
|
||||
private int intValue;
|
||||
|
||||
ProductionType(int value) {
|
||||
intValue = value;
|
||||
getMappings().put(value, this);
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return intValue;
|
||||
}
|
||||
|
||||
public static ProductionType forValue(int value) {
|
||||
return getMappings().get(value);
|
||||
}
|
||||
|
||||
private static java.util.HashMap<Integer, ProductionType> getMappings() {
|
||||
if (mappings == null) {
|
||||
synchronized (ProductionType.class) {
|
||||
if (mappings == null) {
|
||||
mappings = new java.util.HashMap<Integer, ProductionType>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return mappings;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The states for the internal state machine.
|
||||
* Note: numerical ordering of these states matters.
|
||||
*/
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: private enum State : byte
|
||||
private enum State {
|
||||
Start((byte)0), // Start: no buffers have yet been provided to the parser.
|
||||
Error(((byte)0) + 1), // Unrecoverable parse error encountered.
|
||||
NeedSegmentLength(((byte)0) + 2), // Parsing segment header length
|
||||
NeedSegment(((byte)0) + 3), // Parsing segment header
|
||||
NeedHeader(((byte)0) + 4), // Parsing HybridRow header
|
||||
NeedRecord(((byte)0) + 5), // Parsing record header
|
||||
NeedRow(((byte)0) + 6); // Parsing row body
|
||||
|
||||
public static final int SIZE = java.lang.Byte.SIZE;
|
||||
private static java.util.HashMap<Byte, State> mappings;
|
||||
private byte byteValue;
|
||||
|
||||
State(byte value) {
|
||||
byteValue = value;
|
||||
getMappings().put(value, this);
|
||||
}
|
||||
|
||||
public byte getValue() {
|
||||
return byteValue;
|
||||
}
|
||||
|
||||
public static State forValue(byte value) {
|
||||
return getMappings().get(value);
|
||||
}
|
||||
|
||||
private static java.util.HashMap<Byte, State> getMappings() {
|
||||
if (mappings == null) {
|
||||
synchronized (State.class) {
|
||||
if (mappings == null) {
|
||||
mappings = new java.util.HashMap<Byte, State>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return mappings;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,368 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.recordio;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.MemorySpanResizer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public final class RecordIOStream {
|
||||
/**
|
||||
* A function that produces RecordIO record bodies.
|
||||
* <p>
|
||||
* Record bodies are returned as memory blocks. It is expected that each block is a
|
||||
* HybridRow, but any binary data is allowed.
|
||||
*
|
||||
* @param index The 0-based index of the record within the segment to be produced.
|
||||
* @return A tuple with: Success if the body was produced without error, the error code otherwise.
|
||||
* And, the byte sequence of the record body's row buffer.
|
||||
*/
|
||||
public delegate ValueTask
|
||||
|
||||
ProduceFuncAsync(long index);<(Result,ReadOnlyMemory<Byte>)>
|
||||
|
||||
/**
|
||||
* Reads an entire RecordIO stream.
|
||||
*
|
||||
* @param stm The stream to read from.
|
||||
* @param visitRecord A (required) delegate that is called once for each record.
|
||||
* <p>
|
||||
* <paramref name="visitRecord" /> is passed a {@link Memory{T}} of the byte sequence
|
||||
* of the
|
||||
* record body's row buffer.
|
||||
* </p>
|
||||
* <p>If <paramref name="visitRecord" /> returns an error then the sequence is aborted.</p>
|
||||
* @param visitSegment An (optional) delegate that is called once for each segment header.
|
||||
* <p>
|
||||
* If <paramref name="visitSegment" /> is not provided then segment headers are parsed but
|
||||
* skipped
|
||||
* over.
|
||||
* </p>
|
||||
* <p>
|
||||
* <paramref name="visitSegment" /> is passed a {@link Memory{T}} of the byte sequence of
|
||||
* the segment header's row buffer.
|
||||
* </p>
|
||||
* <p>If <paramref name="visitSegment" /> returns an error then the sequence is aborted.</p>
|
||||
* @param resizer Optional memory resizer.
|
||||
* @return Success if the stream is parsed without error, the error code otherwise.
|
||||
*/
|
||||
|
||||
public static Task<Result> ReadRecordIOAsync(Stream stm, Func<Memory<Byte>, Result> visitRecord,
|
||||
Func<Memory<Byte>, Result> visitSegment) {
|
||||
return ReadRecordIOAsync(stm, visitRecord, visitSegment, null);
|
||||
}
|
||||
|
||||
public static Task<Result> ReadRecordIOAsync(Stream stm, Func<Memory<Byte>, Result> visitRecord) {
|
||||
return ReadRecordIOAsync(stm, visitRecord, null, null);
|
||||
}
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no equivalent in Java to the 'async' keyword:
|
||||
//ORIGINAL LINE: public static async Task<Result> ReadRecordIOAsync(this Stream stm, Func<Memory<byte>, Result>
|
||||
// visitRecord, Func<Memory<byte>, Result> visitSegment = default, MemorySpanResizer<byte> resizer = default)
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
public static Task<Result> ReadRecordIOAsync(InputStream stm,
|
||||
tangible.Func1Param<Memory<Byte>, Result> visitRecord,
|
||||
tangible.Func1Param<Memory<Byte>, Result> visitSegment,
|
||||
MemorySpanResizer<Byte> resizer) {
|
||||
checkArgument(stm != null);
|
||||
checkArgument(visitRecord != null);
|
||||
|
||||
// Create a reusable, resizable buffer if the caller didn't provide one.
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: resizer = resizer != null ? resizer : new MemorySpanResizer<byte>();
|
||||
resizer = resizer != null ? resizer : new MemorySpanResizer<Byte>();
|
||||
|
||||
RecordIOParser parser = null;
|
||||
int need = 0;
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: Memory<byte> active = resizer.Memory;
|
||||
Memory<Byte> active = resizer.getMemory();
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: Memory<byte> avail = default;
|
||||
Memory<Byte> avail = null;
|
||||
while (true) {
|
||||
checkState(avail.Length < active.Length);
|
||||
checkState(active.Length > 0);
|
||||
checkState(active.Length >= need);
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no equivalent to 'await' in Java:
|
||||
int read = await stm.ReadAsync(active.Slice(avail.Length));
|
||||
if (read == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
avail = active.Slice(0, avail.Length + read);
|
||||
|
||||
// If there isn't enough data to move the parser forward then just read again.
|
||||
if (avail.Length < need) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Process the available data until no more forward progress is possible.
|
||||
while (avail.Length > 0) {
|
||||
// Loop around processing available data until we don't have anymore
|
||||
RecordIOParser.ProductionType prodType;
|
||||
Out<RecordIOParser.ProductionType> tempOut_prodType = new Out<RecordIOParser.ProductionType>();
|
||||
Memory<Byte> record;
|
||||
Out<Memory<Byte>> tempOut_record = new Out<Memory<Byte>>();
|
||||
Out<Integer> tempOut_need = new Out<Integer>();
|
||||
int consumed;
|
||||
Out<Integer> tempOut_consumed = new Out<Integer>();
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: Result r = parser.Process(avail, out RecordIOParser.ProductionType prodType, out
|
||||
// Memory<byte> record, out need, out int consumed);
|
||||
Result r = parser.Process(avail, tempOut_prodType, tempOut_record, tempOut_need, tempOut_consumed);
|
||||
consumed = tempOut_consumed.get();
|
||||
need = tempOut_need.get();
|
||||
record = tempOut_record.get();
|
||||
prodType = tempOut_prodType.get();
|
||||
|
||||
if ((r != Result.Success) && (r != Result.InsufficientBuffer)) {
|
||||
return r;
|
||||
}
|
||||
|
||||
active = active.Slice(consumed);
|
||||
avail = avail.Slice(consumed);
|
||||
if (avail.IsEmpty) {
|
||||
active = resizer.getMemory();
|
||||
}
|
||||
|
||||
// If there wasn't enough data to move the parser forward then get more data.
|
||||
if (r == Result.InsufficientBuffer) {
|
||||
if (need > active.Length) {
|
||||
resizer.Resize(need, avail.Span);
|
||||
active = resizer.getMemory();
|
||||
avail = resizer.getMemory().Slice(0, avail.Length);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Validate the Segment
|
||||
if (prodType == RecordIOParser.ProductionType.Segment) {
|
||||
checkState(!record.IsEmpty);
|
||||
r = visitSegment == null ? null : visitSegment.invoke(record) != null ?
|
||||
visitSegment.invoke(record) : Result.Success;
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
// Consume the record.
|
||||
if (prodType == RecordIOParser.ProductionType.Record) {
|
||||
checkState(!record.IsEmpty);
|
||||
|
||||
r = visitRecord.invoke(record);
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we processed all of the available data.
|
||||
checkState(avail.Length == 0);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a RecordIO segment into a stream.
|
||||
*
|
||||
* @param stm The stream to write to.
|
||||
* @param segment The segment header to write.
|
||||
* @param produce A function to produces the record bodies for the segment.
|
||||
* <p>
|
||||
* The <paramref name="produce" /> function is called until either an error is encountered or it
|
||||
* produces an empty body. An empty body terminates the segment.
|
||||
* </p>
|
||||
* <p>If <paramref name="produce" /> returns an error then the sequence is aborted.</p>
|
||||
* @param resizer Optional memory resizer for RecordIO metadata row buffers.
|
||||
* <p>
|
||||
* <em>Note:</em> This should <em>NOT</em> be the same resizer used to process any rows as both
|
||||
* blocks of memory are used concurrently.
|
||||
* </p>
|
||||
* @return Success if the stream is written without error, the error code otherwise.
|
||||
*/
|
||||
|
||||
public static Task<Result> WriteRecordIOAsync(Stream stm, Segment segment, ProduceFunc produce) {
|
||||
return WriteRecordIOAsync(stm, segment, produce, null);
|
||||
}
|
||||
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//ORIGINAL LINE: public static Task<Result> WriteRecordIOAsync(this Stream stm, Segment segment, ProduceFunc
|
||||
// produce, MemorySpanResizer<byte> resizer = default)
|
||||
// TODO: C# TO JAVA CONVERTER: C# to Java Converter cannot determine whether this System.IO.Stream is input or
|
||||
// output:
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
public static Task<Result> WriteRecordIOAsync(Stream stm, Segment segment, ProduceFunc produce,
|
||||
MemorySpanResizer<Byte> resizer) {
|
||||
return RecordIOStream.WriteRecordIOAsync(stm,
|
||||
segment.clone(), index ->
|
||||
{
|
||||
ReadOnlyMemory<Byte> buffer;
|
||||
Out<ReadOnlyMemory<Byte>> tempOut_buffer = new Out<ReadOnlyMemory<Byte>>();
|
||||
buffer = tempOut_buffer.get();
|
||||
return new ValueTask<(Result, ReadOnlyMemory < Byte >) > ((r,buffer))
|
||||
}, resizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a RecordIO segment into a stream.
|
||||
*
|
||||
* @param stm The stream to write to.
|
||||
* @param segment The segment header to write.
|
||||
* @param produce A function to produces the record bodies for the segment.
|
||||
* <p>
|
||||
* The <paramref name="produce" /> function is called until either an error is encountered or it
|
||||
* produces an empty body. An empty body terminates the segment.
|
||||
* </p>
|
||||
* <p>If <paramref name="produce" /> returns an error then the sequence is aborted.</p>
|
||||
* @param resizer Optional memory resizer for RecordIO metadata row buffers.
|
||||
* <p>
|
||||
* <em>Note:</em> This should <em>NOT</em> be the same resizer used to process any rows as both
|
||||
* blocks of memory are used concurrently.
|
||||
* </p>
|
||||
* @return Success if the stream is written without error, the error code otherwise.
|
||||
*/
|
||||
|
||||
public static Task<Result> WriteRecordIOAsync(Stream stm, Segment segment, ProduceFuncAsync produce) {
|
||||
return WriteRecordIOAsync(stm, segment, produce, null);
|
||||
}
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no equivalent in Java to the 'async' keyword:
|
||||
//ORIGINAL LINE: public static async Task<Result> WriteRecordIOAsync(this Stream stm, Segment segment,
|
||||
// ProduceFuncAsync produce, MemorySpanResizer<byte> resizer = default)
|
||||
//C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
public static Task<Result> WriteRecordIOAsync(OutputStream stm, Segment segment, ProduceFuncAsync produce,
|
||||
MemorySpanResizer<Byte> resizer) {
|
||||
// Create a reusable, resizable buffer if the caller didn't provide one.
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: resizer = resizer != null ? resizer : new MemorySpanResizer<byte>();
|
||||
resizer = resizer != null ? resizer : new MemorySpanResizer<Byte>();
|
||||
|
||||
// Write a RecordIO stream.
|
||||
Memory<Byte> metadata;
|
||||
Out<Memory<Byte>> tempOut_metadata = new Out<Memory<Byte>>();
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: Result r = RecordIOStream.FormatSegment(segment, resizer, out Memory<byte> metadata);
|
||||
Result r = RecordIOStream.FormatSegment(segment.clone(), resizer, tempOut_metadata);
|
||||
metadata = tempOut_metadata.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no equivalent to 'await' in Java:
|
||||
await stm.WriteAsync(metadata);
|
||||
|
||||
long index = 0;
|
||||
while (true) {
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: ReadOnlyMemory<byte> body;
|
||||
ReadOnlyMemory<Byte> body;
|
||||
// TODO: C# TO JAVA CONVERTER: Java has no equivalent to the C# deconstruction assignments:
|
||||
(r, body) =await produce (index++);
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (body.IsEmpty) {
|
||||
break;
|
||||
}
|
||||
|
||||
Out<Memory<Byte>> tempOut_metadata2 = new Out<Memory<Byte>>();
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: r = RecordIOStream.FormatRow(body, resizer, out metadata);
|
||||
r = RecordIOStream.FormatRow(body, resizer, tempOut_metadata2);
|
||||
metadata = tempOut_metadata2.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
// Metadata and Body memory blocks should not overlap since they are both in
|
||||
// play at the same time. If they do this usually means that the same resizer
|
||||
// was incorrectly used for both. Check the resizer parameter passed to
|
||||
// WriteRecordIOAsync for metadata.
|
||||
checkState(!metadata.Span.Overlaps(body.Span));
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no equivalent to 'await' in Java:
|
||||
await stm.WriteAsync(metadata);
|
||||
// TODO: C# TO JAVA CONVERTER: There is no equivalent to 'await' in Java:
|
||||
await stm.WriteAsync(body);
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute and format a record header for the given record body.
|
||||
*
|
||||
* @param body The body whose record header should be formatted.
|
||||
* @param resizer The resizer to use in allocating a buffer for the record header.
|
||||
* @param block The byte sequence of the written row buffer.
|
||||
* @return Success if the write completes without error, the error code otherwise.
|
||||
*/
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: private static Result FormatRow(ReadOnlyMemory<byte> body, MemorySpanResizer<byte> resizer, out Memory<byte> block)
|
||||
private static Result FormatRow(ReadOnlyMemory<Byte> body, MemorySpanResizer<Byte> resizer, Out<Memory<Byte>> block) {
|
||||
RowBuffer row;
|
||||
Out<RowBuffer> tempOut_row = new Out<RowBuffer>();
|
||||
Result r = RecordIOFormatter.FormatRecord(body, tempOut_row, resizer);
|
||||
row = tempOut_row.get();
|
||||
if (r != Result.Success) {
|
||||
block.setAndGet(null);
|
||||
return r;
|
||||
}
|
||||
|
||||
block.setAndGet(resizer.getMemory().Slice(0, row.Length));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a segment.
|
||||
*
|
||||
* @param segment The segment to format.
|
||||
* @param resizer The resizer to use in allocating a buffer for the segment.
|
||||
* @param block The byte sequence of the written row buffer.
|
||||
* @return Success if the write completes without error, the error code otherwise.
|
||||
*/
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: private static Result FormatSegment(Segment segment, MemorySpanResizer<byte> resizer, out
|
||||
// Memory<byte> block)
|
||||
private static Result FormatSegment(Segment segment, MemorySpanResizer<Byte> resizer,
|
||||
Out<Memory<Byte>> block) {
|
||||
RowBuffer row;
|
||||
Out<RowBuffer> tempOut_row =
|
||||
new Out<RowBuffer>();
|
||||
Result r = RecordIOFormatter.FormatSegment(segment.clone(), tempOut_row, resizer);
|
||||
row = tempOut_row.get();
|
||||
if (r != Result.Success) {
|
||||
block.setAndGet(null);
|
||||
return r;
|
||||
}
|
||||
|
||||
block.setAndGet(resizer.getMemory().Slice(0, row.Length));
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that produces RecordIO record bodies.
|
||||
* <p>
|
||||
* Record bodies are returned as memory blocks. It is expected that each block is a
|
||||
* HybridRow, but any binary data is allowed.
|
||||
*
|
||||
* @param index The 0-based index of the record within the segment to be produced.
|
||||
* @param buffer The byte sequence of the record body's row buffer.
|
||||
* @return Success if the body was produced without error, the error code otherwise.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ProduceFunc {
|
||||
Result invoke(long index, Out<ReadOnlyMemory<Byte>> buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.recordio;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
|
||||
public final class RecordSerializer {
|
||||
public static Result Read(Reference<RowReader> reader, Out<Record> obj) {
|
||||
obj.setAndGet(null);
|
||||
while (reader.get().Read()) {
|
||||
Result r;
|
||||
|
||||
// TODO: use Path tokens here.
|
||||
switch (reader.get().getPath().toString()) {
|
||||
case "length":
|
||||
Out<Integer> tempOut_Length = new Out<Integer>();
|
||||
r = reader.get().ReadInt32(tempOut_Length);
|
||||
obj.get().argValue.Length = tempOut_Length.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
break;
|
||||
case "crc32":
|
||||
Out<Integer> tempOut_Crc32 = new Out<Integer>();
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: r = reader.ReadUInt32(out obj.Crc32);
|
||||
r = reader.get().ReadUInt32(tempOut_Crc32);
|
||||
obj.get().argValue.Crc32 = tempOut_Crc32.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public static Result Write(Reference<RowWriter> writer, TypeArgument typeArg, Record obj) {
|
||||
Result r;
|
||||
r = writer.get().WriteInt32("length", obj.Length);
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
r = writer.get().WriteUInt32("crc32", obj.Crc32);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.recordio;
|
||||
|
||||
// TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java:
|
||||
///#pragma warning disable CA1051 // Do not declare visible instance fields
|
||||
|
||||
|
||||
//C# TO JAVA CONVERTER WARNING: Java does not allow user-defined value types. The behavior of this class may differ
|
||||
// from the original:
|
||||
//ORIGINAL LINE: public struct Segment
|
||||
public final class Segment {
|
||||
public String Comment;
|
||||
public int Length;
|
||||
public String SDL;
|
||||
|
||||
public Segment() {
|
||||
}
|
||||
|
||||
public Segment(String comment, String sdl) {
|
||||
this.Length = 0;
|
||||
this.Comment = comment;
|
||||
this.SDL = sdl;
|
||||
}
|
||||
|
||||
public Segment clone() {
|
||||
Segment varCopy = new Segment();
|
||||
|
||||
varCopy.Length = this.Length;
|
||||
varCopy.Comment = this.Comment;
|
||||
varCopy.SDL = this.SDL;
|
||||
|
||||
return varCopy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.recordio;
|
||||
|
||||
import com.azure.data.cosmos.core.Out;
|
||||
import com.azure.data.cosmos.core.Reference;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.HybridRowVersion;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.Result;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
|
||||
import com.azure.data.cosmos.serialization.hybridrow.io.RowReader;
|
||||
|
||||
public final class SegmentSerializer {
|
||||
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
|
||||
//ORIGINAL LINE: public static Result Read(Span<byte> span, LayoutResolver resolver, out Segment obj)
|
||||
public static Result Read(Span<Byte> span, LayoutResolver resolver, Out<Segment> obj) {
|
||||
RowBuffer row = new RowBuffer(span, HybridRowVersion.V1, resolver);
|
||||
Reference<RowBuffer> tempReference_row =
|
||||
new Reference<RowBuffer>(row);
|
||||
RowReader reader = new RowReader(tempReference_row);
|
||||
row = tempReference_row.get();
|
||||
Reference<RowReader> tempReference_reader =
|
||||
new Reference<RowReader>(reader);
|
||||
Result tempVar = SegmentSerializer.Read(tempReference_reader, obj.clone());
|
||||
reader = tempReference_reader.get();
|
||||
return tempVar;
|
||||
}
|
||||
|
||||
public static Result Read(Reference<RowReader> reader, Out<Segment> obj) {
|
||||
obj.setAndGet(null);
|
||||
while (reader.get().Read()) {
|
||||
Result r;
|
||||
|
||||
// TODO: use Path tokens here.
|
||||
switch (reader.get().getPath().toString()) {
|
||||
case "length":
|
||||
Out<Integer> tempOut_Length = new Out<Integer>();
|
||||
r = reader.get().ReadInt32(tempOut_Length);
|
||||
obj.get().argValue.Length = tempOut_Length.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
// If the RowBuffer isn't big enough to contain the rest of the header, then just
|
||||
// return the length.
|
||||
if (reader.get().getLength() < obj.get().Length) {
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
break;
|
||||
case "comment":
|
||||
Out<String> tempOut_Comment = new Out<String>();
|
||||
r = reader.get().ReadString(tempOut_Comment);
|
||||
obj.get().argValue.Comment = tempOut_Comment.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
break;
|
||||
case "sdl":
|
||||
Out<String> tempOut_SDL = new Out<String>();
|
||||
r = reader.get().ReadString(tempOut_SDL);
|
||||
obj.get().argValue.SDL = tempOut_SDL.get();
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public static Result Write(Reference<RowWriter> writer, TypeArgument typeArg, Segment obj) {
|
||||
Result r;
|
||||
if (obj.Comment != null) {
|
||||
r = writer.get().WriteString("comment", obj.Comment);
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.SDL != null) {
|
||||
r = writer.get().WriteString("sdl", obj.SDL);
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
// Defer writing the length until all other fields of the segment header are written.
|
||||
// The length is then computed based on the current size of the underlying RowBuffer.
|
||||
// Because the length field is itself fixed, writing the length can never change the length.
|
||||
int length = writer.get().getLength();
|
||||
r = writer.get().WriteInt32("length", length);
|
||||
if (r != Result.Success) {
|
||||
return r;
|
||||
}
|
||||
|
||||
checkState(length == writer.get().getLength());
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
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.
|
||||
*/
|
||||
public class ArrayPropertyType extends ScopePropertyType {
|
||||
/**
|
||||
* (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 void setItems(PropertyType value) {
|
||||
Items = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public class MapPropertyType extends ScopePropertyType {
|
||||
/**
|
||||
* (Optional) type of the keys of the map, if a typed map, otherwise 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;
|
||||
/**
|
||||
* (Optional) type of the values of the map, if a typed map, otherwise 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 void setKeys(PropertyType value) {
|
||||
Keys = value;
|
||||
}
|
||||
|
||||
public final PropertyType getValues() {
|
||||
return Values;
|
||||
}
|
||||
|
||||
public final void setValues(PropertyType value) {
|
||||
Values = value;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user