Пример #1
0
        public List <IComparable> GetLastRowFromTable(TableDefinition tableDefinition)
        {
            Stack <long> pointers = new Stack <long>();

            long dataPosition = tableDefinition.DataAddress;

            pointers.Push(dataPosition);

            while (PageIsFull(dataPosition, tableDefinition.GetRowSizeInBytes()))
            {
                dataPosition = PageLocationHelper.GetNextPagePointer(dataPosition);

                pointers.Push(dataPosition);
            }

            using (FileStream fs = new FileStream(Constants.FILE_NAME, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (BinaryReader binaryReader = new BinaryReader(fs))
                {
                    List <List <IComparable> > rowsFromLastPage = ReadDataFromPage(dataPosition, tableDefinition.ColumnDefinitions, binaryReader);

                    if (!rowsFromLastPage.Any())
                    {
                        //if there are no rows, then the last row is on the previous page
                        pointers.Pop(); //remove last pointer, which is a pointer to an empty page

                        long previousAddress = pointers.Pop();

                        rowsFromLastPage = ReadDataFromPage(previousAddress, tableDefinition.ColumnDefinitions, binaryReader);
                    }

                    return(rowsFromLastPage.Last());
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Checks if current page is full. If so, writes a pointer to the end of the page and
        /// returns next available writeable address.
        /// Otherwise, return current address
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        private void WritePointerIfLastObjectOnPage(long address, int objectSize)
        {
            long nextPageAddress = PageLocationHelper.GetNextDivisbleNumber(address, Constants.Page_Size);

            long load = address + (objectSize + Constants.Int64_Byte_Length);

            bool willBeLastObjectOnPage = load + objectSize >= nextPageAddress - Constants.Int64_Byte_Length;

            if (willBeLastObjectOnPage)
            {
                long nextPagePointer = GetNextUnclaimedDataPage();

                using (FileStream fileStream = File.Open(Constants.FILE_NAME, FileMode.Open, FileAccess.Write, FileShare.ReadWrite))
                {
                    using (BinaryWriter binaryWriter = new BinaryWriter(fileStream))
                    {
                        binaryWriter.BaseStream.Position = nextPageAddress - Constants.Int64_Byte_Length;

                        binaryWriter.Write(nextPagePointer);

                        binaryWriter.BaseStream.Position = nextPagePointer;

                        binaryWriter.Write((short)0);
                    }
                }
            }
        }
Пример #3
0
        public long GetPointerToNextPage(long pageAddress)
        {
            long pointerToNextPage = PageLocationHelper.GetNextDivisbleNumber(pageAddress, Constants.Page_Size)
                                     - Constants.Int64_Byte_Length;

            using (FileStream fs = new FileStream(Constants.FILE_NAME, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (BinaryReader binaryReader = new BinaryReader(fs))
                {
                    binaryReader.BaseStream.Position = pointerToNextPage;

                    long nextPageAddress = binaryReader.ReadInt64();

                    return(nextPageAddress);
                }
            }
        }
Пример #4
0
        public long GetFirstAvailableDataAddress(long dataStart, int objectSize)
        {
            while (PageIsFull(dataStart, objectSize))
            {
                dataStart = PageLocationHelper.GetNextPagePointer(dataStart);
            }

            using (FileStream fileStream = new FileStream(Constants.FILE_NAME, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                fileStream.Position = dataStart;

                using (BinaryReader binaryReader = new BinaryReader(fileStream))
                {
                    short numObjects = binaryReader.ReadInt16();

                    return(objectSize * numObjects + 2 + dataStart);//todo: use global 2 byte integer size
                }
            }
        }