diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/io/RowReader.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/io/RowReader.java index bb91f0b..83c849c 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/io/RowReader.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/io/RowReader.java @@ -14,7 +14,7 @@ import com.azure.data.cosmos.serialization.hybridrow.RowCursor; import com.azure.data.cosmos.serialization.hybridrow.RowCursors; import com.azure.data.cosmos.serialization.hybridrow.UnixDateTime; import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutSpanReadable; -import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutUtf8SpanReadable; +import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutUtf8Readable; import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutBinary; import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutBoolean; import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutColumn; @@ -1049,7 +1049,7 @@ public final class RowReader { LayoutColumn column = this.columns.get(this.columnIndex); LayoutType type = this.columns.get(this.columnIndex).type(); - if (!(type instanceof LayoutUtf8SpanReadable)) { + if (!(type instanceof LayoutUtf8Readable)) { value.set(null); return Result.TYPE_MISMATCH; } @@ -1059,10 +1059,10 @@ public final class RowReader { switch (storage) { case FIXED: - return type.typeAs().readFixed(this.row, this.cursor, column, value); + return type.typeAs().readFixed(this.row, this.cursor, column, value); case VARIABLE: - return type.typeAs().readVariable(this.row, this.cursor, column, value); + return type.typeAs().readVariable(this.row, this.cursor, column, value); default: assert false : lenientFormat("expected FIXED or VARIABLE column storage, not %s", storage); diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/io/RowWriter.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/io/RowWriter.java index c3a4fac..c2197a8 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/io/RowWriter.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/io/RowWriter.java @@ -24,7 +24,7 @@ import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutTypedMap; import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutTypes; import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutUDT; import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutUniqueScope; -import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutUtf8SpanWritable; +import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutUtf8Writable; import com.azure.data.cosmos.serialization.hybridrow.layouts.TypeArgument; import com.azure.data.cosmos.serialization.hybridrow.layouts.TypeArgumentList; import com.azure.data.cosmos.serialization.hybridrow.layouts.UpdateOptions; @@ -748,7 +748,7 @@ public final class RowWriter { * @param sparse The {@link RowBuffer} access method for . * @return Success if the write is successful, an error code otherwise. */ - private & LayoutUtf8SpanWritable> Result writePrimitive(UtfAnyString path, Utf8String value, TLayoutType type, AccessUtf8SpanMethod sparse) { + private & LayoutUtf8Writable> Result writePrimitive(UtfAnyString path, Utf8String value, TLayoutType type, AccessUtf8SpanMethod sparse) { Result result = Result.NOT_FOUND; if (this.cursor.scopeType() instanceof LayoutUDT) { result = this.writeSchematizedValue(path, value); diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8.java index 3cf5181..ec27780 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8.java @@ -14,7 +14,7 @@ import javax.annotation.Nonnull; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -public final class LayoutUtf8 extends LayoutTypePrimitive implements LayoutUtf8SpanWritable, LayoutUtf8SpanReadable { +public final class LayoutUtf8 extends LayoutTypePrimitive implements LayoutUtf8Readable, LayoutUtf8Writable { public LayoutUtf8() { super(LayoutCode.UTF_8, 0); diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8SpanReadable.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8Readable.java similarity index 93% rename from java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8SpanReadable.java rename to java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8Readable.java index 860b53e..9c44447 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8SpanReadable.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8Readable.java @@ -14,7 +14,7 @@ import javax.annotation.Nonnull; /** * An optional interface that indicates a {@link LayoutType{T}} can also read using a {@link Utf8String}. */ -public interface LayoutUtf8SpanReadable extends ILayoutType { +public interface LayoutUtf8Readable extends ILayoutType { @Nonnull Result readFixedSpan(RowBuffer buffer, RowCursor scope, LayoutColumn column, Out value); diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8SpanWritable.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8Writable.java similarity index 94% rename from java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8SpanWritable.java rename to java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8Writable.java index a527fad..09b2625 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8SpanWritable.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/LayoutUtf8Writable.java @@ -13,7 +13,7 @@ import javax.annotation.Nonnull; /** * An optional interface that indicates a {@link LayoutType{T}} can also write using a {@link Utf8String} */ -public interface LayoutUtf8SpanWritable extends ILayoutType { +public interface LayoutUtf8Writable extends ILayoutType { @Nonnull Result writeFixed(RowBuffer buffer, RowCursor scope, LayoutColumn column, Utf8String value); diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Namespace.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Namespace.java index a41520f..ff57ff7 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Namespace.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/Namespace.java @@ -19,7 +19,7 @@ public class Namespace { * Initializes a new instance of the {@link Namespace} class. */ public Namespace() { - this.setSchemas(new ArrayList()); + this.schemas(new ArrayList()); } /** @@ -37,28 +37,31 @@ public class Namespace { /** * The set of schemas that make up the {@link Namespace}. *

- * Namespaces may consist of zero or more table schemas along with zero or more UDT schemas. - * Table schemas can only reference UDT schemas defined in the same namespace. UDT schemas can - * contain nested UDTs whose schemas are defined within the same namespace. - * @return + * Namespaces may consist of zero or more table schemas along with zero or more UDT schemas. Table schemas can only + * reference UDT schemas defined in the same namespace. UDT schemas can contain nested UDTs whose schemas are + * defined within the same namespace. + * + * @return list of schemas in the current {@link Namespace}. */ public final List schemas() { return this.schemas; } - public final void setSchemas(ArrayList value) { + public final Namespace schemas(ArrayList value) { this.schemas = value != null ? value : new ArrayList(); + return this; } /** * The version of the HybridRow Schema Definition Language used to encode this namespace. */ - public final SchemaLanguageVersion getVersion() { + public final SchemaLanguageVersion version() { return this.version; } - public final void setVersion(SchemaLanguageVersion value) { + public final Namespace version(SchemaLanguageVersion value) { this.version = value; + return this; } /** diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaHash.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaHash.java index d98282e..0844ece 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaHash.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SchemaHash.java @@ -3,55 +3,78 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; +import com.azure.data.cosmos.serialization.hybridrow.internal.Murmur3Hash; + public final class SchemaHash { - /** Computes the logical hash for a logical schema. - @param ns The namespace within which is defined. - @param schema The logical schema to compute the hash of. - @param seed The seed to initialized the hash function. - @return The logical 128-bit hash as a two-tuple (low, high). + + public static class Code { + + private final long low; + private final long high; + + private Code(long low, long high) { + this.low = low; + this.high = high; + } + + public long high() { + return this.high; + } + + public long low() { + return this.low; + } + } + + /** + * Computes the logical hash for a logical schema. + * @param ns The namespace within which is defined. + * @param schema The logical schema to compute the hash of. + * @param seed The seed to initialized the hash function. + * @return The logical 128-bit hash as a two-tuple (low, high). */ - // TODO: C# TO JAVA CONVERTER: Methods returning tuples are not converted by C# to Java Converter: - // public static(ulong low, ulong high) ComputeHash(Namespace ns, Schema schema, (ulong low, ulong high) seed = - // default) - // { - // (ulong low, ulong high) hash = seed; - // hash = Murmur3Hash.Hash128(schema.SchemaId, hash); - // hash = Murmur3Hash.Hash128(schema.Type, hash); - // hash = SchemaHash.ComputeHash(ns, schema.Options, hash); - // if (schema.PartitionKeys != null) - // { - // foreach (PartitionKey p in schema.PartitionKeys) - // { - // hash = SchemaHash.ComputeHash(ns, p, hash); - // } - // } - // - // if (schema.PrimarySortKeys != null) - // { - // foreach (PrimarySortKey p in schema.PrimarySortKeys) - // { - // hash = SchemaHash.ComputeHash(ns, p, hash); - // } - // } - // - // if (schema.StaticKeys != null) - // { - // foreach (StaticKey p in schema.StaticKeys) - // { - // hash = SchemaHash.ComputeHash(ns, p, hash); - // } - // } - // - // if (schema.Properties != null) - // { - // foreach (Property p in schema.Properties) - // { - // hash = SchemaHash.ComputeHash(ns, p, hash); - // } - // } - // - // return hash; - // } + public static Code ComputeHash(Namespace ns, Schema schema, Code seed) + { + Code hash = seed; + + hash = Murmur3Hash.Hash128(schema.schemaId(), hash); + hash = Murmur3Hash.Hash128(schema.type(), hash); + hash = SchemaHash.ComputeHash(ns, schema.options(), hash); + + if (schema.partitionKeys() != null) + { + foreach (PartitionKey p in schema.PartitionKeys) + { + hash = SchemaHash.ComputeHash(ns, p, hash); + } + } + + if (schema.PrimarySortKeys != null) + { + foreach (PrimarySortKey p in schema.PrimarySortKeys) + { + hash = SchemaHash.ComputeHash(ns, p, hash); + } + } + + if (schema.StaticKeys != null) + { + foreach (StaticKey p in schema.StaticKeys) + { + hash = SchemaHash.ComputeHash(ns, p, hash); + } + } + + if (schema.Properties != null) + { + foreach (Property p in schema.Properties) + { + hash = SchemaHash.ComputeHash(ns, p, hash); + } + } + + return hash; + } // TODO: C# TO JAVA CONVERTER: Methods returning tuples are not converted by C# to Java Converter: // private static(ulong low, ulong high) ComputeHash(Namespace ns, SchemaOptions options, (ulong low, ulong high) diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SortDirection.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SortDirection.java index 24ab024..e58e25c 100644 --- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SortDirection.java +++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/SortDirection.java @@ -3,6 +3,9 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; + /** * Describes the sort order direction. */ @@ -10,15 +13,16 @@ public enum SortDirection { /** * Sorts from the lowest to the highest value. */ - Ascending(0), + ASCENDING(0), /** * Sorts from the highests to the lowest value. */ - Descending(1); + DESCENDING(1); - public static final int SIZE = java.lang.Integer.SIZE; - private static java.util.HashMap mappings; + public static final int BYTEST = Integer.BYTES; + + private static Int2ObjectMap mappings; private int value; SortDirection(int value) { @@ -30,15 +34,15 @@ public enum SortDirection { return this.value; } - public static SortDirection forValue(int value) { + public static SortDirection from(int value) { return mappings().get(value); } - private static java.util.HashMap mappings() { + private static Int2ObjectMap mappings() { if (mappings == null) { synchronized (SortDirection.class) { if (mappings == null) { - mappings = new java.util.HashMap<>(); + mappings = new Int2ObjectOpenHashMap<>(); } } } diff --git a/java/src/test/java/com/azure/data/cosmos/serialization/hybridrow/unit/SchemaUnitTests.java b/java/src/test/java/com/azure/data/cosmos/serialization/hybridrow/unit/SchemaUnitTests.java index e906618..7ca8a3d 100644 --- a/java/src/test/java/com/azure/data/cosmos/serialization/hybridrow/unit/SchemaUnitTests.java +++ b/java/src/test/java/com/azure/data/cosmos/serialization/hybridrow/unit/SchemaUnitTests.java @@ -688,8 +688,8 @@ class AnonymousType3 { pulic String Path pubblct[] expectedSchemas = new Object[] { AnonymousType("{'path': 'a'}", "{'path': 'b', 'direction': 'desc'}, " + - "{'path': 'c'}", new String[] { "a" }, new Object[] { AnonymousType2("b", SortDirection.Descending), - AnonymousType3("c", SortDirection.Ascending) }) }; + "{'path': 'c'}", new String[] { "a" }, new Object[] { AnonymousType2("b", SortDirection.DESCENDING), + AnonymousType3("c", SortDirection.ASCENDING) }) }; for(bjeic AnonymousType3(String _Path, SortDirection _Dir) { Path = _Path;