+ * This method mixes the bits of the underlying {@code int} value of the {@link SchemaId} by multiplying by the
+ * golden ratio and xor-shifting the result. It has slightly worse behavior than MurmurHash3. In open-addressing
+ * In open-addressing tables the average number of probes is slightly larger, but the computation of the value
+ * is faster.
+ *
+ * @return the hash code value for this {@link SchemaId}.
+ * @see HashCommon#mix(int)
+ * @see Koloboke
+ * @see MurmurHash
+ */
@Override
public int hashCode() {
return mix(this.value);
@@ -120,16 +132,16 @@ public final class SchemaId implements Comparable
@@ -12,15 +14,24 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
*/
public class ArrayPropertyType extends ScopePropertyType {
+ @JsonProperty
private PropertyType items;
/**
* (Optional) type of the elements of the array, if a typed array, otherwise null.
+ *
+ * @return type of the elements of the array or {@code null}, if the array is untyped.
*/
public final PropertyType items() {
return this.items;
}
+ /**
+ * Set the type of the elements of the array
+ *
+ * @param value type of the elements of the array or {@code null}, if the array is untyped.
+ * @return a reference to this {@link ArrayPropertyType}.
+ */
public final ArrayPropertyType items(PropertyType value) {
this.items = value;
return this;
diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PropertyType.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PropertyType.java
index 5fcdd91..2a9d842 100644
--- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PropertyType.java
+++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PropertyType.java
@@ -9,8 +9,6 @@ import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
-import java.util.PrimitiveIterator;
-
/**
* The base class for property types both primitive and complex.
*/
@@ -19,45 +17,43 @@ import java.util.PrimitiveIterator;
// Composite types
@Type(value = ArrayPropertyType.class, name = "array"),
@Type(value = MapPropertyType.class, name = "map"),
- @Type(value = ObjectPropertyType.class, name="object"),
- @Type(value = ScopePropertyType.class, name="scope"),
- @Type(value = SetPropertyType.class, name="set"),
- @Type(value = TaggedPropertyType.class, name="tagged"),
- @Type(value = TuplePropertyType.class, name="tuple"),
+ @Type(value = ObjectPropertyType.class, name = "object"),
+ @Type(value = SetPropertyType.class, name = "set"),
+ @Type(value = TaggedPropertyType.class, name = "tagged"),
+ @Type(value = TuplePropertyType.class, name = "tuple"),
+ @Type(value = UdtPropertyType.class, name = "schema"),
// Primitive types
- @Type(value = PrimitivePropertyType.class, name="null"),
- @Type(value = PrimitivePropertyType.class, name="bool"),
- @Type(value = PrimitivePropertyType.class, name="int8"),
- @Type(value = PrimitivePropertyType.class, name="int16"),
- @Type(value = PrimitivePropertyType.class, name="int32"),
- @Type(value = PrimitivePropertyType.class, name="int64"),
- @Type(value = PrimitivePropertyType.class, name="varint"),
- @Type(value = PrimitivePropertyType.class, name="uint8"),
- @Type(value = PrimitivePropertyType.class, name="uint16"),
- @Type(value = PrimitivePropertyType.class, name="uint32"),
- @Type(value = PrimitivePropertyType.class, name="uint64"),
- @Type(value = PrimitivePropertyType.class, name="varuint"),
- @Type(value = PrimitivePropertyType.class, name="float32"),
- @Type(value = PrimitivePropertyType.class, name="float64"),
- @Type(value = PrimitivePropertyType.class, name="float128"),
- @Type(value = PrimitivePropertyType.class, name="decimal"),
- @Type(value = PrimitivePropertyType.class, name="datetime"),
- @Type(value = PrimitivePropertyType.class, name="unixdatetime"),
- @Type(value = PrimitivePropertyType.class, name="binary"),
- @Type(value = PrimitivePropertyType.class, name="guid"),
- @Type(value = PrimitivePropertyType.class, name="utf8"),
- @Type(value = PrimitivePropertyType.class, name="any")
+ @Type(value = PrimitivePropertyType.class, name = "null"),
+ @Type(value = PrimitivePropertyType.class, name = "bool"),
+ @Type(value = PrimitivePropertyType.class, name = "int8"),
+ @Type(value = PrimitivePropertyType.class, name = "int16"),
+ @Type(value = PrimitivePropertyType.class, name = "int32"),
+ @Type(value = PrimitivePropertyType.class, name = "int64"),
+ @Type(value = PrimitivePropertyType.class, name = "varint"),
+ @Type(value = PrimitivePropertyType.class, name = "uint8"),
+ @Type(value = PrimitivePropertyType.class, name = "uint16"),
+ @Type(value = PrimitivePropertyType.class, name = "uint32"),
+ @Type(value = PrimitivePropertyType.class, name = "uint64"),
+ @Type(value = PrimitivePropertyType.class, name = "varuint"),
+ @Type(value = PrimitivePropertyType.class, name = "float32"),
+ @Type(value = PrimitivePropertyType.class, name = "float64"),
+ @Type(value = PrimitivePropertyType.class, name = "float128"),
+ @Type(value = PrimitivePropertyType.class, name = "decimal"),
+ @Type(value = PrimitivePropertyType.class, name = "datetime"),
+ @Type(value = PrimitivePropertyType.class, name = "unixdatetime"),
+ @Type(value = PrimitivePropertyType.class, name = "binary"),
+ @Type(value = PrimitivePropertyType.class, name = "guid"),
+ @Type(value = PrimitivePropertyType.class, name = "utf8"),
+ @Type(value = PrimitivePropertyType.class, name = "any")
})
public abstract class PropertyType {
- @JsonProperty(required = true)
- private TypeKind type;
-
@JsonProperty
private String apiType;
-
@JsonProperty(defaultValue = "true")
private boolean nullable;
+ @JsonProperty(required = true)
+ private TypeKind type;
protected PropertyType() {
this.nullable(true);
diff --git a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/UdtPropertyType.java b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/UdtPropertyType.java
index b20ba58..34e9bfc 100644
--- a/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/UdtPropertyType.java
+++ b/java/src/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/UdtPropertyType.java
@@ -18,7 +18,7 @@ public class UdtPropertyType extends ScopePropertyType {
private String name;
@JsonProperty(required = true)
- private SchemaId schemaId;
+ private SchemaId id;
/**
* The name of the UDT schema defining the structure of a nested row.
@@ -55,7 +55,7 @@ public class UdtPropertyType extends ScopePropertyType {
* @return the unique identifier of the UDT schema defining the structure of a nested row or {@code null}.
*/
public final SchemaId schemaId() {
- return this.schemaId;
+ return this.id;
}
/**
@@ -70,7 +70,7 @@ public class UdtPropertyType extends ScopePropertyType {
* @return a reference to this {@link UdtPropertyType}.
*/
public final UdtPropertyType schemaId(SchemaId value) {
- this.schemaId = value;
+ this.id = value;
return this;
}
}
diff --git a/java/src/test/java/com/azure/data/cosmos/serialization/hybridrow/layouts/SystemSchemaTest.java b/java/src/test/java/com/azure/data/cosmos/serialization/hybridrow/layouts/SystemSchemaTest.java
index f64cc91..e6a9565 100644
--- a/java/src/test/java/com/azure/data/cosmos/serialization/hybridrow/layouts/SystemSchemaTest.java
+++ b/java/src/test/java/com/azure/data/cosmos/serialization/hybridrow/layouts/SystemSchemaTest.java
@@ -13,10 +13,10 @@ import static org.testng.Assert.*;
@Test(groups = "unit")
public class SystemSchemaTest {
- private static final Path SCHEMA_FILE = Paths.get("test-data", "CustomerSchema.json");
+ private static final Path SCHEMA_FILE = Paths.get("test-data", "RootSegment.json");
@Test
- public void testLoadSchema() {
+ public void testLayoutResolver() {
final LayoutResolver layoutResolver = SystemSchema.layoutResolver();
diff --git a/java/src/test/java/com/azure/data/cosmos/serialization/hybridrow/schemas/NamespaceTest.java b/java/src/test/java/com/azure/data/cosmos/serialization/hybridrow/schemas/NamespaceTest.java
new file mode 100644
index 0000000..d83c4c7
--- /dev/null
+++ b/java/src/test/java/com/azure/data/cosmos/serialization/hybridrow/schemas/NamespaceTest.java
@@ -0,0 +1,84 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.data.cosmos.serialization.hybridrow.schemas;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Factory;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.UUID;
+
+import static com.google.common.base.Strings.lenientFormat;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.fail;
+
+public class NamespaceTest {
+
+ private static final String basedir = System.getProperty("project.basedir", System.getProperty("user.dir"));
+ private final Path schemaPath;
+ private Namespace namespace;
+
+ private NamespaceTest(Path schemaPath) {
+ this.schemaPath = schemaPath;
+ }
+
+ @BeforeClass(groups = "unit")
+ public void setUp() {
+
+ assertNull(this.namespace);
+
+ try (InputStream stream = Files.newInputStream(this.schemaPath)) {
+
+ this.namespace = Namespace.parse(stream).orElseThrow(() ->
+ new AssertionError(lenientFormat("failed to parse %s", this.schemaPath))
+ );
+
+ } catch (IOException error) {
+ fail(lenientFormat("unexpected %s", error));
+ }
+ }
+
+ @Test(groups = "unit")
+ public void testName() {
+ String name = UUID.randomUUID().toString();
+ this.namespace.name(name);
+ assertEquals(this.namespace.name(), name);
+ }
+
+ @Test(groups = "unit")
+ public void testSchemas() {
+ }
+
+ @Test(groups = "unit")
+ public void testTestParse() {
+ }
+
+ @Test(groups = "unit")
+ public void testTestSchemas() {
+ }
+
+ @Test(groups = "unit")
+ public void testTestVersion() {
+ }
+
+ @Test(groups = "unit")
+ public void testVersion() {
+ }
+
+ public static class Builder {
+ @Factory
+ public static Object[] create() {
+ return new Object[] {
+ new NamespaceTest(Paths.get(basedir, "test-data", "RootSegment.json"))
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/test-data/RootSegment.bin b/test-data/RootSegment.bin
new file mode 100644
index 0000000..0e9b9e8
Binary files /dev/null and b/test-data/RootSegment.bin differ
diff --git a/test-data/RootSegment.hybridrow b/test-data/RootSegment.hybridrow
new file mode 100644
index 0000000..6ce93f8
Binary files /dev/null and b/test-data/RootSegment.hybridrow differ
diff --git a/test-data/RootSegment.json b/test-data/RootSegment.json
new file mode 100644
index 0000000..df28b9b
--- /dev/null
+++ b/test-data/RootSegment.json
@@ -0,0 +1,609 @@
+{
+ "version": "v1",
+ "schemas": [{
+ "name": "RootSegment",
+ "id": -1,
+ "type": "schema",
+ "properties": [{
+ "path": "PropertyBag",
+ "type": {
+ "type": "schema",
+ "name": "RootSegmentPropertyBag",
+ "id": 7
+ }
+ },
+ {
+ "path": "SegmentInfos",
+ "type": {
+ "type": "array",
+ "items": {
+ "type": "schema",
+ "name": "SegmentInfo",
+ "id": 1,
+ "nullable": false
+ }
+ }
+ },
+ {
+ "path": "SnapshotInfos",
+ "type": {
+ "type": "array",
+ "items": {
+ "type": "schema",
+ "name": "SnapshotInfo",
+ "id": 5,
+ "nullable": false
+ }
+ }
+ }
+ ]
+ },
+ {
+ "name": "InvalidationManifest",
+ "id": -2,
+ "type": "schema",
+ "properties": [{
+ "path": "PropertyBag",
+ "type": {
+ "type": "schema",
+ "name": "InvalidationManifestPropertyBag",
+ "id": 9
+ }
+ },
+ {
+ "path": "StreamInfos",
+ "type": {
+ "type": "array",
+ "items": {
+ "type": "schema",
+ "name": "InvalidationStreamInfo",
+ "id": 10,
+ "nullable": false
+ }
+ }
+ }
+ ]
+ },
+ {
+ "name": "SegmentInfo",
+ "id": 1,
+ "type": "schema",
+ "properties": [{
+ "path": "LSID",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "PSID",
+ "type": {
+ "type": "schema",
+ "name": "FileId",
+ "id": 2
+ }
+ },
+ {
+ "path": "SegmentMetadata",
+ "type": {
+ "type": "schema",
+ "name": "SegmentMetadata",
+ "id": 4
+ }
+ },
+ {
+ "path": "ReferenceCount",
+ "type": {
+ "type": "uint8",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "ZeroUtilizationTimestamp",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "Control",
+ "type": {
+ "type": "uint8",
+ "storage": "fixed",
+ "nullable": false
+ }
+ }
+ ]
+ },
+ {
+ "name": "FileId",
+ "id": 2,
+ "type": "schema",
+ "properties": [{
+ "path": "StorageAccountIndex",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "FileType",
+ "type": {
+ "type": "int16",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "FileIndex",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "PartitionId",
+ "type": {
+ "type": "guid",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "PartitionKeyRangeRid",
+ "type": {
+ "type": "binary",
+ "storage": "fixed",
+ "length": 30,
+ "nullable": false
+ }
+ }
+ ]
+ },
+ {
+ "name": "SequenceVector",
+ "id": 3,
+ "type": "schema",
+ "properties": [{
+ "path": "GlobalSequenceNumber",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "LocalSequenceNumber",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ }
+ ]
+ },
+ {
+ "name": "SegmentMetadata",
+ "id": 4,
+ "type": "schema",
+ "properties": [{
+ "path": "InitialRecordCount",
+ "type": {
+ "type": "uint32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "TombstoneRecordCount",
+ "type": {
+ "type": "uint32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "InvalidatedRecordCount",
+ "type": {
+ "type": "uint32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "SegmentSize",
+ "type": {
+ "type": "uint32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "MinSequenceVector",
+ "type": {
+ "type": "schema",
+ "name": "SequenceVector",
+ "id": 3
+ }
+ },
+ {
+ "path": "MaxSequenceVector",
+ "type": {
+ "type": "schema",
+ "name": "SequenceVector",
+ "id": 3
+ }
+ },
+ {
+ "path": "InvalidationFileId",
+ "type": {
+ "type": "schema",
+ "name": "FileId",
+ "id": 2
+ }
+ },
+ {
+ "path": "InvalidationStats",
+ "type": {
+ "type": "schema",
+ "name": "InvalidationStats",
+ "id": 6
+ }
+ },
+ {
+ "path": "SchemaHash",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "ExpiredRecordCount",
+ "type": {
+ "type": "uint32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "MinRecordTimestamp",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "MaxRecordTimestamp",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "PartialSegment",
+ "type": {
+ "type": "bool",
+ "storage": "fixed",
+ "nullable": false
+ }
+ }
+ ]
+ },
+ {
+ "name": "SnapshotInfo",
+ "id": 5,
+ "type": "schema",
+ "properties": [{
+ "path": "SnapshotId",
+ "type": {
+ "type": "uint32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "Timestamp",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "PSID",
+ "type": {
+ "type": "schema",
+ "name": "FileId",
+ "id": 2
+ }
+ },
+ {
+ "path": "TTL",
+ "type": {
+ "type": "int32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ }
+ ]
+ },
+ {
+ "name": "InvalidationStats",
+ "id": 6,
+ "type": "schema",
+ "properties": [{
+ "path": "Count",
+ "type": {
+ "type": "uint32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "SizeInBytes",
+ "type": {
+ "type": "uint32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ }
+ ]
+ },
+ {
+ "name": "RootSegmentPropertyBag",
+ "id": 7,
+ "type": "schema",
+ "properties": [{
+ "path": "Control",
+ "type": {
+ "type": "uint8",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "NumberOfEntries",
+ "type": {
+ "type": "uint32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "NumberOfSnapshots",
+ "type": {
+ "type": "uint32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "LastCheckpointedLSID",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "LastCheckpointedSequenceVector",
+ "type": {
+ "type": "schema",
+ "name": "SequenceVector",
+ "id": 3
+ }
+ },
+ {
+ "path": "LastFlushedLSID",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "LastFlushedSequenceVector",
+ "type": {
+ "type": "schema",
+ "name": "SequenceVector",
+ "id": 3
+ }
+ },
+ {
+ "path": "LastRestoredSourceOffset",
+ "type": {
+ "type": "schema",
+ "name": "Logoffset",
+ "id": 8
+ }
+ },
+ {
+ "path": "LogVersion",
+ "type": {
+ "type": "uint8",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "Timestamp",
+ "type": {
+ "type": "uint64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "ArchivalPartitionId",
+ "type": {
+ "type": "guid",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "TTL",
+ "type": {
+ "type": "int32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "PhysicalUsageInKB",
+ "type": {
+ "type": "uint64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "LogicalUsageInKB",
+ "type": {
+ "type": "uint64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ }
+ ]
+ },
+ {
+ "name": "Logoffset",
+ "id": 8,
+ "type": "schema",
+ "properties": [{
+ "path": "LSID",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "RecordGroupID",
+ "type": {
+ "type": "int32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "RecordIndex",
+ "type": {
+ "type": "int32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ }
+ ]
+ },
+ {
+ "name": "InvalidationManifestPropertyBag",
+ "id": 9,
+ "type": "schema",
+ "properties": [{
+ "path": "NumberOfEntries",
+ "type": {
+ "type": "uint32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "MaxMergedLevel0LSID",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "Timestamp",
+ "type": {
+ "type": "uint64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ }
+ ]
+ },
+ {
+ "name": "InvalidationStreamInfo",
+ "id": 10,
+ "type": "schema",
+ "properties": [{
+ "path": "InvalidationFileId",
+ "type": {
+ "type": "schema",
+ "name": "FileId",
+ "id": 2
+ }
+ },
+ {
+ "path": "State",
+ "type": {
+ "type": "uint8",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "StartLSID",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "EndLSID",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "Level",
+ "type": {
+ "type": "int32",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "CreationTimestamp",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "ObsoletionTimestamp",
+ "type": {
+ "type": "int64",
+ "storage": "fixed",
+ "nullable": false
+ }
+ },
+ {
+ "path": "InvalidationStats",
+ "type": {
+ "type": "schema",
+ "name": "InvalidationStats",
+ "id": 6
+ }
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file