Beispiel #1
0
        IEnumerable <BTreePageItems <T> > GetNodeItemPages <T>(BTreePageBase <T> rootPage)
            where T : IComparable <T>
        {
            var stack = new Stack <BTreePageBase <T> >();

            stack.Push(rootPage);
            while (stack.Count > 0)
            {
                var item = stack.Pop();
                if (item.Type == BTreePageType.Collection)
                {
                    yield return(item as BTreePageItems <T>);
                }
                else
                {
                    var node = item as BTreePageNode <T>;

                    if (node.Right != null)
                    {
                        stack.Push(node.Right);
                    }

                    if (node.Left != null)
                    {
                        stack.Push(node.Left);
                    }
                }
            }
        }
Beispiel #2
0
        void StoreTreePage <T>(BTreePageBase <T> rootPage, io.BinaryWriter writer)
            where T : IComparable <T>
        {
            if (rootPage.IsLeaf)
            {
                //store id of left
                Int32 valueInt32 = Consts.BTreePageNodeItemsFlag;
                writer.Write(valueInt32);
                //offset
                /////////////////  TO BE USED AS AN ID //////////////////////////
                var leaf = rootPage as BTreePageItems <T>;
                writer.Write(leaf.Offset);
            }
            else
            {
                //store page node
                var buffer = rootPage.ToBuffer();
                writer.Write(buffer, 0, buffer.Length);

                //try to navigate left or right
                var node  = rootPage as BTreePageNode <T>;
                int empty = 0;
                if (node.Left == null)
                {
                    //signal, no left node
                    writer.Write(empty);
                    throw new ArgumentException($"Tree Node key:[{node.Root.Key}] has no left child");
                }
                else
                {
                    StoreTreePage <T>(node.Left, writer);
                }

                if (node.Right == null)
                {
                    //signal, no right node
                    writer.Write(empty);
                    throw new ArgumentException($"Tree Node key:[{node.Root.Key}] has no right child");
                }
                else
                {
                    StoreTreePage <T>(node.Right, writer);
                }
            }
        }
Beispiel #3
0
        void SaveBinaryIndex <T>(BTreePageBase <T> rootPage, DbColumn index)
            where T : IComparable <T>
        {
            if (rootPage == null)
            {
                return;
            }
            var pageCount = rootPage.ChildrenCount;

            Console.WriteLine($"   saving ({pageCount}) page(s)");

            //update column tree page count
            index.NodePages = pageCount;
            index.Table.Database.Modified = true;

            string indexfilepath = io.Path.Combine(Database.BinaryPath, $"{index.Indexer}");

            //page with items .bin
            //this where the main info is
            var indexBinFilePath = indexfilepath + ".bin";

            using (var writer = new io.BinaryWriter(io.File.Create(indexBinFilePath)))
            {
                var collectionPage = GetNodeItemPages <T>(rootPage).ToList();

                //update column item page count
                index.ItemPages = collectionPage.Count;

                //MAIN HEADER

                Int32 pageCollectionCount = collectionPage.Count;
                //write amount of pages
                writer.Write(pageCollectionCount);

                //write index key type
                Int32 keyType = (int)index.TypeEnum;
                writer.Write(keyType);

                //pages
                //sizeof: pageCollectionCount, keyType
                var offset = DbGenerator.ItemsPageStart;                   // 8;
                foreach (var page in collectionPage)
                {
                    page.Offset = offset;
                    //save page
                    var buffer = page.ToBuffer();
                    //
                    offset += buffer.Length;
                    //
                    writer.Write(buffer, 0, buffer.Length);
                }
            }

            //tree page indexer .index
            //this is a light in-memory tree structure for fast search
            using (var writer = new io.BinaryWriter(io.File.Create(indexfilepath)))
            {
                Int32 valueInt32 = 0;
                //write Index main Header
                PageIndexTreeHeader header = new PageIndexTreeHeader();
                //
                header.Value0 = 0;
                //page count
                header.PageCount = pageCount;
                //index.Index
                header.ColumnIndex = index.Index;

                //index.Unique
                //index.Key
                valueInt32 =
                    (index.Unique ? Consts.IndexHeaderIsUnique : 0) |
                    (index.Key ? Consts.IndexHeaderIsKey : 0) |
                    (rootPage.IsLeaf ? Consts.IndexHeaderIsLeaf : 0);

                //index.Type
                //valueInt32 = valueInt32 << 8;
                valueInt32  |= (byte)index.TypeEnum;
                header.Flags = valueInt32;

                //write Header
                byte[] buffer = header.ToByteArray();
                writer.Write(buffer, 0, buffer.Length);

                //test
                var bin = Convert.ToString(header.Flags, 2);

                //write page tree
                if (!rootPage.IsLeaf)
                {
                    StoreTreePage <T>(rootPage, writer);
                }
            }
        }