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;
 }
Exemple #2
0
        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;
 }
Exemple #4
0
 public void AllocPageId( IndexPage p )
 {
   p.PageId = PageAlloc++;
   PageMap[ p.PageId ] = p;    
 }