mirror of
https://github.com/microsoft/HybridRow.git
synced 2026-01-20 09:53:13 +00:00
RootSegment.json now loads
This commit is contained in:
@@ -10,7 +10,7 @@ Licensed under the MIT License.
|
||||
|
||||
<groupId>com.azure.data</groupId>
|
||||
<artifactId>azure-cosmos-serialization</artifactId>
|
||||
<version>2.9.5</version>
|
||||
<version>2.9.5-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Microsoft Azure Cosmos Serialization API</name>
|
||||
|
||||
@@ -5,7 +5,6 @@ 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;
|
||||
@@ -13,6 +12,7 @@ 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.HashCommon;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
|
||||
|
||||
@@ -20,7 +20,7 @@ import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.google.common.base.Strings.lenientFormat;
|
||||
import static it.unimi.dsi.fastutil.HashCommon.*;
|
||||
import static it.unimi.dsi.fastutil.HashCommon.mix;
|
||||
|
||||
/**
|
||||
* The unique identifier for a schema.
|
||||
@@ -32,15 +32,14 @@ import static it.unimi.dsi.fastutil.HashCommon.*;
|
||||
public final class SchemaId implements Comparable<SchemaId> {
|
||||
|
||||
public static final int BYTES = Integer.BYTES;
|
||||
public static final SchemaId INVALID = null;
|
||||
public static final SchemaId INVALID;
|
||||
public static final SchemaId NONE;
|
||||
|
||||
private static final long MAX_VALUE = 0x00000000FFFFFFFEL;
|
||||
private static final Int2ReferenceMap<SchemaId> cache;
|
||||
|
||||
static {
|
||||
cache = new Int2ReferenceOpenHashMap<>();
|
||||
cache.put(-1, NONE = new SchemaId(-1));
|
||||
cache.put(0, INVALID = NONE = new SchemaId(0));
|
||||
}
|
||||
|
||||
private final int value;
|
||||
@@ -94,6 +93,19 @@ public final class SchemaId implements Comparable<SchemaId> {
|
||||
return cache.computeIfAbsent(value, SchemaId::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this {@link SchemaId}.
|
||||
* <p>
|
||||
* 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 <a href="https://github.com/OpenHFT/Koloboke">Koloboke</a>
|
||||
* @see <a href="https://en.wikipedia.org/wiki/MurmurHash">MurmurHash</a>
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mix(this.value);
|
||||
@@ -120,16 +132,16 @@ public final class SchemaId implements Comparable<SchemaId> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchemaId deserialize(final JsonParser parser, final DeserializationContext context) throws IOException, JsonProcessingException {
|
||||
public SchemaId deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
|
||||
|
||||
final long value = parser.getLongValue();
|
||||
final int value = parser.getIntValue();
|
||||
|
||||
if (value < 0 || value > MAX_VALUE) {
|
||||
String message = lenientFormat("expected value in [0, %s], not %s", MAX_VALUE, value);
|
||||
if (value == 0) {
|
||||
String message = "expected non-zero int value for SchemaId";
|
||||
throw MismatchedInputException.from(parser, SchemaId.class, message);
|
||||
}
|
||||
|
||||
return SchemaId.from((int) value);
|
||||
return SchemaId.from(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,8 +152,9 @@ public final class SchemaId implements Comparable<SchemaId> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(final SchemaId value, final JsonGenerator generator, final SerializerProvider provider) throws IOException {
|
||||
generator.writeNumber((long) value.value() & MAX_VALUE);
|
||||
public void serialize(
|
||||
final SchemaId value, final JsonGenerator generator, final SerializerProvider provider) throws IOException {
|
||||
generator.writeNumber(value.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ public final class SystemSchema {
|
||||
*/
|
||||
public static final SchemaId SEGMENT_SCHEMA_ID = SchemaId.from(2147473648);
|
||||
|
||||
@SuppressWarnings("StatementWithEmptyBody")
|
||||
private static final Supplier<LayoutResolver> layoutResolver = Suppliers.memoize(() -> {
|
||||
|
||||
final Optional<Namespace> namespace;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
package com.azure.data.cosmos.serialization.hybridrow.schemas;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Array properties represent an unbounded set of zero or more items.
|
||||
* <p>
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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"))
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user