//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!"); } }
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; } } } }