private static void Merge(Page A, Page B, RecordMatcher Comparer) { List <Record> x = new List <Record>(); int ptrA = 0, ptrB = 0; while (ptrA < A.Count && ptrB < B.Count) { if (Comparer.Compare(A.Cache[ptrA], B.Cache[ptrB]) < 0) { x.Add(A.Cache[ptrA]); ptrA++; } else { x.Add(B.Cache[ptrB]); ptrB++; } } while (ptrA < A.Count) { x.Add(A.Cache[ptrA]); ptrA++; } while (ptrB < B.Count) { x.Add(B.Cache[ptrB]); ptrB++; } A.Cache = x.GetRange(0, A.Count); B.Cache = x.GetRange(A.Count, B.Count); }
public static void Distinct(Table Element, RecordMatcher Comparer) { // Check if the table is a heap // if (!(Element is HeapTable)) { throw new Exception("Can only sort a HeapTable"); } if (Element.Header.IndexHeaders.Count != 0) { throw new Exception("Can not sort a table with indexes"); } // Step 1: create a shell // Table t = Element.Host.CreateTempTable(Element.Columns); // Step 4: write to the shell // using (RecordWriter Writer = t.OpenWriter()) { Distinct(Element, Writer, Comparer); } // Step 5: drop the table // string dir = Element.Header.Directory, name = Element.Header.Name; Drop(Element.Host, Element.Key); // Step 6: rename the table // Rename(t, dir, name); // Step 7: reset Element's header // Element.Header.RecordCount = t.RecordCount; Element.Header.PageCount = t.PageCount; Element.Header.OriginPageID = t.OriginPageID; Element.Header.TerminalPageID = t.TerminalPageID; }
/// <summary> /// Buffers a block of pages /// </summary> /// <param name="Header"></param> /// <param name="PageOffset"></param> /// <param name="PageCount"></param> /// <returns></returns> internal static List <Page> BufferBlock(TableHeader Header, int PageOffset, int PageCount) { long Offset = TableHeader.SIZE + (long)(PageOffset) * (long)Header.PageSize; long ByteCount = (long)PageCount * (long)Header.PageSize; if (ByteCount > (long)int.MaxValue) { throw new IndexOutOfRangeException("Cannot read more than 2gb into memory at once"); } byte[] b = new byte[ByteCount]; using (FileStream fs = File.Open(Header.Path, FileMode.Open, FileAccess.Read, FileShare.None)) { fs.Position = Offset; fs.Read(b, 0, (int)ByteCount); } RecordMatcher matcher = new RecordMatcher(Header.ClusterKey); long Location = 0; List <Page> pages = new List <Page>(); for (int i = 0; i < PageCount; i++) { Page p = Page.Read2(b, Location); if (p.PageType == Page.SORTED_PAGE_TYPE) { p = new SortedPage(p, matcher); } Location += Header.PageSize; pages.Add(p); } return(pages); }
// Sort support // private static void Sort(Page Element, RecordMatcher Comparer) { if (Element.PageType != Page.BASE_PAGE_TYPE) { throw new ArgumentException("Can only sort a base page"); } Element.Cache.Sort(Comparer); Element.Version++; }
public static void Sort(Table Element, RecordMatcher Comparer) { // Check that this is a heap table // if (!(Element is HeapTable)) { throw new Exception("Can only sort heap tables"); } if (Element.Header.IndexHeaders.Count != 0) { throw new Exception("Cannot sort a table with indexes"); } // Sort each element // SortEach(Element, Comparer); // Merge sort // Table.PageWalker x = new Table.PageWalker(Element); Table.PageWalker y = new Table.PageWalker(Element); while (x.CanAdvance) { // Get x's page // Page A = x.SelectNext(); // Break if we on the last page // if (A.NextPageID == -1) { break; } // Open a new page walker that starts at the next page // y.ToPage(A.NextPageID); // Loop through y // while (y.CanAdvance) { // Get the second page // Page B = y.SelectNext(); // Merge // Merge(A, B, Comparer); // Set B // Element.SetPage(B); } // A is final at this point // Element.SetPage(A); } }
private static void SortEach(Table Element, RecordMatcher Comparer) { if (Element.Header.ClusterKey.Count != 0) { throw new Exception("Can only sort a heap table"); } if (Element.RecordCount == 0) { return; } Table.PageWalker walker = new Table.PageWalker(Element); while (walker.CanAdvance) { Page p = walker.SelectNext(); Sort(p, Comparer); Element.SetPage(p); } }
// Distinct Support // public static void Distinct(Table Element, RecordWriter Writer, RecordMatcher Comparer) { // Check if the table is a heap // if (!(Element is HeapTable)) { throw new Exception("Can only sort a HeapTable"); } if (Element.Header.IndexHeaders.Count != 0) { throw new Exception("Can not sort a table with indexes"); } // Step 1: sort table // Sort(Element, Comparer); // Step 2: create a shell // //Table t = Element.Host.CreateTempTable(Element.Columns); // Step 3: open a reader // RecordReader rr = Element.OpenReader(); // Step 4: write to the shell // Record lag = null; while (rr.CanAdvance) { Record current = rr.ReadNext(); if (lag == null) { Writer.Insert(current); } else if (Comparer.Compare(lag, current) != 0) { Writer.Insert(current); } lag = current; } }