diff --git a/.gitignore b/.gitignore
index 3e759b7..1ebbeff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,7 @@ bld/
[Bb]in/
[Oo]bj/
[Ll]og/
+target/
# Visual Studio 2015/2017 cache/options directory
.vs/
@@ -328,3 +329,4 @@ ASALocalRun/
# MFractors (Xamarin productivity tool) working folder
.mfractor/
+*.iml
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..ebf23ac
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,14 @@
+# Contributing
+
+This project welcomes contributions and suggestions. Most contributions require you to
+agree to a Contributor License Agreement (CLA) declaring that you have the right to,
+and actually do, grant us the rights to use your contribution. For details, visit
+https://cla.microsoft.com.
+
+When you submit a pull request, a CLA-bot will automatically determine whether you need
+to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the
+instructions provided by the bot. You will only need to do this once across all repositories using our CLA.
+
+This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
+For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
+or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 4b1ad51..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
- MIT License
-
- Copyright (c) Microsoft Corporation. All rights reserved.
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE
diff --git a/LICENSE.TXT b/LICENSE.TXT
new file mode 100644
index 0000000..4437826
--- /dev/null
+++ b/LICENSE.TXT
@@ -0,0 +1,21 @@
+Copyright (c) Microsoft Corporation.
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index b81a84e..fe1d34b 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,3 @@
+# PLACEHOLDER
-# Contributing
-
-This project welcomes contributions and suggestions. Most contributions require you to agree to a
-Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
-the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
-
-When you submit a pull request, a CLA bot will automatically determine whether you need to provide
-a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
-provided by the bot. You will only need to do this once across all repos using our CLA.
-
-This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
-For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
-contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
+TODO: DANOBLE: Write README.md
diff --git a/Hybrid Row Whitepaper.docx b/docs/Hybrid-row-whitepaper.docx
similarity index 100%
rename from Hybrid Row Whitepaper.docx
rename to docs/Hybrid-row-whitepaper.docx
diff --git a/dotnet/src/Core/UtfAnyString.cs b/dotnet/src/Core/UtfAnyString.cs
new file mode 100644
index 0000000..34ebd40
--- /dev/null
+++ b/dotnet/src/Core/UtfAnyString.cs
@@ -0,0 +1,480 @@
+// ------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// ------------------------------------------------------------
+
+#pragma warning disable CA2225 // Operator overloads have named alternates
+
+// ReSharper disable once UseNameofExpression
+namespace Microsoft.Azure.Cosmos.Core.Utf8
+{
+ using System;
+ using System.Diagnostics;
+ using System.Runtime.CompilerServices;
+
+ /// A string whose memory representation may be either UTF8 or UTF16.
+ ///
+ /// This type supports polymorphic use of and
+ /// when equality, hashing, and comparison are needed against either encoding. An API leveraging
+ /// can avoid separate method overloads while still accepting either
+ /// encoding without imposing additional allocations.
+ ///
+ [DebuggerDisplay("{ToString()}")]
+ public readonly struct UtfAnyString :
+ IEquatable, IComparable,
+ IEquatable, IComparable,
+ IEquatable, IComparable
+ {
+ public static UtfAnyString Empty => string.Empty;
+
+ private readonly object buffer;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public UtfAnyString(string utf16String)
+ {
+ this.buffer = utf16String;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public UtfAnyString(Utf8String utf8String)
+ {
+ this.buffer = utf8String;
+ }
+
+ public bool IsUtf8 => this.buffer is Utf8String;
+
+ public bool IsUtf16 => this.buffer is string;
+
+ /// True if the length is empty.
+ public bool IsNull => object.ReferenceEquals(null, this.buffer);
+
+ /// True if the length is empty.
+ public bool IsEmpty
+ {
+ get
+ {
+ if (object.ReferenceEquals(null, this.buffer))
+ {
+ return false;
+ }
+
+ switch (this.buffer)
+ {
+ case string s:
+ return s.Length == 0;
+ default:
+ return ((Utf8String)this.buffer).IsEmpty;
+ }
+ }
+ }
+
+ public static implicit operator UtfAnyString(string utf16String)
+ {
+ return new UtfAnyString(utf16String);
+ }
+
+ public static implicit operator string(UtfAnyString str)
+ {
+ return str.buffer?.ToString();
+ }
+
+ public override string ToString()
+ {
+ // ReSharper disable once AssignNullToNotNullAttribute
+ return this.buffer?.ToString();
+ }
+
+ public Utf8String ToUtf8String()
+ {
+ if (object.ReferenceEquals(null, this.buffer))
+ {
+ return null;
+ }
+
+ switch (this.buffer)
+ {
+ case string s:
+ return Utf8String.TranscodeUtf16(s);
+ default:
+ return (Utf8String)this.buffer;
+ }
+ }
+
+ public bool ReferenceEquals(UtfAnyString other)
+ {
+ return this.buffer == other.buffer;
+ }
+
+ public bool Equals(UtfAnyString other)
+ {
+ if (object.ReferenceEquals(null, this.buffer))
+ {
+ return object.ReferenceEquals(null, other.buffer);
+ }
+
+ switch (this.buffer)
+ {
+ case string s:
+ return other.Equals(s);
+ default:
+ return other.Equals((Utf8String)this.buffer);
+ }
+ }
+
+ public bool Equals(Utf8Span other)
+ {
+ return other.Equals(this.buffer);
+ }
+
+ public override bool Equals(object obj)
+ {
+ switch (obj)
+ {
+ case string s:
+ return this.Equals(s);
+ case Utf8String s:
+ return this.Equals(s);
+ case UtfAnyString s:
+ return this.Equals(s);
+ }
+
+ return false;
+ }
+
+ public bool Equals(Utf8String other)
+ {
+ if (object.ReferenceEquals(null, other))
+ {
+ return object.ReferenceEquals(null, this.buffer);
+ }
+
+ return other.Equals(this.buffer);
+ }
+
+ public bool Equals(string other)
+ {
+ if (object.ReferenceEquals(null, this.buffer))
+ {
+ return object.ReferenceEquals(null, other);
+ }
+
+ switch (this.buffer)
+ {
+ case string s:
+ return string.Equals(s, other, StringComparison.Ordinal);
+ default:
+ return ((Utf8String)this.buffer).Equals(other);
+ }
+ }
+
+ public static bool operator ==(UtfAnyString left, UtfAnyString right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(UtfAnyString left, UtfAnyString right)
+ {
+ return !left.Equals(right);
+ }
+
+ public static bool operator ==(UtfAnyString left, string right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(UtfAnyString left, string right)
+ {
+ return !left.Equals(right);
+ }
+
+ public static bool operator ==(string left, UtfAnyString right)
+ {
+ return right.Equals(left);
+ }
+
+ public static bool operator !=(string left, UtfAnyString right)
+ {
+ return !right.Equals(left);
+ }
+
+ public static bool operator ==(UtfAnyString left, Utf8String right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(UtfAnyString left, Utf8String right)
+ {
+ return !left.Equals(right);
+ }
+
+ public static bool operator ==(Utf8String left, UtfAnyString right)
+ {
+ return right.Equals(left);
+ }
+
+ public static bool operator !=(Utf8String left, UtfAnyString right)
+ {
+ return !right.Equals(left);
+ }
+
+ public static bool operator ==(UtfAnyString left, Utf8Span right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(UtfAnyString left, Utf8Span right)
+ {
+ return !left.Equals(right);
+ }
+
+ public static bool operator ==(Utf8Span left, UtfAnyString right)
+ {
+ return right.Equals(left);
+ }
+
+ public static bool operator !=(Utf8Span left, UtfAnyString right)
+ {
+ return !right.Equals(left);
+ }
+
+ public override int GetHashCode()
+ {
+ uint hash1 = 5381;
+ uint hash2 = hash1;
+
+ if (object.ReferenceEquals(null, this.buffer))
+ {
+ return unchecked((int)(hash1 + (hash2 * 1566083941)));
+ }
+
+ switch (this.buffer)
+ {
+ case string s:
+ unchecked
+ {
+ Utf16LittleEndianCodePointEnumerator thisEnumerator = new Utf16LittleEndianCodePointEnumerator(s);
+ for (int i = 0; thisEnumerator.MoveNext(); i++)
+ {
+ uint c = thisEnumerator.Current;
+ if (i % 2 == 0)
+ {
+ hash1 = ((hash1 << 5) + hash1) ^ c;
+ }
+ else
+ {
+ hash2 = ((hash2 << 5) + hash2) ^ c;
+ }
+ }
+
+ return (int)(hash1 + (hash2 * 1566083941));
+ }
+
+ default:
+ return this.buffer.GetHashCode();
+ }
+ }
+
+ public static bool operator <(UtfAnyString left, UtfAnyString right)
+ {
+ return left.CompareTo(right) < 0;
+ }
+
+ public static bool operator <=(UtfAnyString left, UtfAnyString right)
+ {
+ return left.CompareTo(right) <= 0;
+ }
+
+ public static bool operator >(UtfAnyString left, UtfAnyString right)
+ {
+ return left.CompareTo(right) > 0;
+ }
+
+ public static bool operator >=(UtfAnyString left, UtfAnyString right)
+ {
+ return left.CompareTo(right) >= 0;
+ }
+
+ public static bool operator <(UtfAnyString left, string right)
+ {
+ return left.CompareTo(right) < 0;
+ }
+
+ public static bool operator <=(UtfAnyString left, string right)
+ {
+ return left.CompareTo(right) <= 0;
+ }
+
+ public static bool operator >(UtfAnyString left, string right)
+ {
+ return left.CompareTo(right) > 0;
+ }
+
+ public static bool operator >=(UtfAnyString left, string right)
+ {
+ return left.CompareTo(right) >= 0;
+ }
+
+ public static bool operator <(string left, UtfAnyString right)
+ {
+ return right.CompareTo(left) >= 0;
+ }
+
+ public static bool operator <=(string left, UtfAnyString right)
+ {
+ return right.CompareTo(left) > 0;
+ }
+
+ public static bool operator >(string left, UtfAnyString right)
+ {
+ return right.CompareTo(left) <= 0;
+ }
+
+ public static bool operator >=(string left, UtfAnyString right)
+ {
+ return right.CompareTo(left) < 0;
+ }
+
+ public static bool operator <(UtfAnyString left, Utf8String right)
+ {
+ return left.CompareTo(right) < 0;
+ }
+
+ public static bool operator <=(UtfAnyString left, Utf8String right)
+ {
+ return left.CompareTo(right) <= 0;
+ }
+
+ public static bool operator >(UtfAnyString left, Utf8String right)
+ {
+ return left.CompareTo(right) > 0;
+ }
+
+ public static bool operator >=(UtfAnyString left, Utf8String right)
+ {
+ return left.CompareTo(right) >= 0;
+ }
+
+ public static bool operator <(Utf8String left, UtfAnyString right)
+ {
+ return right.CompareTo(left) >= 0;
+ }
+
+ public static bool operator <=(Utf8String left, UtfAnyString right)
+ {
+ return right.CompareTo(left) > 0;
+ }
+
+ public static bool operator >(Utf8String left, UtfAnyString right)
+ {
+ return right.CompareTo(left) <= 0;
+ }
+
+ public static bool operator >=(Utf8String left, UtfAnyString right)
+ {
+ return right.CompareTo(left) < 0;
+ }
+
+ public static bool operator <(UtfAnyString left, Utf8Span right)
+ {
+ return left.CompareTo(right) < 0;
+ }
+
+ public static bool operator <=(UtfAnyString left, Utf8Span right)
+ {
+ return left.CompareTo(right) <= 0;
+ }
+
+ public static bool operator >(UtfAnyString left, Utf8Span right)
+ {
+ return left.CompareTo(right) > 0;
+ }
+
+ public static bool operator >=(UtfAnyString left, Utf8Span right)
+ {
+ return left.CompareTo(right) >= 0;
+ }
+
+ public static bool operator <(Utf8Span left, UtfAnyString right)
+ {
+ return right.CompareTo(left) >= 0;
+ }
+
+ public static bool operator <=(Utf8Span left, UtfAnyString right)
+ {
+ return right.CompareTo(left) > 0;
+ }
+
+ public static bool operator >(Utf8Span left, UtfAnyString right)
+ {
+ return right.CompareTo(left) <= 0;
+ }
+
+ public static bool operator >=(Utf8Span left, UtfAnyString right)
+ {
+ return right.CompareTo(left) < 0;
+ }
+
+ public int CompareTo(UtfAnyString other)
+ {
+ if (object.ReferenceEquals(null, other.buffer))
+ {
+ return object.ReferenceEquals(null, this.buffer) ? 0 : 1;
+ }
+
+ switch (other.buffer)
+ {
+ case string s:
+ return this.CompareTo(s);
+ default:
+ return this.CompareTo((Utf8String)other.buffer);
+ }
+ }
+
+ public int CompareTo(Utf8String other)
+ {
+ if (object.ReferenceEquals(null, this.buffer))
+ {
+ return object.ReferenceEquals(null, other) ? 0 : -1;
+ }
+
+ switch (this.buffer)
+ {
+ case string s:
+ return -other.Span.CompareTo(s);
+ default:
+ return -other.Span.CompareTo((Utf8String)this.buffer);
+ }
+ }
+
+ public int CompareTo(Utf8Span other)
+ {
+ if (object.ReferenceEquals(null, this.buffer))
+ {
+ return -1;
+ }
+
+ switch (this.buffer)
+ {
+ case string s:
+ return -other.CompareTo(s);
+ default:
+ return -other.CompareTo((Utf8String)this.buffer);
+ }
+ }
+
+ public int CompareTo(string other)
+ {
+ if (object.ReferenceEquals(null, this.buffer))
+ {
+ return object.ReferenceEquals(null, other) ? 0 : -1;
+ }
+
+ switch (this.buffer)
+ {
+ case string s:
+ return string.Compare(s, other, StringComparison.Ordinal);
+ default:
+ return ((Utf8String)this.buffer).CompareTo(other);
+ }
+ }
+ }
+}
diff --git a/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/ISpanResizer.java b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/ISpanResizer.java
new file mode 100644
index 0000000..bb25c0d
--- /dev/null
+++ b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/ISpanResizer.java
@@ -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 {
+ /**
+ * Resizes an existing a buffer.
+ * The type of the elements of the memory.
+ *
+ * @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 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 at least as big as
+ * and containing the content of .
+ */
+
+ Span Resize(int minimumLength);
+
+ //C# TO JAVA CONVERTER NOTE: Java does not support optional parameters. Overloaded method(s) are created above:
+ //ORIGINAL LINE: Span Resize(int minimumLength, Span buffer = default);
+ Span Resize(int minimumLength, Span buffer);
+}
\ No newline at end of file
diff --git a/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/MemorySpanResizer.java b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/MemorySpanResizer.java
new file mode 100644
index 0000000..712863d
--- /dev/null
+++ b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/MemorySpanResizer.java
@@ -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 implements ISpanResizer {
+ private Memory 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(new T[initialCapacity]);
+ this.memory = initialCapacity == 0 ? null : new Memory((T[])new Object[initialCapacity]);
+ }
+
+ public Memory getMemory() {
+ return this.memory;
+ }
+
+ /**
+ *
+ */
+
+ public Span 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 Resize(int minimumLength, Span buffer = default)
+ public Span Resize(int minimumLength, Span 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(new T[Math.Max(minimumLength, buffer.Length)]);
+ this.memory = new Memory((T[])new Object[Math.max(minimumLength, buffer.Length)]);
+ }
+
+ Span next = this.memory.Span;
+ if (!buffer.IsEmpty && next.Slice(0, buffer.Length) != buffer) {
+ buffer.CopyTo(next);
+ }
+
+ return next;
+ }
+}
\ No newline at end of file
diff --git a/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/SamplingStringComparer.java b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/SamplingStringComparer.java
new file mode 100644
index 0000000..2427305
--- /dev/null
+++ b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/SamplingStringComparer.java
@@ -0,0 +1,48 @@
+// 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 {
+
+ 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 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/SamplingUtf8StringComparer.java b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/SamplingUtf8StringComparer.java
new file mode 100644
index 0000000..c2f589e
--- /dev/null
+++ b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/layouts/SamplingUtf8StringComparer.java
@@ -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 {
+ 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 utf8 = obj.Span.Span;
+ ReadOnlySpan 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/Record.java b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/Record.java
new file mode 100644
index 0000000..490d34e
--- /dev/null
+++ b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/Record.java
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.data.cosmos.serialization.hybridrow.recordio;
+
+public final class Record {
+
+ public static Record empty() {
+ return new Record(0, 0);
+ }
+
+ private int crc32;
+ private int length;
+
+ public Record(int length, int crc32) {
+ this.length = length;
+ this.crc32 = crc32;
+ }
+
+ public int crc32() {
+ return this.crc32;
+ }
+
+ public Record crc32(int value) {
+ this.crc32 = value;
+ return this;
+ }
+
+ public int length() {
+ return this.length;
+ }
+
+ public Record length(int value) {
+ this.length = value;
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordIOFormatter.java b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordIOFormatter.java
new file mode 100644
index 0000000..689825b
--- /dev/null
+++ b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordIOFormatter.java
@@ -0,0 +1,78 @@
+// 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;
+import com.azure.data.cosmos.serialization.hybridrow.layouts.Layout;
+import com.azure.data.cosmos.serialization.hybridrow.layouts.SystemSchema;
+
+public final class RecordIOFormatter {
+
+ public static final Layout RECORD_LAYOUT = SystemSchema.layoutResolver.resolve(SystemSchema.RECORD_SCHEMA_ID);
+ public static final Layout SEGMENT_LAYOUT = SystemSchema.layoutResolver.resolve(SystemSchema.SEGMENT_SCHEMA_ID);
+
+ public static Result FormatRecord(ReadOnlyMemory body, Out 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 body, out RowBuffer row,
+ // ISpanResizer resizer = default)
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ public static Result FormatRecord(ReadOnlyMemory body, Out row,
+ ISpanResizer resizer) {
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ //ORIGINAL LINE: resizer = resizer != null ? resizer : DefaultSpanResizer.Default;
+ resizer = resizer != null ? resizer : DefaultSpanResizer < Byte >.Default;
+ int estimatedSize = HybridRowHeader.BYTES + RecordIOFormatter.RECORD_LAYOUT.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.RECORD_LAYOUT, record.clone(),
+ RecordSerializer.Write, row.clone());
+ }
+
+ public static Result FormatSegment(Segment segment, Out 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
+ // resizer = default)
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ public static Result FormatSegment(Segment segment, Out row, ISpanResizer resizer) {
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ //ORIGINAL LINE: resizer = resizer != null ? resizer : DefaultSpanResizer.Default;
+ resizer = resizer != null ? resizer : DefaultSpanResizer < Byte >.Default;
+ int estimatedSize =
+ HybridRowHeader.BYTES + RecordIOFormatter.SEGMENT_LAYOUT.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.SEGMENT_LAYOUT,
+ 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(ISpanResizer resizer, int initialCapacity, Layout
+ // layout, T obj, RowWriter.WriterFunc writer, out RowBuffer row)
+ private static Result FormatObject(ISpanResizer resizer, int initialCapacity, Layout layout, T obj,
+ RowWriter.WriterFunc writer, Out 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;
+ }
+}
\ No newline at end of file
diff --git a/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordIOParser.java b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordIOParser.java
new file mode 100644
index 0000000..d6547b5
--- /dev/null
+++ b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordIOParser.java
@@ -0,0 +1,354 @@
+// 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.io.Segment;
+import com.azure.data.cosmos.serialization.hybridrow.layouts.SystemSchema;
+import io.netty.buffer.ByteBuf;
+import it.unimi.dsi.fastutil.bytes.Byte2ObjectMap;
+import it.unimi.dsi.fastutil.bytes.Byte2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+
+import javax.annotation.Nonnull;
+
+import static com.google.common.base.Preconditions.checkState;
+
+public final class RecordIOParser {
+
+ private Record record;
+ private Segment segment;
+ private State state = State.values()[0];
+
+ /**
+ * Processes one buffers worth of data possibly advancing the parser state
+ *
+ * @param buffer1 The buffer to consume
+ * @param type Indicates the type of Hybrid Row produced in {@code 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 this method 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 Result#SUCCESS} if no error has occurred;, otherwise the {@link Result} of the last error
+ * encountered during parsing.
+ *
+ * >
+ */
+ @Nonnull
+ public Result process(
+ @Nonnull final ByteBuf buffer,
+ @Nonnull final Out type,
+ @Nonnull final Out record,
+ @Nonnull final Out need,
+ @Nonnull final Out consumed) {
+
+ Result result = Result.FAILURE;
+ type.set(ProductionType.NONE);
+ record.set(null);
+
+ final int start = buffer.readerIndex();
+
+ switch (this.state) {
+
+ case STATE:
+ this.state = State.NEED_SEGMENT_LENGTH;
+ // TODO: C# TO JAVA CONVERTER: There is no 'goto' in Java:
+ // goto case State.NeedSegmentLength;
+
+ case NEED_SEGMENT_LENGTH: {
+
+ final int minimalSegmentRowSize = HybridRowHeader.BYTES + RecordIOFormatter.SEGMENT_LAYOUT.size();
+
+ if (buffer.readableBytes() < minimalSegmentRowSize) {
+ consumed.set(buffer.readerIndex() - start);
+ need.set(minimalSegmentRowSize);
+ return Result.INSUFFICIENT_BUFFER;
+ }
+
+ ByteBuf span = buffer.slice(buffer.readerIndex(), minimalSegmentRowSize);
+ RowBuffer row = new RowBuffer(span, HybridRowVersion.V1, SystemSchema.layoutResolver);
+ Reference tempReference_row =
+ new Reference(row);
+ RowReader reader = new RowReader(tempReference_row);
+ row = tempReference_row.get();
+ Reference tempReference_reader =
+ new Reference(reader);
+ Out tempOut_segment =
+ new Out();
+ result = SegmentSerializer.read(tempReference_reader, tempOut_segment);
+ this.segment = tempOut_segment.get();
+ reader = tempReference_reader.get();
+ if (result != Result.SUCCESS) {
+ break;
+ }
+
+ this.state = State.NEED_SEGMENT;
+ // TODO: C# TO JAVA CONVERTER: There is no 'goto' in Java:
+ goto case State.NEED_SEGMENT
+ }
+
+ case NEED_SEGMENT: {
+ if (buffer.Length < this.segment.length()) {
+ need.set(this.segment.length());
+ consumed.set(buffer.Length - buffer.Length);
+ return Result.INSUFFICIENT_BUFFER;
+ }
+
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ //ORIGINAL LINE: Span span = b.Span.Slice(0, this.segment.Length);
+ Span span = buffer.Span.Slice(0, this.segment.length());
+ RowBuffer row = new RowBuffer(span, HybridRowVersion.V1, SystemSchema.layoutResolver);
+ Reference tempReference_row2 =
+ new Reference(row);
+ RowReader reader = new RowReader(tempReference_row2);
+ row = tempReference_row2.get();
+ Reference tempReference_reader2 =
+ new Reference(reader);
+ Out tempOut_segment2
+ = new Out();
+ result = SegmentSerializer.read(tempReference_reader2, tempOut_segment2);
+ this.segment = tempOut_segment2.get();
+ reader = tempReference_reader2.get();
+ if (result != Result.SUCCESS) {
+ break;
+ }
+
+ record.set(buffer.Slice(0, span.Length));
+ buffer = buffer.Slice(span.Length);
+ need.set(0);
+ this.state = State.NEED_HEADER;
+ consumed.set(buffer.Length - buffer.Length);
+ type.set(ProductionType.SEGMENT);
+ return Result.SUCCESS;
+ }
+
+ case NEED_HEADER: {
+ if (buffer.Length < HybridRowHeader.BYTES) {
+ need.set(HybridRowHeader.BYTES);
+ consumed.set(buffer.Length - buffer.Length);
+ return Result.INSUFFICIENT_BUFFER;
+ }
+
+ 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(buffer.Span, out header);
+ if (header.Version != HybridRowVersion.V1) {
+ result = Result.INVALID_ROW;
+ break;
+ }
+
+ if (SchemaId.opEquals(header.SchemaId,
+ SystemSchema.SEGMENT_SCHEMA_ID)) {
+ // TODO: C# TO JAVA CONVERTER: There is no 'goto' in Java:
+ goto case State.NEED_SEGMENT
+ }
+
+ if (SchemaId.opEquals(header.SchemaId,
+ SystemSchema.RECORD_SCHEMA_ID)) {
+ // TODO: C# TO JAVA CONVERTER: There is no 'goto' in Java:
+ goto case State.NEED_RECORD
+ }
+
+ result = Result.INVALID_ROW;
+ break;
+ }
+
+ case NEED_RECORD: {
+ int minimalRecordRowSize = HybridRowHeader.BYTES + RecordIOFormatter.RECORD_LAYOUT.size();
+ if (buffer.Length < minimalRecordRowSize) {
+ need.set(minimalRecordRowSize);
+ consumed.set(buffer.Length - buffer.Length);
+ return Result.INSUFFICIENT_BUFFER;
+ }
+
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ //ORIGINAL LINE: Span span = b.Span.Slice(0, minimalRecordRowSize);
+ Span span = buffer.Span.Slice(0, minimalRecordRowSize);
+ RowBuffer row = new RowBuffer(span, HybridRowVersion.V1, SystemSchema.layoutResolver);
+ Reference tempReference_row3 =
+ new Reference(row);
+ RowReader reader = new RowReader(tempReference_row3);
+ row = tempReference_row3.get();
+ Reference tempReference_reader3 = new Reference(reader);
+ Out tempOut_record = new Out();
+ result = RecordSerializer.read(tempReference_reader3, tempOut_record);
+ this.record = tempOut_record.get();
+ reader = tempReference_reader3.get();
+ if (result != Result.SUCCESS) {
+ break;
+ }
+
+ buffer = buffer.Slice(span.Length);
+ this.state = State.NEED_ROW;
+ // TODO: C# TO JAVA CONVERTER: There is no 'goto' in Java:
+ goto case State.NEED_ROW
+ }
+
+ case NEED_ROW: {
+ if (buffer.Length < this.record.length()) {
+ need.set(this.record.length());
+ consumed.set(buffer.Length - buffer.Length);
+ return Result.INSUFFICIENT_BUFFER;
+ }
+
+ record.set(buffer.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()) {
+ result = Result.INVALID_ROW;
+ break;
+ }
+
+ buffer = buffer.Slice(this.record.length());
+ need.set(0);
+ this.state = State.NEED_HEADER;
+ consumed.set(buffer.Length - buffer.Length);
+ type.set(ProductionType.RECORD);
+ return Result.SUCCESS;
+ }
+ }
+
+ this.state = State.ERROR;
+ need.set(0);
+ consumed.set(buffer.Length - buffer.Length);
+ return result;
+ }
+
+ /**
+ * True if a valid segment has been parsed.
+ */
+ public boolean haveSegment() {
+ return this.state.value() >= State.NEED_HEADER.value();
+ }
+
+ /**
+ * If a valid segment has been parsed then current active segment, otherwise undefined.
+ */
+ public Segment segment() {
+ checkState(this.haveSegment());
+ return this.segment;
+ }
+
+ /**
+ * 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 BYTES = Integer.BYTES;
+
+ private static Int2ObjectMap mappings;
+ private int value;
+
+ ProductionType(int value) {
+ this.value = value;
+ mappings().put(value, this);
+ }
+
+ public int value() {
+ return this.value;
+ }
+
+ public static ProductionType from(int value) {
+ return mappings().get(value);
+ }
+
+ private static Int2ObjectMap mappings() {
+ if (mappings == null) {
+ synchronized (ProductionType.class) {
+ if (mappings == null) {
+ mappings = new Int2ObjectOpenHashMap<>();
+ }
+ }
+ }
+ return mappings;
+ }
+ }
+
+ /**
+ * The states for the internal state machine.
+ * Note: numerical ordering of these states matters.
+ */
+ private enum State {
+ STATE(
+ (byte) 0, "Start: no buffers have yet been provided to the parser"),
+ ERROR(
+ (byte) 1, "Unrecoverable parse error encountered"),
+ NEED_SEGMENT_LENGTH(
+ (byte) 2, "Parsing segment header length"),
+ NEED_SEGMENT(
+ (byte) 3, "Parsing segment header"),
+ NEED_HEADER(
+ (byte) 4, "Parsing HybridRow header"),
+ NEED_RECORD(
+ (byte) 5, "Parsing record header"),
+ NEED_ROW(
+ (byte) 6, "Parsing row body");
+
+ public static final int BYTES = Byte.SIZE;
+
+ private static Byte2ObjectMap mappings;
+ private final String description;
+ private final byte value;
+
+ State(byte value, String description) {
+ this.description = description;
+ this.value = value;
+ mappings().put(value, this);
+ }
+
+ public String description() {
+ return this.description;
+ }
+
+ public byte value() {
+ return this.value;
+ }
+
+ public static State from(byte value) {
+ return mappings().get(value);
+ }
+
+ private static Byte2ObjectMap mappings() {
+ if (mappings == null) {
+ synchronized (State.class) {
+ if (mappings == null) {
+ mappings = new Byte2ObjectOpenHashMap<>();
+ }
+ }
+ }
+ return mappings;
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordIOStream.java b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordIOStream.java
new file mode 100644
index 0000000..43f2868
--- /dev/null
+++ b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordIOStream.java
@@ -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.
+ *
+ * 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)>
+
+ /**
+ * Reads an entire RecordIO stream.
+ *
+ * @param stm The stream to read from.
+ * @param visitRecord A (required) delegate that is called once for each record.
+ *
+ * is passed a {@link Memory{T}} of the byte sequence
+ * of the
+ * record body's row buffer.
+ *
+ *
If returns an error then the sequence is aborted.
+ * @param visitSegment An (optional) delegate that is called once for each segment header.
+ *
+ * If is not provided then segment headers are parsed but
+ * skipped
+ * over.
+ *
+ *
+ * is passed a {@link Memory{T}} of the byte sequence of
+ * the segment header's row buffer.
+ *
+ *
If returns an error then the sequence is aborted.
+ * @param resizer Optional memory resizer.
+ * @return Success if the stream is parsed without error, the error code otherwise.
+ */
+
+ public static Task ReadRecordIOAsync(Stream stm, Func, Result> visitRecord,
+ Func, Result> visitSegment) {
+ return ReadRecordIOAsync(stm, visitRecord, visitSegment, null);
+ }
+
+ public static Task ReadRecordIOAsync(Stream stm, Func, 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 ReadRecordIOAsync(this Stream stm, Func, Result>
+ // visitRecord, Func, Result> visitSegment = default, MemorySpanResizer 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 ReadRecordIOAsync(InputStream stm,
+ tangible.Func1Param, Result> visitRecord,
+ tangible.Func1Param, Result> visitSegment,
+ MemorySpanResizer 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();
+ resizer = resizer != null ? resizer : new MemorySpanResizer();
+
+ RecordIOParser parser = null;
+ int need = 0;
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ //ORIGINAL LINE: Memory active = resizer.Memory;
+ Memory active = resizer.getMemory();
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ //ORIGINAL LINE: Memory avail = default;
+ Memory 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 tempOut_prodType = new Out();
+ Memory record;
+ Out> tempOut_record = new Out>();
+ Out tempOut_need = new Out();
+ int consumed;
+ Out tempOut_consumed = new Out();
+ //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 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.INSUFFICIENT_BUFFER)) {
+ 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.INSUFFICIENT_BUFFER) {
+ 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.
+ *
+ * The function is called until either an error is encountered or it
+ * produces an empty body. An empty body terminates the segment.
+ *
+ * Note: This should NOT be the same resizer used to process any rows as both
+ * blocks of memory are used concurrently.
+ *
+ * @return Success if the stream is written without error, the error code otherwise.
+ */
+
+ public static Task 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 WriteRecordIOAsync(this Stream stm, Segment segment, ProduceFunc
+ // produce, MemorySpanResizer 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 WriteRecordIOAsync(Stream stm, Segment segment, ProduceFunc produce,
+ MemorySpanResizer resizer) {
+ return RecordIOStream.WriteRecordIOAsync(stm,
+ segment.clone(), index ->
+ {
+ ReadOnlyMemory buffer;
+ Out> tempOut_buffer = new Out>();
+ 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.
+ *
+ * The function is called until either an error is encountered or it
+ * produces an empty body. An empty body terminates the segment.
+ *
+ * Note: This should NOT be the same resizer used to process any rows as both
+ * blocks of memory are used concurrently.
+ *
+ * @return Success if the stream is written without error, the error code otherwise.
+ */
+
+ public static Task 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 WriteRecordIOAsync(this Stream stm, Segment segment,
+ // ProduceFuncAsync produce, MemorySpanResizer 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 WriteRecordIOAsync(OutputStream stm, Segment segment, ProduceFuncAsync produce,
+ MemorySpanResizer 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();
+ resizer = resizer != null ? resizer : new MemorySpanResizer();
+
+ // Write a RecordIO stream.
+ Memory metadata;
+ Out> tempOut_metadata = new Out>();
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ //ORIGINAL LINE: Result r = RecordIOStream.FormatSegment(segment, resizer, out Memory 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 body;
+ ReadOnlyMemory 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> tempOut_metadata2 = new Out>();
+ //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 body, MemorySpanResizer resizer, out Memory block)
+ private static Result FormatRow(ReadOnlyMemory body, MemorySpanResizer resizer, Out> block) {
+ RowBuffer row;
+ Out tempOut_row = new Out();
+ 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 resizer, out
+ // Memory block)
+ private static Result FormatSegment(Segment segment, MemorySpanResizer resizer,
+ Out> block) {
+ RowBuffer row;
+ Out tempOut_row =
+ new Out();
+ 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.
+ *
+ * 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> buffer);
+ }
+}
\ No newline at end of file
diff --git a/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordSerializer.java b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordSerializer.java
new file mode 100644
index 0000000..bdb05d4
--- /dev/null
+++ b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/RecordSerializer.java
@@ -0,0 +1,68 @@
+// 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.UtfAnyString;
+import com.azure.data.cosmos.serialization.hybridrow.Result;
+import com.azure.data.cosmos.serialization.hybridrow.io.RowReader;
+import com.azure.data.cosmos.serialization.hybridrow.io.RowWriter;
+import com.azure.data.cosmos.serialization.hybridrow.layouts.TypeArgument;
+
+import javax.annotation.Nonnull;
+
+import static com.google.common.base.Preconditions.checkState;
+
+public final class RecordSerializer {
+
+ @Nonnull
+ public static Result read(RowReader reader, Out record) {
+
+ Out value = new Out<>();
+ record.set(Record.empty());
+
+ while (reader.read()) {
+
+ String path = reader.path().toUtf16();
+ checkState(path != null);
+ Result result;
+
+ // TODO: use Path tokens here
+
+ switch (path) {
+
+ case "length":
+
+ result = reader.readInt32(value);
+ record.get().length(value.get());
+
+ if (result != Result.SUCCESS) {
+ return result;
+ }
+ break;
+
+ case "crc32":
+
+ result = reader.readInt32(value);
+ record.get().crc32(value.get());
+
+ if (result != Result.SUCCESS) {
+ return result;
+ }
+ break;
+ }
+ }
+
+ return Result.SUCCESS;
+ }
+
+ @Nonnull
+ public static Result write(RowWriter writer, TypeArgument typeArg, Record record) {
+ Result result = writer.writeInt32(new UtfAnyString("length"), record.length());
+ if (result != Result.SUCCESS) {
+ return result;
+ }
+ return writer.writeUInt32(new UtfAnyString("crc32"), record.crc32());
+ }
+}
\ No newline at end of file
diff --git a/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/SegmentSerializer.java b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/SegmentSerializer.java
new file mode 100644
index 0000000..78db48b
--- /dev/null
+++ b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/recordio/SegmentSerializer.java
@@ -0,0 +1,123 @@
+// 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.Utf8String;
+import com.azure.data.cosmos.core.UtfAnyString;
+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;
+import com.azure.data.cosmos.serialization.hybridrow.io.RowWriter;
+import com.azure.data.cosmos.serialization.hybridrow.io.Segment;
+import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutResolver;
+import com.azure.data.cosmos.serialization.hybridrow.layouts.TypeArgument;
+import io.netty.buffer.ByteBuf;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkState;
+
+public final class SegmentSerializer {
+
+ private static final UtfAnyString COMMENT = new UtfAnyString("comment");
+ private static final UtfAnyString LENGTH = new UtfAnyString("length");
+ private static final UtfAnyString SDL = new UtfAnyString("sdl");
+
+ public static Result read(ByteBuf buffer, LayoutResolver resolver, Out segment) {
+ RowReader reader = new RowReader(new RowBuffer(buffer, HybridRowVersion.V1, resolver));
+ return SegmentSerializer.read(reader, segment);
+ }
+
+ public static Result read(RowReader reader, Out segment) {
+
+ segment.set(new Segment(null, null));
+
+ final Out comment = new Out<>();
+ final Out length = new Out<>();
+ final Out sdl = new Out<>();
+
+ while (reader.read()) {
+
+ // TODO: Use Path tokens here.
+
+ switch (Objects.requireNonNull(reader.path().toUtf16())) {
+
+ case "length": {
+
+ Result result = reader.readInt32(length);
+ segment.get().length(length.get());
+
+ if (result != Result.SUCCESS) {
+ return result;
+ }
+
+ if (reader.length() < segment.get().length()) {
+ // RowBuffer isn't big enough to contain the rest of the header so just return the length
+ return Result.SUCCESS;
+ }
+
+ break;
+ }
+ case "comment": {
+
+ Result result = reader.readString(comment);
+ segment.get().comment(comment.get());
+
+ if (result != Result.SUCCESS) {
+ return result;
+ }
+
+ break;
+ }
+ case "sdl": {
+
+ Result result = reader.readString(sdl);
+ segment.get().sdl(sdl.get());
+
+ if (result != Result.SUCCESS) {
+ return result;
+ }
+
+ break;
+ }
+ }
+ }
+
+ return Result.SUCCESS;
+ }
+
+ public static Result write(RowWriter writer, TypeArgument typeArg, Segment segment) {
+
+ Result result;
+
+ if (segment.comment() != null) {
+ result = writer.writeString(COMMENT, segment.comment());
+ if (result != Result.SUCCESS) {
+ return result;
+ }
+ }
+
+ if (segment.sdl() != null) {
+ result = writer.writeString(SDL, segment.sdl());
+ if (result != Result.SUCCESS) {
+ return result;
+ }
+ }
+
+ // 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.length();
+ result = writer.writeInt32(LENGTH, length);
+ if (result != Result.SUCCESS) {
+ return result;
+ }
+
+ checkState(length == writer.length());
+ return Result.SUCCESS;
+ }
+}
\ No newline at end of file
diff --git a/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PropertySchemaConverter.java b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PropertySchemaConverter.java
new file mode 100644
index 0000000..4d92ef9
--- /dev/null
+++ b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/PropertySchemaConverter.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 Newtonsoft.Json.*;
+import Newtonsoft.Json.Converters.*;
+import Newtonsoft.Json.Linq.*;
+
+/**
+ * Helper class for parsing the polymorphic {@link PropertyType} subclasses from JSON.
+ */
+public class PropertySchemaConverter extends JsonConverter {
+ @Override
+ public boolean getCanWrite() {
+ return false;
+ }
+
+ @Override
+ public boolean CanConvert(java.lang.Class objectType) {
+ return objectType.isAssignableFrom(PropertyType.class);
+ }
+
+ @Override
+ public Object ReadJson(JsonReader reader, java.lang.Class objectType, Object existingValue,
+ JsonSerializer serializer) {
+ PropertyType p;
+ if (reader.TokenType != JsonToken.StartObject) {
+ throw new JsonSerializationException();
+ }
+
+ JObject propSchema = JObject.Load(reader);
+ TypeKind propType;
+
+ JToken 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:
+ if (!propSchema.TryGetValue("type", out value)) {
+ throw new JsonSerializationException("Required \"type\" property missing.");
+ }
+
+ try (JsonReader typeReader = value.CreateReader()) {
+ typeReader.Read(); // Move to the start token
+ propType = TypeKind.forValue((new StringEnumConverter(true)).ReadJson(typeReader, TypeKind.class, null,
+ serializer));
+ }
+
+ switch (propType) {
+ case Array:
+ p = new ArrayPropertyType();
+ break;
+ case SET:
+ p = new SetPropertyType();
+ break;
+ case MAP:
+ p = new MapPropertyType();
+ break;
+ case Object:
+ p = new ObjectPropertyType();
+ break;
+ case Tuple:
+ p = new TuplePropertyType();
+ break;
+ case TAGGED:
+ p = new TaggedPropertyType();
+ break;
+ case Schema:
+ p = new UdtPropertyType();
+ break;
+ default:
+ p = new PrimitivePropertyType();
+ break;
+ }
+
+ serializer.Populate(propSchema.CreateReader(), p);
+ return p;
+ }
+
+ // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
+ //ORIGINAL LINE: [ExcludeFromCodeCoverage] public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ @Override
+ public void WriteJson(JsonWriter writer, Object value, JsonSerializer serializer) {
+ }
+}
\ No newline at end of file
diff --git a/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StrictBooleanConverter.java b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StrictBooleanConverter.java
new file mode 100644
index 0000000..596536b
--- /dev/null
+++ b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StrictBooleanConverter.java
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.data.cosmos.serialization.hybridrow.schemas;
+
+import Newtonsoft.Json.*;
+
+public class StrictBooleanConverter extends JsonConverter {
+ @Override
+ public boolean getCanWrite() {
+ return false;
+ }
+
+ @Override
+ public boolean CanConvert(java.lang.Class objectType) {
+ return objectType == Boolean.class;
+ }
+
+ @Override
+ public Object ReadJson(JsonReader reader, java.lang.Class objectType, Object existingValue,
+ JsonSerializer serializer) {
+ switch (reader.TokenType) {
+ case JsonToken.Boolean:
+ return serializer.Deserialize(reader, objectType);
+ default:
+ throw new JsonSerializationException(String.format("Token \"%1$s\" of type %2$s was not a JSON bool",
+ reader.Value, reader.TokenType));
+ }
+ }
+
+ // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
+ //ORIGINAL LINE: [ExcludeFromCodeCoverage] public override void WriteJson(JsonWriter writer, object value,
+ // JsonSerializer serializer)
+ @Override
+ public void WriteJson(JsonWriter writer, Object value, JsonSerializer serializer) {
+ }
+}
\ No newline at end of file
diff --git a/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StrictIntegerConverter.java b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StrictIntegerConverter.java
new file mode 100644
index 0000000..7626519
--- /dev/null
+++ b/java/exclusions/main/java/com/azure/data/cosmos/serialization/hybridrow/schemas/StrictIntegerConverter.java
@@ -0,0 +1,47 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.data.cosmos.serialization.hybridrow.schemas;
+
+import Newtonsoft.Json.*;
+
+import java.math.BigInteger;
+
+public class StrictIntegerConverter extends JsonConverter {
+ @Override
+ public boolean getCanWrite() {
+ return false;
+ }
+
+ @Override
+ public boolean CanConvert(java.lang.Class objectType) {
+ return StrictIntegerConverter.IsIntegerType(objectType);
+ }
+
+ @Override
+ public Object ReadJson(JsonReader reader, java.lang.Class objectType, Object existingValue,
+ JsonSerializer serializer) {
+ switch (reader.TokenType) {
+ case JsonToken.Integer:
+ return serializer.Deserialize(reader, objectType);
+ default:
+ throw new JsonSerializationException(String.format("Token \"%1$s\" of type %2$s was not a JSON " +
+ "integer", reader.Value, reader.TokenType));
+ }
+ }
+
+ // TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
+ //ORIGINAL LINE: [ExcludeFromCodeCoverage] public override void WriteJson(JsonWriter writer, object value,
+ // JsonSerializer serializer)
+ @Override
+ public void WriteJson(JsonWriter writer, Object value, JsonSerializer serializer) {
+ }
+
+ private static boolean IsIntegerType(java.lang.Class type) {
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ //ORIGINAL LINE: if (type == typeof(long) || type == typeof(ulong) || type == typeof(int) || type == typeof
+ // (uint) || type == typeof(short) || type == typeof(ushort) || type == typeof(byte) || type == typeof(sbyte)
+ // || type == typeof(BigInteger))
+ return type == Long.class || type == Long.class || type == Integer.class || type == Integer.class || type == Short.class || type == Short.class || type == Byte.class || type == Byte.class || type == BigInteger.class;
+ }
+}
\ No newline at end of file
diff --git a/java/exclusions/test/java/com/azure/data/cosmos/serialization/hybridrow/perf/BenchmarkSuiteBase.java b/java/exclusions/test/java/com/azure/data/cosmos/serialization/hybridrow/perf/BenchmarkSuiteBase.java
new file mode 100644
index 0000000..e7b841d
--- /dev/null
+++ b/java/exclusions/test/java/com/azure/data/cosmos/serialization/hybridrow/perf/BenchmarkSuiteBase.java
@@ -0,0 +1,140 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.data.cosmos.serialization.hybridrow.perf;
+
+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.MemorySpanResizer;
+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;
+import com.azure.data.cosmos.serialization.hybridrow.layouts.Layout;
+import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutResolver;
+import com.azure.data.cosmos.serialization.hybridrow.layouts.LayoutResolverNamespace;
+import com.azure.data.cosmos.serialization.hybridrow.layouts.SystemSchema;
+import com.azure.data.cosmos.serialization.hybridrow.recordio.RecordIOStream;
+import com.azure.data.cosmos.serialization.hybridrow.io.Segment;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.stream.Stream;
+
+// TODO: C# TO JAVA CONVERTER: There is no preprocessor in Java:
+///#pragma warning disable SA1401 // Fields should be private
+
+
+public class BenchmarkSuiteBase {
+ //C# TO JAVA CONVERTER WARNING: Java has no equivalent to C# 'private protected' access:
+ //ORIGINAL LINE: private protected const int InitialCapacity = 2 * 1024 * 1024;
+ protected static final int InitialCapacity = 2 * 1024 * 1024;
+ //C# TO JAVA CONVERTER WARNING: Java has no equivalent to C# 'private protected' access:
+ //ORIGINAL LINE: private protected LayoutResolverNamespace DefaultResolver = (LayoutResolverNamespace)
+ // SystemSchema.LayoutResolver;
+ protected LayoutResolverNamespace DefaultResolver = (LayoutResolverNamespace)SystemSchema.layoutResolver;
+
+ // TODO: C# TO JAVA CONVERTER: Methods returning tuples are not converted by C# to Java Converter:
+ // private protected async Task<(List>, LayoutResolverNamespace)>
+ // LoadExpectedAsync(string expectedFile)
+ // {
+ // LayoutResolverNamespace resolver = this.DefaultResolver;
+ // List> expected = new List>();
+ // using (Stream stm = new FileStream(expectedFile, FileMode.Open))
+ // {
+ // // Read a RecordIO stream.
+ // MemorySpanResizer resizer = new MemorySpanResizer(BenchmarkSuiteBase.InitialCapacity);
+ // Result r = await stm.ReadRecordIOAsync(record =>
+ // {
+ // r = BenchmarkSuiteBase.LoadOneRow(record, resolver, out Dictionary
+ // rowValue);
+ // ResultAssert.IsSuccess(r);
+ // expected.Add(rowValue);
+ // return Result.Success;
+ // }
+ // , segment =>
+ // {
+ // r = SegmentSerializer.Read(segment.Span, SystemSchema.LayoutResolver, out Segment s);
+ // ResultAssert.IsSuccess(r);
+ // Assert.IsNotNull(s.SDL);
+ // resolver = new LayoutResolverNamespace(Namespace.Parse(s.SDL), resolver);
+ // return Result.Success;
+ // }
+ // , resizer);
+ //
+ // ResultAssert.IsSuccess(r);
+ // }
+ //
+ // return (expected, resolver);
+ // }
+
+ //C# TO JAVA CONVERTER WARNING: Java has no equivalent to C# 'private protected' access:
+ //ORIGINAL LINE: private protected static Result LoadOneRow(Memory buffer, LayoutResolver resolver, out
+ // Dictionary rowValue)
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ protected static Result LoadOneRow(Memory buffer, LayoutResolver resolver,
+ Out> rowValue) {
+ RowBuffer row = new RowBuffer(buffer.Span, HybridRowVersion.V1, resolver);
+ Reference tempReference_row =
+ new Reference(row);
+ RowReader reader = new RowReader(tempReference_row);
+ row = tempReference_row.get();
+ Reference tempReference_reader =
+ new Reference(reader);
+ Result tempVar = DiagnosticConverter.ReaderToDynamic(tempReference_reader, rowValue);
+ reader = tempReference_reader.get();
+ return tempVar;
+ }
+
+ // TODO: C# TO JAVA CONVERTER: There is no equivalent in Java to the 'async' keyword:
+ //ORIGINAL LINE: private protected static async Task WriteAllRowsAsync(string file, string sdl, LayoutResolver
+ // resolver, Layout layout, List> rows)
+ //C# TO JAVA CONVERTER WARNING: Java has no equivalent to C# 'private protected' access:
+ protected static Task WriteAllRowsAsync(String file, String sdl, LayoutResolver resolver, Layout layout,
+ ArrayList> rows) {
+ try (Stream stm = new FileStream(file, FileMode.Truncate)) {
+ // Create a reusable, resizable buffer.
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ //ORIGINAL LINE: MemorySpanResizer resizer = new MemorySpanResizer(BenchmarkSuiteBase
+ // .InitialCapacity);
+ MemorySpanResizer resizer = new MemorySpanResizer(BenchmarkSuiteBase.InitialCapacity);
+
+ // Write a RecordIO stream.
+ // TODO: C# TO JAVA CONVERTER: There is no equivalent to 'await' in Java:
+ // TODO: C# TO JAVA CONVERTER: The following lambda contained an unresolved 'out' keyword - these are
+ // not converted by C# to Java Converter:
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ //ORIGINAL LINE: Result r = await stm.WriteRecordIOAsync(new Segment("HybridRow.Tests.Perf Expected
+ // Results", sdl), (long index, out ReadOnlyMemory body) =>
+ Result r = await RecordIOStream.WriteRecordIOAsync(stm,
+ new Segment("HybridRow.Tests.Perf Expected Results", sdl), (long index, out ReadOnlyMemorybody) ->
+ {
+ body = null;
+ if (index >= rows.size()) {
+ return Result.SUCCESS;
+ }
+
+ StreamingRowGenerator writer = new StreamingRowGenerator(BenchmarkSuiteBase.InitialCapacity, layout,
+ resolver, resizer);
+
+ Result r2 = writer.WriteBuffer(rows.get((int)index));
+ if (r2 != Result.SUCCESS) {
+ return r2;
+ }
+
+ body = resizer.getMemory().Slice(0, writer.getLength());
+ return Result.SUCCESS;
+ });
+
+ ResultAssert.IsSuccess(r);
+ }
+ }
+
+ //C# TO JAVA CONVERTER WARNING: Java has no equivalent to C# 'private protected' access:
+ //ORIGINAL LINE: private protected static class ResultAssert
+ protected static class ResultAssert {
+ public static void IsSuccess(Result actual) {
+ assert actual == Result.SUCCESS || Result.SUCCESS == actual;
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/exclusions/test/java/com/azure/data/cosmos/serialization/hybridrow/perf/BsonJsonModelRowGenerator.java b/java/exclusions/test/java/com/azure/data/cosmos/serialization/hybridrow/perf/BsonJsonModelRowGenerator.java
new file mode 100644
index 0000000..73d36f1
--- /dev/null
+++ b/java/exclusions/test/java/com/azure/data/cosmos/serialization/hybridrow/perf/BsonJsonModelRowGenerator.java
@@ -0,0 +1,130 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.data.cosmos.serialization.hybridrow.perf;
+
+import org.bson.BsonWriter;
+import org.bson.BsonBinaryWriter
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import static com.google.common.base.Strings.lenientFormat;
+
+public final class BsonJsonModelRowGenerator implements Closeable {
+ // TODO: C# TO JAVA CONVERTER: C# to Java Converter cannot determine whether this System.IO.MemoryStream is
+ // input or output:
+ private MemoryStream stream;
+ private BsonWriter writer;
+
+ public BsonJsonModelRowGenerator(int capacity) {
+ // TODO: C# TO JAVA CONVERTER: C# to Java Converter cannot determine whether this System.IO.MemoryStream
+ // is input or output:
+ this.stream = new MemoryStream(capacity);
+ this.writer = new BsonBinaryWriter(this.stream);
+ }
+
+ public int getLength() {
+ return (int)this.stream.Position;
+ }
+
+ public void Reset() {
+ this.stream.SetLength(0);
+ this.stream.Position = 0;
+ }
+
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ //ORIGINAL LINE: public byte[] ToArray()
+ public byte[] ToArray() {
+ return this.stream.ToArray();
+ }
+
+ public void WriteBuffer(HashMap dict) {
+ this.writer.writeStartDocument();
+ for ((Utf8String propPath,Object propValue) : dict)
+ {
+ this.JsonModelSwitch(propPath, propValue);
+ }
+
+ this.writer.writeEndDocument();
+ }
+
+ public void close() throws IOException {
+ this.writer.Dispose();
+ this.stream.Dispose();
+ }
+
+ private void JsonModelSwitch(Utf8String path, Object value) {
+ if (path != null) {
+ this.writer.writeName(path.toString());
+ }
+
+ switch (value) {
+ case null:
+ this.writer.writeNull();
+ return;
+ // TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements:
+ //ORIGINAL LINE: case bool x:
+ case
+ boolean x:
+ this.writer.writeBoolean(x);
+ return;
+ // TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements:
+ //ORIGINAL LINE: case long x:
+ case
+ long x:
+ this.writer.writeInt64(x);
+ return;
+ // TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements:
+ //ORIGINAL LINE: case double x:
+ case
+ double x:
+ this.writer.writeDouble(x);
+ return;
+ // TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements:
+ //ORIGINAL LINE: case string x:
+ case String
+ x:
+ this.writer.writeString(x);
+ return;
+ // TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements:
+ //ORIGINAL LINE: case Utf8String x:
+ case Utf8String
+ x:
+ this.writer.writeString(x.toString());
+ return;
+ // TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements:
+ //ORIGINAL LINE: case byte[] x:
+ //C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
+ case
+ byte[] x:
+ this.writer.writeBytes(x);
+ return;
+ // TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements:
+ //ORIGINAL LINE: case Dictionary x:
+ case HashMap < Utf8String, Object > x:
+ this.writer.writeStartDocument();
+ for ((Utf8String propPath,Object propValue) :x)
+ {
+ this.JsonModelSwitch(propPath, propValue);
+ }
+
+ this.writer.writeEndDocument();
+ return;
+ // TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements:
+ //ORIGINAL LINE: case List