From 4d3b03c65538711499bbeeea642e4c98d33f3519 Mon Sep 17 00:00:00 2001 From: Nalu Tripician Date: Mon, 11 Sep 2023 13:02:48 -0700 Subject: [PATCH] Requested changes --- .../CosmosQueryExecutionContextFactory.cs | 17 ++--- .../src/Routing/PartitionKeyHash.cs | 10 ++- .../PartitionKeyHashBaselineTest.Lists.xml | 32 ++++++++++ .../Pagination/InMemoryContainer.cs | 2 +- .../Routing/PartitionKeyHashBaselineTest.cs | 63 +++++++++++++++++++ .../PartitionKeyHashRangeSplitterAndMerger.cs | 10 ++- 6 files changed, 121 insertions(+), 13 deletions(-) create mode 100644 Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/PartitionKeyHashBaselineTest.Lists.xml rename Microsoft.Azure.Cosmos/{src => tests/Microsoft.Azure.Cosmos.Tests}/Routing/PartitionKeyHashRangeSplitterAndMerger.cs (96%) diff --git a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs index dbd1b4800f..e9916b173d 100644 --- a/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs +++ b/Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs @@ -7,9 +7,9 @@ namespace Microsoft.Azure.Cosmos.Query.Core.ExecutionContext using System.Collections.Generic; using System.Diagnostics; using System.Linq; - using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; + using global::Azure; using Microsoft.Azure.Cosmos; using Microsoft.Azure.Cosmos.CosmosElements; using Microsoft.Azure.Cosmos.Pagination; @@ -648,7 +648,8 @@ private static async Task GetPartitionedQueryExec else if (TryGetEpkProperty(properties, out string effectivePartitionKeyString)) { List> effectiveRanges = new List> - { new Documents.Routing.Range(effectivePartitionKeyString, effectivePartitionKeyString, true, true) }; + { Documents.Routing.Range.GetPointRange(effectivePartitionKeyString) }; + targetRanges = await queryClient.GetTargetPartitionKeyRangesAsync( resourceLink, containerQueryProperties.ResourceId, @@ -656,17 +657,19 @@ private static async Task GetPartitionedQueryExec forceRefresh: false, trace); } - else + else if (feedRangeInternal != null) { - targetRanges = feedRangeInternal != null - ? await queryClient.GetTargetPartitionKeyRangeByFeedRangeAsync( + targetRanges = await queryClient.GetTargetPartitionKeyRangeByFeedRangeAsync( resourceLink, containerQueryProperties.ResourceId, containerQueryProperties.PartitionKeyDefinition, feedRangeInternal, forceRefresh: false, - trace) - : await queryClient.GetTargetPartitionKeyRangesAsync( + trace); + } + else + { + targetRanges = await queryClient.GetTargetPartitionKeyRangesAsync( resourceLink, containerQueryProperties.ResourceId, partitionedQueryExecutionInfo.QueryRanges, diff --git a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHash.cs b/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHash.cs index 905f0b7eec..0d7189abb2 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHash.cs +++ b/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHash.cs @@ -5,7 +5,7 @@ namespace Microsoft.Azure.Cosmos.Routing { using System; - using System.Runtime.CompilerServices; + using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using Microsoft.Azure.Documents.Routing; @@ -35,7 +35,7 @@ namespace Microsoft.Azure.Cosmos.Routing /// internal readonly struct PartitionKeyHash : IComparable, IEquatable { - private readonly UInt128[] values; + private readonly IReadOnlyList values; public PartitionKeyHash(UInt128 value) : this(new UInt128[] { value }) @@ -47,6 +47,10 @@ public PartitionKeyHash(UInt128[] values) StringBuilder stringBuilder = new StringBuilder(); foreach (UInt128 value in values) { + if (stringBuilder.Length > 0) + { + stringBuilder.Append('-'); + } stringBuilder.Append(value.ToString()); } @@ -58,7 +62,7 @@ public PartitionKeyHash(UInt128[] values) public string Value { get; } - internal readonly UInt128[] HashValues => this.values; + internal readonly IReadOnlyList HashValues => this.values; public int CompareTo(PartitionKeyHash other) { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/PartitionKeyHashBaselineTest.Lists.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/PartitionKeyHashBaselineTest.Lists.xml new file mode 100644 index 0000000000..b362660f8a --- /dev/null +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/PartitionKeyHashBaselineTest.Lists.xml @@ -0,0 +1,32 @@ + + + + 1 Path List + ["/path1"] + + + 00-00-00-00-00-00-00-00-00-00-00-00-0A-A1-CC-05 + B6-3D-B6-C4-3A-4F-1B-01-4C-63-B0-C2-E6-28-E8-12 + + + + + 2 Path List + ["/path1","/path2"] + + + 00-00-00-00-00-00-00-00-00-00-00-00-0A-A1-CC-05-00-00-00-00-00-00-00-00-00-00-00-00-C9-1E-F0-78 + B6-3D-B6-C4-3A-4F-1B-01-4C-63-B0-C2-E6-28-E8-12A6-0C-6C-BE-5A-2D-38-6E-5D-AE-1A-AC-94-21-6B-6C + + + + + 3 Path List + ["/path1","/path2","/path3"] + + + 00-00-00-00-00-00-00-00-00-00-00-00-0A-A1-CC-05-00-00-00-00-00-00-00-00-00-00-00-00-C9-1E-F0-7800-00-00-00-00-00-00-00-00-00-00-00-9A-B4-68-CD + B6-3D-B6-C4-3A-4F-1B-01-4C-63-B0-C2-E6-28-E8-12-A6-0C-6C-BE-5A-2D-38-6E-5D-AE-1A-AC-94-21-6B-6C88-A6-18-5D-2D-D5-1C-96-D0-47-75-B7-2E-FA-BE-08 + + + \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/InMemoryContainer.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/InMemoryContainer.cs index 55502ff7d6..5c6e8961e7 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/InMemoryContainer.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Pagination/InMemoryContainer.cs @@ -1392,7 +1392,7 @@ private PartitionKeyHash ComputeMedianSplitPointAmongDocumentsInPKRange(Partitio // For MultiHash Collection, split at top level to ensure documents for top level key exist across partitions // after split - if (medianPkHash.HashValues.Length > 1) + if (medianPkHash.HashValues.Count > 1) { return new PartitionKeyHash(medianPkHash.HashValues[0]); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashBaselineTest.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashBaselineTest.cs index 4fb7b5b53f..f60d0849ca 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashBaselineTest.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashBaselineTest.cs @@ -6,6 +6,7 @@ namespace Microsoft.Azure.Cosmos.Tests.Routing { using System; using System.Collections.Generic; + using System.Linq; using System.Numerics; using System.Xml; using Microsoft.Azure.Cosmos.CosmosElements; @@ -126,6 +127,37 @@ public void Numbers() this.ExecuteTestSuite(inputs); } + [TestMethod] + public void Lists() + { + List inputs = new List() + { + new Input( + description: "1 Path List", + partitionKeyValue: CosmosArray.Create(new List() + { + CosmosString.Create("/path1") + })), + new Input( + description: "2 Path List", + partitionKeyValue: CosmosArray.Create(new List() + { + CosmosString.Create("/path1"), + CosmosString.Create("/path2") + })), + new Input( + description: "3 Path List", + partitionKeyValue: CosmosArray.Create(new List() + { + CosmosString.Create("/path1"), + CosmosString.Create("/path2"), + CosmosString.Create("/path3") + })), + }; + + this.ExecuteTestSuite(inputs); + } + public override Output ExecuteTest(Input input) { CosmosElement value = input.PartitionKeyValue; @@ -159,7 +191,38 @@ public override Output ExecuteTest(Input input) partitionKeyHashV1 = PartitionKeyHash.V1.Hash(Number64.ToDouble(cosmosNumber.Value)); partitionKeyHashV2 = PartitionKeyHash.V2.Hash(Number64.ToDouble(cosmosNumber.Value)); break; + case CosmosArray cosmosArray: + IList partitionKeyHashValuesV1 = new List(); + IList partitionKeyHashValuesV2 = new List(); + foreach (CosmosElement element in cosmosArray) + { + PartitionKeyHash elementHashV1 = element switch + { + null => PartitionKeyHash.V2.HashUndefined(), + CosmosString stringPartitionKey => PartitionKeyHash.V1.Hash(stringPartitionKey.Value), + CosmosNumber numberPartitionKey => PartitionKeyHash.V1.Hash(Number64.ToDouble(numberPartitionKey.Value)), + CosmosBoolean cosmosBoolean => PartitionKeyHash.V1.Hash(cosmosBoolean.Value), + CosmosNull _ => PartitionKeyHash.V1.HashNull(), + _ => throw new ArgumentOutOfRangeException(), + }; + partitionKeyHashValuesV1.Add(elementHashV1.HashValues[0]); + + PartitionKeyHash elementHashV2 = element switch + { + null => PartitionKeyHash.V2.HashUndefined(), + CosmosString stringPartitionKey => PartitionKeyHash.V2.Hash(stringPartitionKey.Value), + CosmosNumber numberPartitionKey => PartitionKeyHash.V2.Hash(Number64.ToDouble(numberPartitionKey.Value)), + CosmosBoolean cosmosBoolean => PartitionKeyHash.V2.Hash(cosmosBoolean.Value), + CosmosNull _ => PartitionKeyHash.V2.HashNull(), + _ => throw new ArgumentOutOfRangeException(), + }; + partitionKeyHashValuesV2.Add(elementHashV2.HashValues[0]); + } + + partitionKeyHashV1 = new PartitionKeyHash(partitionKeyHashValuesV1.ToArray()); + partitionKeyHashV2 = new PartitionKeyHash(partitionKeyHashValuesV2.ToArray()); + break; default: throw new ArgumentOutOfRangeException($"Unknown {nameof(CosmosElement)} type: {value.GetType()}."); } diff --git a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRangeSplitterAndMerger.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashRangeSplitterAndMerger.cs similarity index 96% rename from Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRangeSplitterAndMerger.cs rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashRangeSplitterAndMerger.cs index eeaec93a02..af005b1515 100644 --- a/Microsoft.Azure.Cosmos/src/Routing/PartitionKeyHashRangeSplitterAndMerger.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHashRangeSplitterAndMerger.cs @@ -92,7 +92,7 @@ public static PartitionKeyHashRanges SplitRange(PartitionKeyHashRange partitionK return splitOutcome switch { SplitOutcome.Success => splitRanges, - _ => throw new ArgumentOutOfRangeException($"Unknown {nameof(SplitOutcome)}: {splitOutcome}."), + _ => throw new RangeSplitException($"Splitting range failed because {splitOutcome}"), }; } @@ -144,7 +144,13 @@ private sealed class V2 : PartitionKeyHashRangeSplitterAndMerger public override PartitionKeyHashRange FullRange => PartitionKeyHashRangeSplitterAndMerger.V2.fullRange; } - + private sealed class RangeSplitException : Exception + { + public RangeSplitException(string message) + : base(message) + { + } + } public enum SplitOutcome { Success,