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:
David Noble
2019-09-01 14:26:40 -07:00
parent ab82943fe0
commit 7ae43bf830
193 changed files with 3840 additions and 2117 deletions

263
java/pom.xml Normal file
View File

@@ -0,0 +1,263 @@
<!--
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the MIT License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.azure.data</groupId>
<artifactId>azure-cosmos-serialization</artifactId>
<version>2.9.5</version>
<packaging>jar</packaging>
<name>Microsoft Azure Cosmos Serialization API</name>
<description>This package contains Microsoft Azure Serialization API for Azure Cosmos DB</description>
<url>https://github.com/Azure/azure-sdk-for-java</url>
<distributionManagement>
<site>
<id>azure-java-build-docs</id>
<url>${site.url}/site/${project.artifactId}</url>
</site>
</distributionManagement>
<scm>
<url>https://github.com/Azure/azure-sdk-for-java</url>
</scm>
<properties>
<collectedArtifactsForReleaseLocation>${project.basedir}/target/collectedArtifactsForRelease
</collectedArtifactsForReleaseLocation>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<site.url/>
<test.groups>unit</test.groups>
<javadoc.opts/>
<fastutil.version>8.3.0</fastutil.version>
<guava.version>28.0-jre</guava.version>
<jackson.version>2.9.9</jackson.version>
<mockito.version>1.10.19</mockito.version>
<mongodb.version>3.11.0</mongodb.version>
<netty.version>4.1.39.Final</netty.version>
<protobuf.version>3.9.1</protobuf.version>
<slf4j.version>1.7.28</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>${protobuf.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil</artifactId>
<version>${fastutil.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>bson</artifactId>
<version>${mongodb.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
<profiles>
<profile>
<!-- unit test -->
<id>unit</id>
<properties>
<env>default</env>
<test.groups>unit</test.groups>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<groups>unit</groups>
<includes>
<include>%regex[.*]</include>
</includes>
<properties>
<property>
<name>surefire.testng.verbose</name>
<value>2</value>
</property>
</properties>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<includes>
<include>%regex[.*]</include>
</includes>
<properties>
<property>
<name>surefire.testng.verbose</name>
<value>2</value>
</property>
</properties>
<groups>${test.groups}</groups>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<quiet>true</quiet>
<verbose>false</verbose>
<additionalOptions>${javadoc.opts}</additionalOptions>
<sourceFileExcludes>
<sourceFileExclude>**/internal/**/*.java</sourceFileExclude>
<sourceFileExclude>**/*BridgeInternal.java</sourceFileExclude>
</sourceFileExcludes>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
<configuration>
<classpathContainers>
<classpathContainer>
org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8
</classpathContainer>
</classpathContainers>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase/>
<id>default-cli</id>
<configuration>
<target/>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<developers>
<developer>
<id>microsoft</id>
<name>Microsoft Corporation</name>
</developer>
</developers>
<modules/>
</project>

View File

@@ -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 {
}

View 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);
}
}
}

View 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();
}
}

View 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();
}
}

View 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());
}
}
}

View 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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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());
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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 {
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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++);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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>();
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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()));
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

Some files were not shown because too many files have changed in this diff Show More