Esempio n. 1
0
        //later avoid recursive
        PageIndexNodeBase <T> ReadTreePageStructure(int parent)
        {
            //first read the Int32 flag record
            var flags = reader.ReadInt32();

            //
            if (flags == 0)
            {
                //signal tree left or right is null
                return(null);
            }

            var thisPageNo = ++Index.NodePages;

            var pageType = flags & 0b011;

            switch (pageType)
            {
            case Consts.BTreePageNodeFlag:
                //read root
                var page = new PageIndexNode <T>(flags, thisPageNo, reader, KeyType);

                page.Left = ReadTreePageStructure(thisPageNo);

                page.Right = ReadTreePageStructure(thisPageNo);

                return(page);

            case Consts.BTreePageNodeItemsFlag:
                return(new PageIndexItems <T>(flags, thisPageNo, reader));

            default:
                throw new ArgumentException("Invalid database structure!");
            }
        }
Esempio n. 2
0
        internal IEnumerable <KeyValuePair <T, List <int> > > DumpTreeNodesInOrder(PageIndexNodeBase <T> root)
        {
            var stack = new Stack <PageIndexNodeBase <T> >();
            PageIndexNode <T> nodePage = null;

            //set current to root
            PageIndexNodeBase <T> current = root;

            IEnumerable <KeyValuePair <T, List <int> > > EnumerateOffsets(PageIndexItems <T> page)
            {
                //find from dictionary for fast search
                var metaPage = Index.IndexItems <T>()[page.Offset];

                if (metaPage != null)
                {
                    foreach (var ofs in metaPage.Items)
                    {
                        yield return(ofs);
                    }
                }
                else
                {
                    yield break;
                }
            }

            while (stack.Count > 0 || current != null)
            {
                if (current != null)
                {
                    //if it's a items page, return all it's values
                    if (current.Type == MetaIndexType.Items)
                    {
                        //find items page by its offset
                        foreach (var ofs in EnumerateOffsets(current as PageIndexItems <T>))
                        {
                            yield return(ofs);
                        }
                        //signal end
                        current = null;
                    }
                    else
                    {
                        //it's a node page, push current page
                        stack.Push(current);

                        //try to go Left
                        current = ((PageIndexNode <T>)current).Left;
                    }
                }
                else
                {
                    current = stack.Pop();
                    //return current node page items --first--

                    if (current.Type == MetaIndexType.Items)
                    {
                        //find items page by its offset
                        foreach (var ofs in EnumerateOffsets(current as PageIndexItems <T>))
                        {
                            yield return(ofs);
                        }
                        //signal end
                        current = null;
                    }
                    else
                    {
                        //it's a node page, return Key values, and try to go Right
                        nodePage = current as PageIndexNode <T>;
                        yield return(new KeyValuePair <T, List <int> >(nodePage.Key, nodePage.Values));

                        current = nodePage.Right;
                    }
                }
            }
        }