Exemple #1
0
        // find whether there's already a record with given key in file
        public Tuple <bool, long, long> FindKey(long key)
        {
            Tuple <bool, long, long, long> address = FindInIndex(key);

            // try to find on which page could possibly be that record
            if (address == null || address.Item1 == false)
            {
                return(new Tuple <bool, long, long>(false, -1, -1));
            }

            long     pageAddress = address.Item3;
            FilePage filePage    = null;

            while ((filePage = MainReader.ReadPage(pageAddress++)) != null)
            {
                for (int i = filePage.Entries.Count - 1; i >= 0; i--)
                {
                    if (filePage.Entries[i].Item1.Key == key) // if record is found
                    {
                        return(new Tuple <bool, long, long>(true, filePage.Address, i));
                    }
                    if (filePage.Entries[i].Item1.Key < key && filePage.Entries[i].Item2 != -1)
                    // if some record has overflow pointer which can possibly be given record
                    {
                        Tuple <bool, long, long> search = FindKeyInOverflowChain(filePage.Entries[i].Item2, key);
                        // look for the key in overflow chain
                        if (search.Item1)
                        {
                            return(search);
                        }
                    }
                }
            }
            return(new Tuple <bool, long, long>(false, -1, -1)); // not found
        }
Exemple #2
0
        //todo
        public void Reorganize()
        {
            Console.WriteLine("###REORGANIZATION###");
            var NewMainReader = new MainReader("newmain", MainPageSize, Mode.New);
            var NewMainWriter = new MainWriter("newmain", MainPageSize, Mode.New);

            TempLong = OverflowAddress;
            ResetVariables();
            AllocateEmptyPageAtTheEnd(ref NewMainWriter);
            MainPages++;
            FilePage             newPage = NewMainReader.ReadNextPage();
            Tuple <Record, long> entry;

            MainReader.Reader.Position = 0;
            //MainReader._count = false;

            while ((entry = MainReader.ReadNextEntryWithChaining()) != null)
            {
                if (entry.Item1.Key == long.MaxValue)
                {
                    continue;
                }
                if (entry.Item1.Deleted)
                {
                    continue;
                }
                if (newPage.Count >= Alpha * MainPageSize)
                {
                    // insert new element to index
                    // allocate new page

                    NewMainWriter.WritePage(newPage);
                    AllocateEmptyPageAtTheEnd(ref NewMainWriter);
                    newPage = NewMainReader.ReadNextPage();
                    MainPages++;
                    if (entry.Item1.Key != long.MaxValue)
                    {
                        IndexUnit.Entries.Add(new Tuple <long, long>(entry.Item1.Key, MainPages - 1));
                    }
                }

                newPage.Entries[(int)newPage.Count++] = new Tuple <Record, long>(entry.Item1, -1);
                MainRecordCount++;
            }
            NewMainWriter.WritePage(newPage);
            OverflowAddress = NewMainWriter.Writer.Position;
            AllocateEmptyPageAtTheEnd(ref NewMainWriter); // allocate overflow
            OverflowPages++;
            IndexUnit.Sort();
            IndexUnit.WriteIndex();
            MetaData.Save();
            MainReader.Dispose();
            MainWriter.Dispose();
            NewMainReader.Dispose();
            NewMainWriter.Dispose();
            File.Delete(_filePath);
            File.Move("newmain", _filePath);
            MainReader = new MainReader(_filePath, MainPageSize, Mode.Read);
            MainWriter = new MainWriter(_filePath, MainPageSize, Mode.Read);
        }
Exemple #3
0
        public void Remove(long key)
        {
            if (key <= 0)
            {
                Console.WriteLine("Cannot remove that record");
                return;
            }
            Tuple <bool, long, long> found = FindKey(key);

            if (!found.Item1)
            {
                Console.WriteLine("No such record");
                return;
            }
            FilePage page = MainReader.ReadPage(found.Item2);

            for (int i = 0; i < page.Count; i++)
            {
                if (page.Entries[i].Item1.Key == key)
                {
                    page.Entries[i].Item1.Deleted = true;
                    MainWriter.WritePage(page);
                    MetaData.Save();
                    break;
                }
            }
        }
Exemple #4
0
        private FilePage PageFromBytes(byte[] arr)
        {
            var page = new FilePage {
                Count = BitConverter.ToInt64(arr, 0)
            };
            var recList = new List <Tuple <Record, long> >();

            for (int i = 8; i < arr.Length; i += 41)
            {
                bool del = BitConverter.ToBoolean(arr, i);
                long k   = BitConverter.ToInt64(arr, i + 1);
                long a   = BitConverter.ToInt64(arr, i + 1 + 8);
                long b   = BitConverter.ToInt64(arr, i + 1 + 8 * 2);
                long c   = BitConverter.ToInt64(arr, i + 1 + 8 * 3);
                long l   = BitConverter.ToInt64(arr, i + 1 + 8 * 4);
                recList.Add(new Tuple <Record, long>(new Record(k, a, b, c, del), l));
            }

            for (int i = 0; i < recList.Count; ++i)
            {
                page.Entries[i] = recList[i];
            }

            return(page);
        }
Exemple #5
0
        private void AllocateEmptyPageAtTheEnd(ref MainWriter mw)
        {
            mw.Writer.Position = mw.Writer.Length;
            var page = new FilePage {
                Address = MainReader.PageNumberFromAddress(mw.Writer.Position)
            };

            mw.WritePage(page);
        }
Exemple #6
0
 public void WritePage(FilePage filePage)
 {
     _lastPageNumber = filePage.Address;
     LastPage        = filePage;
     byte[] buffer = FilePageToBytes(filePage).ToArray();
     Writer.Position = PageByteAddress(_lastPageNumber);
     Writer.Write(buffer, 0, _pageSizeInBytes);
     Writer.Flush();
     if (_count)
     {
         Program.MainWrites++;
     }
 }
Exemple #7
0
        private IEnumerable <byte> FilePageToBytes(FilePage fp)
        {
            byte[]             cnt = BitConverter.GetBytes(fp.Count);
            IEnumerable <byte> x   = new Byte[0];

            x = x.Concat(cnt);
            for (int i = 0; i < _pageSize; ++i)
            {
                x = x.Concat(fp.Entries[i].Item1.AsBytes());
                x = x.Concat(BitConverter.GetBytes(fp.Entries[i].Item2));
            }
            return(x);
        }
Exemple #8
0
        public FilePage ReadPage(long page)
        {
            if (_eof)
            {
                return(LastPage);
            }
            if (page == LastPageNumber)
            {
                return(LastPage);
            }

            //Reader.Position = PageByteAddress(page);

            var buffer = new byte[_pageSizeInBytes];

            try
            {
                Reader.Position = PageByteAddress(page);
                int bytesRead = Reader.Read(buffer, 0, _pageSizeInBytes);
                if (bytesRead <= 0)
                {
                    return(null);
                }
                if (bytesRead < _pageSizeInBytes)
                {
                    _eof = true;
                    //throw new PageFaultException();
                }
                FilePage tmpPage = PageFromBytes(buffer);
                tmpPage.Address = page;
                if (_count)
                {
                    Program.MainReads++;
                }
                LastPage         = tmpPage;
                LastPageNumber   = page;
                LastRecordNumber = -1L;
                NextRecordNumber = -1L;
                return(tmpPage);
            }
            catch (ArgumentException)
            {
                return(null);
            }
            catch (IOException)
            {
                return(null);
            }
        }
Exemple #9
0
        public Tuple <Record, long> ReadNextEntryWithChaining()
        {
            if (NextRecordNumber != -1)
            {
                return(ReadEntry(NextRecordNumber));
            }
            long page = _counter / _pageSize;

            if (page == PageNumberFromAddress(Index.TempLong))
            {
                return(null);
            }
            var offset = (int)(_counter++ % _pageSize);

            if (page == LastPageNumber)
            {
                LastRecordNumber = offset;
                Tuple <Record, long> ret = LastPage.Entries[offset];
                if (ret.Item2 != -1)
                {
                    NextRecordNumber = ret.Item2;
                }
                else
                {
                    NextRecordNumber = -1;
                }
                return(ret);
            }
            FilePage newPage = ReadPage(page);

            if (newPage == null)
            {
                return(null);
            }

            LastRecordNumber = offset;
            Tuple <Record, long> returning = newPage.Entries[offset];

            if (returning.Item2 != -1)
            {
                NextRecordNumber = returning.Item2;
            }
            else
            {
                NextRecordNumber = -1;
            }
            return(returning);
        }
Exemple #10
0
        public void Update(Record r)
        {
            Tuple <bool, long, long> found = FindKey(r.Key);

            if (!found.Item1)
            {
                Console.WriteLine("No such record");
                return;
            }
            FilePage page = MainReader.ReadPage(found.Item2);

            page.Entries[(int)found.Item3].Item1.A = r.A;
            page.Entries[(int)found.Item3].Item1.B = r.B;
            page.Entries[(int)found.Item3].Item1.C = r.C;
            MainWriter.WritePage(page);
            MetaData.Save();
        }
Exemple #11
0
        private void Initialize()
        {
            //fill primary area with empty pages
            //set overflow area address
            long addrI = 0L, addrM = 0L;

            try
            {
                File.Delete("meta");
            }
            catch
            {
            }

            IndexUnit.Init(true);
            var firstMainPage = new FilePage {
                Address = addrM++, Count = 1
            };

            firstMainPage.Entries[0] = new Tuple <Record, long>(new Record(), -1);
            MainWriter.WritePage(firstMainPage);
            MainPages       = 1;
            MainRecordCount = 1;

            OverflowAddress         = MainWriter.Writer.Position;
            OverflowFirstPageNumber = MainReader.PageNumberFromAddress(MainWriter.Writer.Position);

            var newPage = new FilePage {
                Address = addrM
            };

            MainWriter.WritePage(newPage);

            OverflowEndAddress = MainWriter.Writer.Position;
            OverflowPages      = 1;
            MainWriter.Reset();

            Program.MainWrites = 0L;
            MetaData.Save();
            IndexUnit.WriteIndex();
        }
Exemple #12
0
        public Tuple <Record, long> ReadNextEntry()
        {
            long page   = _counter / _pageSize;
            var  offset = (int)(_counter++ % _pageSize);

            if (page == LastPageNumber)
            {
                LastRecordNumber = offset;
                Tuple <Record, long> ret = LastPage.Entries[offset];
                if (ret.Item2 != -1)
                {
                    NextRecordNumber = ret.Item2;
                }
                else
                {
                    NextRecordNumber = -1;
                }
                return(ret);
            }
            FilePage newPage = ReadPage(page);

            if (newPage == null)
            {
                return(null);
            }

            LastRecordNumber = offset;
            Tuple <Record, long> returning = newPage.Entries[offset];

            if (returning.Item2 != -1)
            {
                NextRecordNumber = returning.Item2;
            }
            else
            {
                NextRecordNumber = -1;
            }
            return(returning);
        }
Exemple #13
0
        // look for a key on given page
        public Tuple <bool, long, long> FindInFilePage(long page, long key)
        {
            FilePage filePage = MainReader.ReadPage(page);
            long     tmp      = 0;
            bool     flag     = false;

            for (int i = filePage.Entries.Count; i >= 0; i--)
            {
                if (filePage.Entries[i].Item1.Key == key)
                {
                    return(new Tuple <bool, long, long>(true, filePage.Address, i));
                }
                if (filePage.Entries[i].Item1.Key < key && filePage.Entries[i].Item2 != -1)
                {
                    tmp  = filePage.Entries[i].Item2;
                    flag = true;
                    break;
                }
            }
            if (flag)
            {
                while (tmp != -1)
                {
                    Tuple <Record, long> rec = MainReader.ReadEntry(tmp);
                    if (rec.Item1.Key == key)
                    {
                        return(new Tuple <bool, long, long>(true, MainReader.LastPage.Address,
                                                            MainReader.LastRecordNumber));
                    }
                    if (rec.Item1.Key < key && rec.Item2 != -1)
                    {
                        tmp = rec.Item2;
                    }
                }
            }
            return(new Tuple <bool, long, long>(false, -1, -1));
        }
Exemple #14
0
        public void Add(Record r)
        {
            long key = r.Key;
            Tuple <bool, long, long> found = FindKey(key);

            if (found.Item1)
            {
                Console.WriteLine("Key already added");
                return;
            }

            //look for a place in available pages in primary area
            //when there's no place, try to add in overflow area
            //when unable to do that, add to new page and to index
            Tuple <bool, long, long, long> index = FindInIndex(key);
            long indexPage = index.Item4;

            if (index.Item1 == false)
            {
                Console.WriteLine("No place");
            }
            FilePage newPage = MainReader.ReadPage(index.Item3);

            //add on current page
            if (newPage.Count < MainPageSize)
            {
                newPage.Entries[(int)newPage.Count] = new Tuple <Record, long>(r, -1);
                newPage.Count++;
                Sort(newPage);
                MainRecordCount++;
                MainWriter.WritePage(newPage);
                MetaData.Save();
            }
            else
            {
                //find a record to which link new record from overflow
                int      linkedRecordNumber = newPage.Entries.Count - 1;
                long     linkAddress        = 0;
                FilePage mainPageWithLink   = newPage;

                for (; linkedRecordNumber >= 0; linkedRecordNumber--)
                {
                    if (mainPageWithLink.Entries[linkedRecordNumber].Item1.Key < key)
                    {
                        break;
                    }
                }

                if (mainPageWithLink.Entries[linkedRecordNumber].Item2 != -1)
                // if a record in primary area already has pointer to overflow
                {
                    while (true)
                    {
                        long id = mainPageWithLink.Entries[linkedRecordNumber].Item2;
                        if (id == -1)
                        {
                            break;
                        }
                        Tuple <Record, long> newEntry = MainReader.ReadEntry(id);
                        if (key > newEntry.Item1.Key)
                        {
                            mainPageWithLink = MainReader.LastPage;
                            for (int i = 0; i < mainPageWithLink.Count; i++)
                            {
                                if (mainPageWithLink.Entries[i].Item1.Key == newEntry.Item1.Key)
                                {
                                    linkedRecordNumber = i;
                                }
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                MainReader.Reader.Position = OverflowAddress;
                FilePage overflowPage = MainReader.ReadNextPage(); // read next page from overflow area

                while (overflowPage != null && overflowPage.Count >= MainPageSize)
                {
                    // find a page with enough space to place a new record
                    overflowPage = MainReader.ReadNextPage();
                }

                if (overflowPage == null)
                {
                    AllocateEmptyPageAtTheEnd(ref MainWriter); // allocate new page for overflow area
                    overflowPage = MainReader.ReadNextPage();
                }
                if (overflowPage.Address == mainPageWithLink.Address)
                {
                    overflowPage = mainPageWithLink;
                }

                if (overflowPage.Count < MainPageSize)
                {
                    overflowPage.Entries[(int)overflowPage.Count] = new Tuple <Record, long>(r,
                                                                                             mainPageWithLink.Entries[linkedRecordNumber].Item2);
                    linkAddress = overflowPage.Address * MainPageSize + overflowPage.Count;
                    overflowPage.Count++;
                    OverflowRecordCount++;
                    mainPageWithLink.Entries[linkedRecordNumber] =
                        new Tuple <Record, long>(mainPageWithLink.Entries[linkedRecordNumber].Item1, linkAddress);
                    MainWriter.WritePage(overflowPage);
                    MetaData.Save();
                }
                if (overflowPage.Address != mainPageWithLink.Address)
                {
                    MainWriter.WritePage(mainPageWithLink);
                }
                MetaData.Save();
            }
            if (OverflowRecordCount > 0.5 * MainRecordCount)
            {
                Reorganize();
            }
        }
Exemple #15
0
 public void Reset()
 {
     LastPage        = null;
     _lastPageNumber = -1;
     _eof            = false;
 }
Exemple #16
0
 public void Dispose()
 {
     Writer.Dispose();
     Writer   = null;
     LastPage = null;
 }
Exemple #17
0
 private void Sort(FilePage fp)
 {
     fp.Entries.Sort((x, y) => x.Item1.Key.CompareTo(y.Item1.Key));
 }
Exemple #18
0
 public void Dispose()
 {
     Reader.Dispose();
     Reader   = null;
     LastPage = null;
 }