Skip to content

Commit

Permalink
Added uniquess check of unique ids. (#50)
Browse files Browse the repository at this point in the history
Co-authored-by: Carael <[email protected]>
  • Loading branch information
nscheibe and Carael authored Apr 29, 2021
1 parent e6b5729 commit 8e64b24
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 16 deletions.
98 changes: 87 additions & 11 deletions src/Prime.Extensions.Tests/MongoCollectionFindExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public async Task FindIds_FindOneId_ReturnsRightBar()

// Act
IReadOnlyDictionary<Guid, Bar> result =
await barCollection.FindIdsAsync(idsToFind, bar => bar.Id);
await barCollection.FindUniqueIdsAsync(idsToFind, bar => bar.Id);

// Assert
Snapshot.Match(result);
Expand Down Expand Up @@ -70,7 +70,7 @@ public async Task FindIds_FindFourBarIdsSynchronously_ReturnsRightBars(

// Act
IReadOnlyDictionary<Guid, Bar> result = await barCollection
.FindIdsAsync(idsToFind, bar => bar.Id, parallelBatchSize: parallelBatchSize);
.FindUniqueIdsAsync(idsToFind, bar => bar.Id, parallelBatchSize: parallelBatchSize);

// Assert
Assert.IsType<Dictionary<Guid, Bar>>(result);
Expand Down Expand Up @@ -103,7 +103,7 @@ public async Task FindIds_FindFourBarIdsAsynchronously_ReturnsRightBars(

// Act
IReadOnlyDictionary<Guid, Bar> result = await barCollection
.FindIdsAsync(idsToFind, bar => bar.Id, parallelBatchSize: parallelBatchSize);
.FindUniqueIdsAsync(idsToFind, bar => bar.Id, parallelBatchSize: parallelBatchSize);

// Assert
Assert.IsType<ConcurrentDictionary<Guid, Bar>>(result);
Expand Down Expand Up @@ -137,7 +137,7 @@ public async Task FindIds_FindFourBarNamesSynchronously_ReturnsRightBars(

// Act
IReadOnlyDictionary<string, Bar> result = await barCollection
.FindIdsAsync(namesToFind, bar => bar.Name, parallelBatchSize: parallelBatchSize);
.FindUniqueIdsAsync(namesToFind, bar => bar.Name, parallelBatchSize: parallelBatchSize);

// Assert
Assert.IsType<Dictionary<string, Bar>>(result);
Expand Down Expand Up @@ -170,13 +170,89 @@ public async Task FindIds_FindFourBarNamesAsynchronously_ReturnsRightBars(

// Act
IReadOnlyDictionary<string, Bar> result = await barCollection
.FindIdsAsync(namesToFind, bar => bar.Name, parallelBatchSize: parallelBatchSize);
.FindUniqueIdsAsync(namesToFind, bar => bar.Name, parallelBatchSize: parallelBatchSize);

// Assert
Assert.IsType<ConcurrentDictionary<string, Bar>>(result);
Snapshot.Match(result.OrderBy(key => key.Key));
}

[Theory]
[InlineData(null)]
[InlineData(3)]
[InlineData(4)]
public async Task FindIds_FindDuplicatedBarIdsSynchronously_ReturnsDistinctBars(
int? parallelBatchSize)
{
// Arrange
IMongoCollection<Bar> barCollection = _mongoDatabase.GetCollection<Bar>();

var arrangedBars = new List<Bar> {
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903041"), "Bar1", "Value1"),
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903042"), "Bar2", "Value2"),
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903043"), "Bar3", "Value3"),
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903044"), "Bar4", "Value4"),
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903045"), "Bar5", "Value5"),
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903046"), "Bar6", "Value6"),
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903047"), "Bar7", "Value7"),
};

await barCollection.InsertManyAsync(arrangedBars);

IEnumerable<Guid> duplicatedIds = new List<Guid> {
Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903041"),
Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903044"),
Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903046"),
Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903044"),
};

// Act
IReadOnlyDictionary<Guid, Bar> result = await barCollection
.FindUniqueIdsAsync(duplicatedIds, bar => bar.Id, parallelBatchSize: parallelBatchSize);

// Assert
Assert.IsType<Dictionary<Guid, Bar>>(result);
Snapshot.Match(result.OrderBy(entry => entry.Key));
}

[Theory]
[InlineData(1)]
[InlineData(2)]
public async Task FindIds_FindDuplicatedBarIdsAsynchronously_ReturnsDistinctBars(
int parallelBatchSize)
{
// Arrange
IMongoCollection<Bar> barCollection = _mongoDatabase.GetCollection<Bar>();

var arrangedBars = new List<Bar> {
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903041"), "Bar1", "Value1"),
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903042"), "Bar2", "Value2"),
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903043"), "Bar3", "Value3"),
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903044"), "Bar4", "Value4"),
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903045"), "Bar5", "Value5"),
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903046"), "Bar6", "Value6"),
new Bar(Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903047"), "Bar7", "Value7"),
};

await barCollection.InsertManyAsync(arrangedBars);

IEnumerable<Guid> duplicatedIds = new List<Guid> {
Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903041"),
Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903044"),
Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903046"),
Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903044"),
Guid.Parse("A1C9E3E8-B448-42DA-A684-716932903047")
};

// Act
IReadOnlyDictionary<Guid, Bar> result = await barCollection
.FindUniqueIdsAsync(duplicatedIds, bar => bar.Id, parallelBatchSize: parallelBatchSize);

// Assert
Assert.IsType<ConcurrentDictionary<Guid, Bar>>(result);
Snapshot.Match(result.OrderBy(key => key.Key));
}

[Theory]
[InlineData(null)]
[InlineData(3)]
Expand Down Expand Up @@ -204,7 +280,7 @@ public async Task FindIds_FindDuplicatedBarNamesSynchronously_ThrowsArgumentExce

// Act
Func<Task> action = async () => await barCollection
.FindIdsAsync(namesToFind, bar => bar.Name, parallelBatchSize: parallelBatchSize);
.FindUniqueIdsAsync(namesToFind, bar => bar.Name, parallelBatchSize: parallelBatchSize);

// Assert
ArgumentException exception = await Assert.ThrowsAsync<ArgumentException>(action);
Expand Down Expand Up @@ -237,7 +313,7 @@ public async Task FindIds_FindDuplicatedBarNamesAsynchronously_ThrowsArgumentExc

// Act
Func<Task> action = async () => await barCollection
.FindIdsAsync(namesToFind, bar => bar.Name, parallelBatchSize: parallelBatchSize);
.FindUniqueIdsAsync(namesToFind, bar => bar.Name, parallelBatchSize: parallelBatchSize);

// Assert
ArgumentException exception = await Assert.ThrowsAsync<ArgumentException>(action);
Expand Down Expand Up @@ -274,7 +350,7 @@ public async Task FindIds_FindNotExistingBarIdsSynchronously_ReturnsEmptyDiction

// Act
IReadOnlyDictionary<Guid, Bar> result = await barCollection
.FindIdsAsync(notExistingIds, bar => bar.Id, parallelBatchSize: parallelBatchSize);
.FindUniqueIdsAsync(notExistingIds, bar => bar.Id, parallelBatchSize: parallelBatchSize);

// Assert
Assert.IsType<Dictionary<Guid, Bar>>(result);
Expand Down Expand Up @@ -311,7 +387,7 @@ public async Task FindIds_FindNotExistingIdsAsynchronously_ReturnsEmptyDictionar

// Act
IReadOnlyDictionary<Guid, Bar> result = await barCollection
.FindIdsAsync(notExistingIds, bar => bar.Id, parallelBatchSize: parallelBatchSize);
.FindUniqueIdsAsync(notExistingIds, bar => bar.Id, parallelBatchSize: parallelBatchSize);

// Assert
Assert.IsType<ConcurrentDictionary<Guid, Bar>>(result);
Expand Down Expand Up @@ -343,7 +419,7 @@ public async Task FindIds_FindBarsByIds_ReturnsRightBars(

// Act
IReadOnlyDictionary<Guid, Bar> result = await barCollection
.FindIdsAsync(barIdsToFind, bar => bar.Id, parallelBatchSize: parallelBatchSize);
.FindUniqueIdsAsync(barIdsToFind, bar => bar.Id, parallelBatchSize: parallelBatchSize);

// Assert
Assert.IsType(dictionaryType, result);
Expand Down Expand Up @@ -374,7 +450,7 @@ public async Task FindIds_FindLargeAmountOfBarsByIds_ReturnsRightBars(

// Act
IReadOnlyDictionary<Guid, Bar> result = await barCollection
.FindIdsAsync(barIdsToFind, bar => bar.Id, parallelBatchSize: parallelBatchSize);
.FindUniqueIdsAsync(barIdsToFind, bar => bar.Id, parallelBatchSize: parallelBatchSize);

// Assert
Assert.IsType(dictionaryType, result);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[
{
"Key": "a1c9e3e8-b448-42da-a684-716932903041",
"Value": {
"Id": "a1c9e3e8-b448-42da-a684-716932903041",
"Name": "Bar1",
"Value": "Value1"
}
},
{
"Key": "a1c9e3e8-b448-42da-a684-716932903044",
"Value": {
"Id": "a1c9e3e8-b448-42da-a684-716932903044",
"Name": "Bar4",
"Value": "Value4"
}
},
{
"Key": "a1c9e3e8-b448-42da-a684-716932903046",
"Value": {
"Id": "a1c9e3e8-b448-42da-a684-716932903046",
"Name": "Bar6",
"Value": "Value6"
}
},
{
"Key": "a1c9e3e8-b448-42da-a684-716932903047",
"Value": {
"Id": "a1c9e3e8-b448-42da-a684-716932903047",
"Name": "Bar7",
"Value": "Value7"
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[
{
"Key": "a1c9e3e8-b448-42da-a684-716932903041",
"Value": {
"Id": "a1c9e3e8-b448-42da-a684-716932903041",
"Name": "Bar1",
"Value": "Value1"
}
},
{
"Key": "a1c9e3e8-b448-42da-a684-716932903044",
"Value": {
"Id": "a1c9e3e8-b448-42da-a684-716932903044",
"Name": "Bar4",
"Value": "Value4"
}
},
{
"Key": "a1c9e3e8-b448-42da-a684-716932903046",
"Value": {
"Id": "a1c9e3e8-b448-42da-a684-716932903046",
"Name": "Bar6",
"Value": "Value6"
}
}
]
12 changes: 7 additions & 5 deletions src/Prime.Extensions/MongoCollectionFindExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ public static class MongoCollectionFindExtensions
{
private static readonly int DefaultConcurrencyLevel = Environment.ProcessorCount;

public static async Task<IReadOnlyDictionary<TId, TDocument>> FindIdsAsync<TId, TDocument>(
public static async Task<IReadOnlyDictionary<TId, TDocument>> FindUniqueIdsAsync<TId, TDocument>(
this IMongoCollection<TDocument> mongoCollection,
IEnumerable<TId> idsToFind,
IEnumerable<TId> uniqueIdsToFind,
Expression<Func<TDocument, TId>> idResultSelector,
FindOptions? findOptions = null,
int? parallelBatchSize = null,
CancellationToken cancellationToken = default)
{
int allIdsCount = idsToFind.Count();
IEnumerable<TId> uniqueIds = uniqueIdsToFind.Distinct();

int allIdsCount = uniqueIds.Count();

Func<TDocument, TId> idSelectorFunc = idResultSelector.Compile();

Expand All @@ -32,15 +34,15 @@ public static async Task<IReadOnlyDictionary<TId, TDocument>> FindIdsAsync<TId,
if (batchPartitionsCount <= 1)
{
return await mongoCollection.FindIdsInOneRequest(
idsToFind,
uniqueIds,
idSelectorFunc,
idResultSelector,
findOptions,
cancellationToken);
}

return await mongoCollection.FindIdsInParallelRequests(
idsToFind,
uniqueIds,
idSelectorFunc,
idResultSelector,
findOptions,
Expand Down

0 comments on commit 8e64b24

Please sign in to comment.