void Initialise() { if ( F.Length == 0 ) // New file : create Root page. { Root = new IndexPage( Inf, null, Database ); AllocPageId( Root ); } else { PageAlloc = (long) ( ( F.Length + IndexPage.PageSize - 1 ) / IndexPage.PageSize ); Root = GetPage( 0 ); // Maybe could delay this until first use of the index ( as index may never be used at all ). } Saved = true; }
public bool Saved = false; // Indicates whether tree has been saved to disk. void Insert(IndexFile ixf, ref IndexFileRecord r) { if (Free == 0 && NodeAlloc == MaxNode) // Page is full, have to split it. { PageParent pp; if (this == ixf.Root) { pp = new PageParent(Inf, null, Database); ixf.AllocPageId(this); pp.FirstPage = PageId; ixf.Root = pp; ixf.PageMap[0] = pp; } else { pp = (PageParent)ixf.PageMap[ParentId]; } IndexPage left = Clone(); left.PageId = PageId; left.FirstPage = FirstPage; ixf.PageMap[PageId] = left; IndexPage right = Clone(); ixf.AllocPageId(right); var div = new IndexFileRecord(); // IndexFileRecord that divides page into left/right, will be inserted into parent page. Divide(left, right, ref div); right.FirstPage = div.Child; div.Child = right.PageId; pp.Insert(ixf, ref div); // Insert into either left or right depending on comparison with sv. (Compare(ref r, ref div) < 0 ? left : right).Insert(ref r, false); // Console.WriteLine( "Insert Split, NodeAlloc=" + NodeAlloc + " MaxNode=" + MaxNode + "ixf.PageAlloc=" + ixf.PageAlloc ); // Console.WriteLine( "Split div=" + div.ToString(ixf.Inf) ); // ixf.Dump(); } else { Insert(ref r, false); } }
public void PrepareToCommit() // Writes pages to the underlying file ( which will be fully buffered ). { if ( Saved ) return; // Save the pages. foreach ( G.KeyValuePair<long,IndexPage> pair in PageMap ) { IndexPage p = pair.Value; if ( !p.Saved ) { p.WriteHeader(); F.Position = (long)p.PageId * IndexPage.PageSize; // For last page, only write the amount actually used (so file size is minimised) F.Write( p.Data, 0, p.PageId == PageAlloc-1 ? p.Size() : IndexPage.PageSize ); p.Saved = true; } } Saved = true; }
public void AllocPageId( IndexPage p ) { p.PageId = PageAlloc++; PageMap[ p.PageId ] = p; }