예제 #1
0
        private void MoveUp(BNode <T, TKey> Crawler, TKey Key, T Value, int RightSibling)
        {
            if (!Crawler.Full)
            {
                Crawler.Insert(Key, Value, RightSibling);
                Crawler.DiskWrite(File, SizesNSpecialCharacters.HeaderSizeInBytes);
                return;
            }
            BNode <T, TKey> Sibling = new BNode <T, TKey>(Degree, FirstAvailablePointer, Crawler.Parent, TFactory, TKeyFactory);

            FirstAvailablePointer++;
            TKey UpwardMovingKey   = TKeyFactory.CreateNull();
            T    UpwardMovingValue = TFactory.CreateNull();

            Crawler.Split(Key, Value, RightSibling, Sibling, ref UpwardMovingKey, UpwardMovingValue);
            BNode <T, TKey> Child = null;

            for (int i = 0; i < Sibling.ChildrenPointers.Count; i++)
            {
                if (Sibling.ChildrenPointers[i] != int.MinValue)
                {
                    Child = BNode <T, TKey> .DiskRead(File, Degree, Sibling.ChildrenPointers[i], TFactory, TKeyFactory);

                    Child.Parent = Sibling.Pointer;
                    Child.DiskWrite(File, SizesNSpecialCharacters.HeaderSizeInBytes);
                }
                else
                {
                    break;
                }
            }
            if (Crawler.Parent == int.MinValue)
            {
                BNode <T, TKey> NewRoot = new BNode <T, TKey>(Degree, FirstAvailablePointer, int.MinValue, TFactory, TKeyFactory);
                FirstAvailablePointer++;
                NewRoot.ChildrenPointers[0] = Crawler.Pointer;
                NewRoot.Insert(UpwardMovingKey, UpwardMovingValue, Sibling.Pointer);
                Crawler.Parent = NewRoot.Pointer;
                Sibling.Parent = NewRoot.Pointer;
                RootPointer    = NewRoot.Pointer;
                NewRoot.DiskWrite(File, SizesNSpecialCharacters.HeaderSizeInBytes);
                Crawler.DiskWrite(File, SizesNSpecialCharacters.HeaderSizeInBytes);
                Sibling.DiskWrite(File, SizesNSpecialCharacters.HeaderSizeInBytes);
            }
            else
            {
                Crawler.DiskWrite(File, SizesNSpecialCharacters.HeaderSizeInBytes);
                Sibling.DiskWrite(File, SizesNSpecialCharacters.HeaderSizeInBytes);

                BNode <T, TKey> Parent = BNode <T, TKey> .DiskRead(File, Degree, Crawler.Parent, TFactory, TKeyFactory);

                MoveUp(Parent, UpwardMovingKey, UpwardMovingValue, Sibling.Pointer);
            }
        }
예제 #2
0
        public BTree(int Degree, string FilePath, IFixedLengthFactory <T> ContentFactory, IFixedLengthFactory <TKey> KeyFactory)
        {
            FileName    = FilePath;
            TFactory    = ContentFactory;
            TKeyFactory = KeyFactory;
            File        = new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite,
                                         FileShare.Read);
            RootPointer           = FileManagment.ReadLine(File, 0);
            FirstAvailablePointer = FileManagment.ReadLine(File, 1);
            this.Degree           = FileManagment.ReadLine(File, 2);
            if (FirstAvailablePointer == int.MinValue)
            {
                FirstAvailablePointer = 0;
            }

            if (this.Degree == int.MinValue)
            {
                this.Degree = Degree;
            }
            if (RootPointer == int.MinValue)
            {
                BNode <T, TKey> Root = new BNode <T, TKey>(this.Degree, FirstAvailablePointer, int.MinValue,
                                                           TFactory, TKeyFactory);
                FirstAvailablePointer++;
                RootPointer = Root.Pointer;
                Root.DiskWrite(File, SizesNSpecialCharacters.HeaderSizeInBytes);
            }
            UpdateHeader();
        }
예제 #3
0
        private void DeleteFromInternalNode(FileStream File, int i)
        {
            TKey            Key = Keys[i];
            BNode <T, TKey> y   = DiskRead(File, Degree, ChildrenPointers[i], ContentFactory, KeyFactory);

            if (y.N >= (Degree / 2 - 1))
            {
                TKey KPrime = y.LeftGreatest(File);
                y.Delete(File, KPrime);
                Keys[i] = KPrime;
            }
            else
            {
                BNode <T, TKey> z = DiskRead(File, Degree, ChildrenPointers[i + 1], ContentFactory, KeyFactory);

                if (z.N >= ((Degree / 2) - 1))
                {
                    TKey KPrime = z.RightLowest(File);
                    z.Delete(File, KPrime);
                    Keys[i] = KPrime;
                }
                else
                {
                    y.Keys[y.N] = Key;
                    for (int j = 0; j < z.N; j++)
                    {
                        y.Keys[y.N + j + 1] = z.Keys[j];
                    }
                    if (!y.Leaf)
                    {
                        for (int j = 0; j <= z.N; j++)
                        {
                            y.Keys[y.N + j + 1] = z.Keys[j];
                        }
                    }

                    for (int j = i + 1; j < N; j++)
                    {
                        Keys[j - 1]         = Keys[j];
                        ChildrenPointers[j] = ChildrenPointers[j + 1];
                    }
                    Keys[N - 1]         = KeyFactory.CreateNull();
                    ChildrenPointers[N] = SizesNSpecialCharacters.NullPointer;

                    DiskWrite(File, 65);
                    y.DiskWrite(File, 65);
                    z.DiskWrite(File, 65);
                    y.Delete(File, Key);
                }
            }

            DiskWrite(File, 65);
        }
예제 #4
0
        private void EnsureFullEnough(FileStream File, int i)
        {
            BNode <T, TKey> Children = DiskRead(File, Degree, ChildrenPointers[0], ContentFactory, KeyFactory);

            if (Children.N < (Degree / 2 - 1))
            {
                BNode <T, TKey> LeftSibling  = DiskRead(File, Degree, ChildrenPointers[i - 1], ContentFactory, KeyFactory);
                int             LeftSiblingN = LeftSibling.N;

                if (i > 0)
                {
                    LeftSibling = DiskRead(File, Degree, ChildrenPointers[i - 1], ContentFactory, KeyFactory);
                }
                else
                {
                    LeftSibling  = null;
                    LeftSiblingN = 0;
                }
                if (N >= (Degree / 2 - 1))
                {
                    for (int j = Children.N - 1; j >= 0; j--)
                    {
                        Children.Keys[j + 1] = Children.Keys[j];
                    }
                    if (!Children.Leaf)
                    {
                        for (int j = Children.N; j >= 0; j--)
                        {
                            Children.ChildrenPointers[j + 1] = Children.ChildrenPointers[j];
                        }
                    }
                    Children.Keys[0] = Keys[i - 1];
                    Keys[i - 1]      = LeftSibling.Keys[LeftSiblingN - 1];
                    LeftSibling.Keys[LeftSiblingN - 1] = KeyFactory.CreateNull();

                    if (!Children.Leaf)
                    {
                        Children.ChildrenPointers[0] = LeftSibling.ChildrenPointers[LeftSiblingN];
                        LeftSibling.ChildrenPointers[LeftSiblingN] = SizesNSpecialCharacters.NullPointer;
                    }
                    DiskWrite(File, 65);
                    Children.DiskWrite(File, 65);
                    LeftSibling.DiskWrite(File, 65);
                }
                else
                {
                    BNode <T, TKey> RightSibling;
                    int             RightSiblingN;

                    if (i < N)
                    {
                        RightSibling  = DiskRead(File, Degree, ChildrenPointers[i + 1], ContentFactory, KeyFactory);
                        RightSiblingN = RightSibling.N;
                    }
                    else
                    {
                        RightSibling  = null;
                        RightSiblingN = 0;
                    }

                    if (RightSiblingN >= (Degree / 2 - 1))
                    {
                        Children.Keys[Children.N] = Keys[i];
                        Keys[i] = RightSibling.Keys[0];

                        if (!Children.Leaf)
                        {
                            Children.ChildrenPointers[Children.N] = RightSibling.ChildrenPointers[0];
                        }

                        for (int j = 1; j < RightSiblingN; j++)
                        {
                            RightSibling.Keys[j - 1] = RightSibling.Keys[j];
                        }
                        RightSibling.Keys[RightSiblingN - 1] = KeyFactory.CreateNull();
                        if (!RightSibling.Leaf)
                        {
                            for (int j = 1; j <= RightSiblingN; j++)
                            {
                                RightSibling.ChildrenPointers[j - 1] = RightSibling.ChildrenPointers[j];
                            }
                            RightSibling.ChildrenPointers[RightSiblingN] = SizesNSpecialCharacters.NullPointer;
                        }
                        DiskWrite(File, 65);
                        Children.DiskWrite(File, 65);
                        RightSibling.DiskWrite(File, 65);
                    }
                    else
                    {
                        if (LeftSiblingN > 0)
                        {
                            for (int j = Children.N - 1; j >= 0; j--)
                            {
                                Children.Keys[j + (Degree / 2 - 1)] = Children.Keys[j];
                            }
                            if (!Children.Leaf)
                            {
                                for (int j = Children.N; j >= 0; j--)
                                {
                                    Children.ChildrenPointers[j + (Degree / 2 - 1)] = Children.ChildrenPointers[j];
                                }
                            }
                            for (int j = 0; j < LeftSiblingN; j++)
                            {
                                Children.Keys[j]    = LeftSibling.Keys[j];
                                LeftSibling.Keys[j] = KeyFactory.CreateNull();
                            }
                            if (!Children.Leaf)
                            {
                                for (int j = 0; j < LeftSiblingN; j++)
                                {
                                    Children.ChildrenPointers[j]    = LeftSibling.ChildrenPointers[j];
                                    LeftSibling.ChildrenPointers[j] = SizesNSpecialCharacters.NullPointer;
                                }
                            }

                            Children.Keys[(Degree / 2 - 1)] = Keys[i - 1];

                            for (int j = i; j < N; j++)
                            {
                                Keys[j - 1]             = Keys[j];
                                ChildrenPointers[j - 1] = ChildrenPointers[j];
                            }
                            ChildrenPointers[N - 1] = ChildrenPointers[N];
                            Keys[N - 1]             = KeyFactory.CreateNull();
                            ChildrenPointers[N]     = SizesNSpecialCharacters.NullPointer;

                            DiskWrite(File, 65);
                            Children.DiskWrite(File, 65);
                        }
                        else
                        {
                            for (int j = 0; j < RightSiblingN; j++)
                            {
                                Children.Keys[j + Children.N + 1] = RightSibling.Keys[j];
                                RightSibling.Keys[j] = KeyFactory.CreateNull();
                            }
                            if (!Children.Leaf)
                            {
                                for (int j = 0; j <= RightSiblingN; j++)
                                {
                                    Children.ChildrenPointers[j + Children.N + 1] = RightSibling.ChildrenPointers[j];
                                    RightSibling.ChildrenPointers[j] = SizesNSpecialCharacters.NullPointer;
                                }
                            }

                            Children.Keys[(Degree / 2 - 1) - 1] = Keys[i];

                            for (int j = i + 1; j < N; j++)
                            {
                                Keys[j - 1]         = Keys[j];
                                ChildrenPointers[j] = ChildrenPointers[j + 1];
                            }
                            Keys[N - 1]         = KeyFactory.CreateNull();
                            ChildrenPointers[N] = SizesNSpecialCharacters.NullPointer;

                            RightSibling.DiskWrite(File, 65);
                            DiskWrite(File, 65);
                            Children.DiskWrite(File, 65);
                        }
                    }
                }
            }
        }