Skip to content

Commit

Permalink
Faster non-positional algorithm for positional partial sub-keys.
Browse files Browse the repository at this point in the history
  • Loading branch information
protobufel committed Jun 4, 2017
1 parent 1b4ecc7 commit 1c0b976
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 22 deletions.
52 changes: 34 additions & 18 deletions MultiKeyMap/Base/NonPositionalBaseMultiKeyMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public override bool TryGetFullKeysByPartialKey(IEnumerable<T> subKeys, IEnumera
return false;
}

ISet<K> result;
HashSet<K> result;

if (GetAtOrNegative(positionList, minPos) < 0)
{
Expand All @@ -172,53 +172,69 @@ public override bool TryGetFullKeysByPartialKey(IEnumerable<T> subKeys, IEnumera
{
if (i != minPos)
{
if (!TryGetFilteredFullKeys(GetAtOrNegative(positionList, i), subKeyList[i], subResults[i], out ISet<K> filteredSubResult))
result.IntersectWith(subResults[i]);

if (result.Count == 0)
{
fullKeys = default(IEnumerable<K>);
fullKeys = default(ISet<K>);
return false;
}
}
}

result.IntersectWith(filteredSubResult);
var subKeyPosList = subKeyList
.Zip<T, int, (T subKey, int position)>(positionList, (subKey, position) => (subKey, position))
.Where((tuple, index) => (index != minPos) && (tuple.position > 0))
.ToList();

if (result.Count == 0)
if (subKeyPosList.Count != 0)
{
// could be streamed via IEnumerable result.Where(<the predicate opposite the one below>) but then subKeyList and positionList should always be copied
result.RemoveWhere(key =>
{
foreach (var subKeyPos in subKeyPosList)
{
fullKeys = default(IEnumerable<K>);
return false;
if (!SubKeyComparer.Equals(subKeyPos.subKey, key.ElementAtOrDefault(subKeyPos.position)))
{
return true;
}
}

return false;
});

if (result.Count == 0)
{
fullKeys = default(IEnumerable<K>);
return false;
}
}

fullKeys = result;
return true;
}

protected virtual bool TryGetFilteredFullKeys(int position, T subkey, ISet<K> source, out ISet<K> target)
protected virtual bool TryGetFilteredFullKeys(int position, T subKey, ISet<K> source, out HashSet<K> target)
{
if (source.Count == 0)
{
target = default(ISet<K>);
target = default(HashSet<K>);
return false;
}

if (position < 0)
{
target = source;
return true;
}

target = new HashSet<K>(EqualityComparerExtensions.ReferenceEqualityComparerOf<K>());

foreach (K fullKey in source)
{
if (SubKeyComparer.Equals(subkey, fullKey.ElementAtOrDefault(position)))
if (SubKeyComparer.Equals(subKey, fullKey.ElementAtOrDefault(position)))
{
target.Add(fullKey);
}
}

if (target.Count == 0)
{
target = default(ISet<K>);
target = default(HashSet<K>);
return false;
}

Expand Down Expand Up @@ -248,7 +264,7 @@ protected override void DeletePartial(K key)

protected override void ClearPartial()
{
partMap.Clear();
partMap.Clear();
}

#endregion
Expand Down
8 changes: 4 additions & 4 deletions MultiKeyMap/MultiKeyMap.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
<RepositoryUrl>https://github.com/protobufel/multikeymapcsharp</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>c# library multikey dictionary</PackageTags>
<PackageReleaseNotes>Added license to all files; same Apache 2.0 license!</PackageReleaseNotes>
<PackageReleaseNotes>Faster non-positional algorithm when dealing with positional partial sub-keys.</PackageReleaseNotes>
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<SignAssembly>False</SignAssembly>
<AssemblyVersion>4.2.21.0</AssemblyVersion>
<FileVersion>4.2.21.0</FileVersion>
<Version>4.2.21</Version>
<AssemblyVersion>4.3.0.0</AssemblyVersion>
<FileVersion>4.3.0.0</FileVersion>
<Version>4.3.0</Version>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
Expand Down

0 comments on commit 1c0b976

Please sign in to comment.