예제 #1
0
        internal static Coordinates[] Locate <TItem, TKey>(
            this UniqueKeyQuery <TItem, TKey> self, ref ReferenceNode <TItem, TKey> node, Coordinates[] coordinateSet, int lvlIndex = 1, int lastOverallIndex = 0)
        {
            if (node == null)
            {
                node = self.Root;
            }

            if (object.Equals(node.Key, default(TKey)))
            {
                node.Key = self.Key;
            }

            var keyComparison =
                self.KeyComparer(node.Key, self.Key);

            //the key in the node is lower than the new key
            if (keyComparison < 0 && node.References != null)
            {
                /* set the rest of the coordinates to the right
                 * if the node has the maximum length, go to the parent and move one to the right
                 * all in the first position
                 * return coordinates set
                 */

                return(GetCoordinates <TItem, TKey>(
                           self, ref node, coordinateSet, lvlIndex, lastOverallIndex, node[node.Length - 1], node.Length - 1));
            }
            //the key in the node is higher than the new key
            else //if (rootComparison > 0)
            {
                /*
                 * if it is a reference one, search inside the child node,
                 * else search inside the values and return the coordinates set
                 */

                var selectKey =
                    self.SelectKey;

                var comparer =
                    self.KeyComparer;

                int rawIndex =
                    ListMixins.BinarySearch(node.Values,
                                            v => v != null ? comparer(self.Key, selectKey(v.Value)):0);

                var found = node[rawIndex < 0 ? ~rawIndex : rawIndex];

                return(GetCoordinates <TItem, TKey>(
                           self, ref node, coordinateSet, lvlIndex, lastOverallIndex, found, rawIndex));
            }
        }
예제 #2
0
        public void Setup()
        {
            RightIndex = 0;

            Query =
                new UniqueKeyQuery <MockItem, int>()
            {
                SelectKey = item => item.Index
            };

            Collection =
                new OptimizedCollection <MockItem>(Query);
        }
예제 #3
0
        /// <summary>
        /// Adds to the value count
        /// </summary>
        /// <typeparam name="TItem">Type of the item</typeparam>
        /// <typeparam name="TKey">Type of the key</typeparam>
        /// <param name="self"></param>
        /// <param name="sumQtd"></param>
        public static void AugmentValueCount <TItem, TKey>(this UniqueKeyQuery <TItem, TKey> self, int sumQtd)
        {
            var lastRefNode =
                self.LastRefNode(self.Root);

            //if needs to change to the next ref node
            if (lastRefNode.Length >= self.State.MaxLengthPerNode)
            {
                self.TryResizeReferencesByOne(lastRefNode);
            }
            else
            {
                TryResizeValues(self, lastRefNode, sumQtd);
            }
        }
예제 #4
0
        /// <summary>
        /// Diminishes the value count from a unique key query
        /// </summary>
        /// <typeparam name="TItem">Type of the item</typeparam>
        /// <typeparam name="TKey">Type of the key</typeparam>
        /// <param name="self">The query</param>
        /// <param name="qtdToSubtract">Quantity to substract</param>
        public static void AbridgeValueCount <TItem, TKey>(this UniqueKeyQuery <TItem, TKey> self, int qtdToSubtract)
        {
            var lastRefNode =
                self.LastRefNode(self.Root);

            if (lastRefNode.Length < 2)
            {
                TryEraseNode(lastRefNode.Parent);
            }
            else
            {
                lastRefNode.Values = lastRefNode
                                     .Values.Resize(lastRefNode.Length - 1);
            }
        }
예제 #5
0
        /// <summary>
        /// Augments the level count.
        /// </summary>
        /// <param name='root'>
        /// The Root of the selector.
        /// </param>
        /// <param name='state'>
        /// the state of the selector tree.
        /// </param>
        /// <param name='itemAmmountToSum'>
        /// Item ammount to sum to the tree.
        /// </param>
        public static void AugmentLevelCount <TItem, TKey>(this UniqueKeyQuery <TItem, TKey> self, int itemAmmountToSum)
        {
            var root = self.Root;

            //increases one level
            //if there is only one level bellow the root,
            if (root.Values != null)
            {
                //Increase one level, and send them to the first node of this new level
                root.References = new []
                {
                    new ReferenceNode <TItem, TKey>
                    {
                        Values   = root.Values,
                        Parent   = root,
                        Key      = root.Key,
                        Comparer = self.KeyComparer
                    }
                };

                root.Values = null;
            }
            else
            {
                //Increase one level, and send them to the first node of this new level
                var refs =
                    root.References;

                root.References = new[]
                {
                    new ReferenceNode <TItem, TKey>
                    {
                        References = refs,
                        Key        = root.Key,
                        Parent     = root,
                        Comparer   = self.KeyComparer
                    }
                };

                for (int i = 0; i < refs.Length; i++)
                {
                    refs[i].Parent =
                        root.References[0];
                }

                refs = null;
            }
        }
예제 #6
0
        /// <summary>
        /// Augments the level count.
        /// </summary>
        /// <param name='root'>
        /// The Root of the selector.
        /// </param>
        /// <param name='state'>
        /// the state of the selector tree.
        /// </param>
        /// <param name='itemAmmountToSum'>
        /// Item ammount to sum to the tree.
        /// </param>
        public static void AbridgeLevelCount <TItem, TKey>(this UniqueKeyQuery <TItem, TKey> self, int itemAmmountToSum)
        {
            var root = self.Root;

            if (root.Values != null)
            {
                throw new NotImplementedException();
            }

            var refs = new List <ReferenceNode <TItem, TKey> >();

            foreach (var subRef in root.GetGrandChildren())
            {
                subRef.Parent = root;
                refs.Add(subRef);
            }

            root.References = refs.ToArray();
        }
예제 #7
0
        /// <summary>
        /// Tries to resize the references by one
        /// </summary>
        /// <typeparam name="TItem">Type of the item</typeparam>
        /// <typeparam name="TKey">Type of the key</typeparam>
        /// <param name="self"></param>
        /// <param name="node">the node that will be increased</param>
        private static void TryResizeReferencesByOne <TItem, TKey>(this UniqueKeyQuery <TItem, TKey> self, ReferenceNode <TItem, TKey> node)
        {
            var lvlIndex = self.State.LevelCount - 2;

            while (node != null)
            {
                if (node.Length < self.State.MaxLengthPerNode)
                {
                    for (int i = lvlIndex; i < self.State.LevelCount; i++)
                    {
                        if (i != (self.State.LevelCount - 2))
                        {
                            node.References = node.References != null?
                                              node.References.Resize(node.Length + 1) :
                                                  new ReferenceNode <TItem, TKey> [1];

                            node.References[node.Length - 1] =
                                new ReferenceNode <TItem, TKey> {
                                Parent = node, Comparer = self.KeyComparer
                            };

                            node = node.References[node.Length - 1];
                        }
                        else
                        {
                            node.Values = node.Values != null?
                                          node.Values.Resize(node.Length + 1) :
                                              new ValueNode <TItem> [1];

                            return;
                        }
                    }
                }
                lvlIndex--;
                node = node.Parent;
            }
        }
예제 #8
0
        internal static Coordinates[] GetCoordinates <TItem, TKey>(UniqueKeyQuery <TItem, TKey> self, ref ReferenceNode <TItem, TKey> node, Coordinates[] coordinateSet, int lvlIndex, int lastOverallIndex, INode found, int rawIndex)
        {
            var index = rawIndex < 0 ? ~rawIndex : rawIndex;

            var coord =
                coordinateSet[lvlIndex];

            coord.Length        = node.Length;
            coord.Index         = index;
            coord.OverallLength = self.State.Levels[lvlIndex].TotalUsed;
            coord.OverallIndex  = (lastOverallIndex * self.State.MaxLengthPerNode) + index;

            lastOverallIndex = coord.OverallIndex;

            if (found is ReferenceNode <TItem, TKey> )
            {
                node = (ReferenceNode <TItem, TKey>)found;

                return(self.Locate(
                           ref node, coordinateSet, lvlIndex + 1, lastOverallIndex));
            }

            return(coordinateSet);
        }
예제 #9
0
        /// <summary>
        /// Loops throughtout all the value nodes, starting from a set of coordinates
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="self"></param>
        /// <param name="coordinateSet"></param>
        /// <param name="inEach"></param>
        /// <returns></returns>
        public static Stack <ReferenceNode <TItem, TKey> > ForEachValuedNode <TItem, TKey>(this UniqueKeyQuery <TItem, TKey> self,
                                                                                           Coordinates[] coordinateSet, Action <ReferenceNode <TItem, TKey>, int> inEach)
        {
            var queue =
                new Stack <ReferenceNode <TItem, TKey> >();

            var coordinates =
                coordinateSet[coordinateSet.Length - 1];

            ReferenceNode <TItem, TKey> @ref = null;

            var iterator =
                IntoLowestRefs(self, coordinateSet).GetEnumerator();

            int overallIndex =
                coordinates.OverallIndex;

            while (iterator.MoveNext())
            {
                queue.Push(@ref = iterator.Current);

                for (int i = coordinates.Index; i < @ref.Length && overallIndex < coordinates.OverallLength; i++)
                {
                    overallIndex++;
                    inEach(@ref, i);
                }
            }

            return(queue);
        }
예제 #10
0
        /// <summary>
        /// Loops throughtout all the value nodes, starting from a set of coordinates, in reverse
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="self"></param>
        /// <param name="coordinates"></param>
        /// <param name="inEach"></param>
        /// <returns></returns>
        public static Stack <ReferenceNode <TItem, TKey> > ForEachValuedNodeReverse <TItem, TKey>(this UniqueKeyQuery <TItem, TKey> self,
                                                                                                  Coordinates[] coordinates, Action <ReferenceNode <TItem, TKey>, int> inEach)
        {
            var queue =
                new Stack <ReferenceNode <TItem, TKey> >();

            var offset =
                coordinates[coordinates.Length - 1];

            ReferenceNode <TItem, TKey> @ref = null;

            var iterator =
                IntoLowestRefsReverse(self, self.Root, coordinates).GetEnumerator();

            int reverseIndex = offset.OverallLength;

            while (iterator.MoveNext())
            {
                queue.Push(@ref = iterator.Current);
                for (int i = @ref.Values.Length - 1; i > -1 && offset.OverallIndex < reverseIndex; i--)
                {
                    reverseIndex--;
                    inEach(@ref, i);
                }
            }

            return(queue);
        }
        /// <summary>
        /// Moves all the references to values one position to the left, starting from a set of coordinates
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="self"></param>
        /// <param name="coordinateSet"></param>
        /// <returns></returns>
        public static Stack <ReferenceNode <TItem, TKey> > MoveAll2TheLeft <TItem, TKey>(this UniqueKeyQuery <TItem, TKey> self, Coordinates[] coordinateSet)
        {
            ReferenceNode <TItem, TKey> previousRef = null;

            return(self.ForEachValuedNode(coordinateSet,
                                          (@ref, i) =>
            {
                //if (@ref.Key.Equals(1089) || (@ref.Key.Equals(1088) && i == 32))
                //{
                //    System.Diagnostics.Debugger.Break();
                //}

                if (i == (@ref.Length - 1) && i > 1)
                {
                    previousRef = @ref;
                }
                else
                {
                    if (previousRef != null)
                    {
                        previousRef.Values[previousRef.Length - 1] = @ref.Values[0];
                        previousRef = null;
                    }

                    if (i != (@ref.Length - 1))
                    {
                        @ref.Values[i] = @ref.Values[i + 1];
                    }
                }
            }));
        }
        /// <summary>
        /// Moves all the references to values one position to the right, starting from a set of coordinates
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="self"></param>
        /// <param name="coordinateSet"></param>
        /// <returns></returns>
        public static Stack <ReferenceNode <TItem, TKey> > MoveAll2TheRight <TItem, TKey>(this UniqueKeyQuery <TItem, TKey> self, Coordinates[] coordinateSet)
        {
            ReferenceNode <TItem, TKey> previousRef = null;

            return(self.ForEachValuedNodeReverse(coordinateSet,
                                                 (@ref, i) =>
            {
                if (i < 1)
                {
                    previousRef = @ref;
                }
                else
                {
                    if (previousRef != null)
                    {
                        previousRef.Values[0] = @ref.Values[@ref.Values.Length - 1];
                        previousRef = null;
                    }

                    @ref.Values[i] = @ref.Values[i - 1];
                }
            }));
        }