Пример #1
0
        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);
        }
Пример #2
0
        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;
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        // 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++;
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        // 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;
            }
        }