Beispiel #1
0
        private void Split(INode nodeAfterEntryAdded)
        {
            INode newN1, newN2;

            if (nodeAfterEntryAdded is NonLeafNode)
            {
                var         result = SplitEntries(nodeAfterEntryAdded);
                NonLeafNode n1     = new NonLeafNode(NonLeafNodeIDGenerater());
                n1.Level = nodeAfterEntryAdded.Level;
                n1.AddEntries(result.Item1);
                NonLeafNode n2 = new NonLeafNode(NonLeafNodeIDGenerater());
                n2.AddEntries(result.Item2);
                n2.Level = nodeAfterEntryAdded.Level;
                newN1    = n1;
                newN2    = n2;
            }
            else
            {
                var  result = SplitEntries(nodeAfterEntryAdded);
                Leaf n1     = new Leaf(NonLeafNodeIDGenerater());
                n1.Level = nodeAfterEntryAdded.Level;
                n1.AddEntries(result.Item1);
                Leaf n2 = new Leaf(NonLeafNodeIDGenerater());
                n2.Level = nodeAfterEntryAdded.Level;
                n2.AddEntries(result.Item2);
                newN1 = n1;
                newN2 = n2;
            }

            _nodesMap.AddOrUpdate(newN1.ID, newN1, (i, n) => { return(newN1); });
            _nodesMap.AddOrUpdate(newN2.ID, newN2, (i, n) => { return(newN2); });


            NonLeafNode parentNode;

            if (!nodeAfterEntryAdded.IsRoot)
            {
                parentNode = nodeAfterEntryAdded.ParentNode as NonLeafNode;
                parentNode.RemoveEntry(nodeAfterEntryAdded.ID);
                _nodesMap.TryRemove(nodeAfterEntryAdded.ID, out nodeAfterEntryAdded);
            }
            else
            {
                parentNode       = new NonLeafNode(NonLeafNodeIDGenerater());
                parentNode.Level = 1;
                _root            = parentNode;
                _nodesMap.AddOrUpdate(_root.ID, _root, (i, n) => { return(_root); });
                _nodesMap.TryRemove(nodeAfterEntryAdded.ID, out nodeAfterEntryAdded);
            }
            parentNode.AddEntry(newN1);
            parentNode.AddEntry(newN2);

            parentNode.UpdateSubTreeLevel(parentNode.Level);

            if (parentNode.Entries.Count() > DEFAULT_MAX_NODE_ENTRIES)
            {
                OverflowTreatment(parentNode);
            }
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="entryToAdd"></param>
        /// <param name="nodeAddTo"></param>
        /// <returns></returns>
        private INode ChooseSubTree(IEntry entryToAdd, INode nodeAddTo, int entryLevel = -1)
        {
            if (entryToAdd is NonLeafNode &&
                nodeAddTo is NonLeafNode &&
                (nodeAddTo as NonLeafNode).Entries.First() is Leaf)
            {
                return(nodeAddTo);
            }

            if (entryToAdd is DataEntry &&
                nodeAddTo is Leaf)
            {
                return(nodeAddTo);
            }
            if (entryLevel == nodeAddTo.Level + 1)
            {
                if (entryToAdd is Leaf &&
                    nodeAddTo is NonLeafNode &&
                    !((nodeAddTo as NonLeafNode).Entries.First() is Leaf))
                {
                    return(ChooseSubTree(entryToAdd, nodeAddTo, ++entryLevel));
                }
                else
                {
                    return(nodeAddTo);
                }
            }
            NonLeafNode nlf = nodeAddTo as NonLeafNode;

            if (nlf.Entries.First() is Leaf)
            {
                var chosenEntryID = nlf.Entries//.AsParallel()
                                    .OrderBy(e => e.MBR.Area)
                                    .OrderBy(e => e.MBR.EnlargementSize(entryToAdd.MBR))
                                    .OrderBy(e =>
                {
                    return((e as Leaf).Entries
                           .Sum(e2 => e2.MBR.OverlapSize(entryToAdd.MBR)));
                })
                                    .Take(2)
                                    .First().ID;
                return(ChooseSubTree(entryToAdd, _nodesMap[chosenEntryID], entryLevel));
            }
            else
            {
                var chosenEntryID = nlf.Entries//.AsParallel()
                                    .OrderBy(e => e.MBR.Area)
                                    .OrderBy(e => e.MBR.EnlargementSize(entryToAdd.MBR))
                                    .First().ID;
                return(ChooseSubTree(entryToAdd, _nodesMap[chosenEntryID], entryLevel));
            }
        }