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

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

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

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

            return(true);
        }
Exemplo n.º 2
0
        public override bool TryGetFullKeysByPartialKey(IEnumerable <T> subKeys, IEnumerable <int> positions, out IEnumerable <K> fullKeys)
        {
            if (subKeys == null)
            {
                throw new ArgumentNullException("subKeys");
            }
            if (positions == null)
            {
                throw new ArgumentNullException("positions");
            }

            if (!subKeys.Any())
            {
                fullKeys = default(IEnumerable <K>);
                return(false);
            }

            IList <int>       positionList = positions as IList <int> ?? positions.ToList();
            IList <T>         subKeyList   = subKeys as IList <T> ?? subKeys.ToList();
            IList <ISet <K> > subResults   = new List <ISet <K> >();
            int minSize = int.MaxValue;
            int minPos  = -1;

            foreach (var subKey in subKeyList)
            {
                if (!partMap.TryGetValue(subKey, out ISet <K> subResult))
                {
                    fullKeys = default(IEnumerable <K>);
                    return(false);
                }

                if (subResult.Count < minSize)
                {
                    minSize = subResult.Count;
                    minPos  = subResults.Count;
                }

                subResults.Add(subResult);
            }

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

            HashSet <K> result;

            if (GetAtOrNegative(positionList, minPos) < 0)
            {
                result = new HashSet <K>(subResults[minPos], EqualityComparerExtensions.ReferenceEqualityComparerOf <K>());
            }
            else if (!TryGetFilteredFullKeys(GetAtOrNegative(positionList, minPos), subKeyList[minPos], subResults[minPos], out result))
            {
                fullKeys = default(IEnumerable <K>);
                return(false);
            }

            if (subResults.Count == 1)
            {
                fullKeys = result;
                return(true);
            }

            for (int i = 0; i < subResults.Count; i++)
            {
                if (i != minPos)
                {
                    result.IntersectWith(subResults[i]);

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

            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 (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)
                    {
                        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);
        }