Пример #1
0
 public DataPage GetDataPage(uint pageID)
 {
     if (pageID == Header.LastPageID) // Page does not exists in disk
     {
         var dataPage = new DataPage(pageID);
         return dataPage;
     }
     else
     {
         return PageFactory.GetDataPage(pageID, Reader, false);
     }
 }
Пример #2
0
        internal FileDBStream(Engine engine, Guid id)
        {
            _engine = engine;

            var indexNode = _engine.Search(id);
            if (indexNode != null)
            {
                _streamLength = indexNode.FileLength;
                _currentPage = PageFactory.GetDataPage(indexNode.DataPageID, engine.Reader, false);
                _info = new EntryInfo(indexNode);
            }
        }
Пример #3
0
        public static void ReadFromFile(DataPage dataPage, BinaryReader reader, bool onlyHeader)
        {
            // Seek the stream on first byte from data page
            long initPos = reader.Seek(Header.HEADER_SIZE + ((long)dataPage.PageID * BasePage.PAGE_SIZE));

            if (reader.ReadByte() != (byte)PageType.Data)
                throw new FileDBException("PageID {0} is not a Data Page", dataPage.PageID);

            dataPage.NextPageID = reader.ReadUInt32();
            dataPage.IsEmpty = reader.ReadBoolean();
            dataPage.DataBlockLength = reader.ReadInt16();

            // If page is empty or onlyHeader parameter, I don't read data content
            if (!dataPage.IsEmpty && !onlyHeader)
            {
                // Seek the stream at the end of page header
                reader.Seek(initPos + DataPage.HEADER_SIZE);

                // Read all bytes from page
                dataPage.DataBlock = reader.ReadBytes(dataPage.DataBlockLength);
            }
        }
Пример #4
0
        // Take a new data page on sequence and update the last
        public static DataPage GetNewDataPage(DataPage basePage, Engine engine)
        {
            if (basePage.NextPageID != uint.MaxValue)
            {
                PageFactory.WriteToFile(basePage, engine.Writer); // Write last page on disk

                var dataPage = PageFactory.GetDataPage(basePage.NextPageID, engine.Reader, false);

                engine.Header.FreeDataPageID = dataPage.NextPageID;

                if (engine.Header.FreeDataPageID == uint.MaxValue)
                    engine.Header.LastFreeDataPageID = uint.MaxValue;

                return dataPage;
            }
            else
            {
                var pageID = ++engine.Header.LastPageID;
                DataPage newPage = new DataPage(pageID);
                basePage.NextPageID = newPage.PageID;
                PageFactory.WriteToFile(basePage, engine.Writer); // Write last page on disk
                return newPage;
            }
        }
Пример #5
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            int bytesLeft = count;

            while (_currentPage != null && bytesLeft > 0)
            {
                int bytesToCopy = Math.Min(bytesLeft, _currentPage.DataBlockLength - _positionInPage);
                Buffer.BlockCopy(_currentPage.DataBlock, _positionInPage, buffer, offset, bytesToCopy);

                _positionInPage += bytesToCopy;
                bytesLeft -= bytesToCopy;
                offset += bytesToCopy;
                _streamPosition += bytesToCopy;

                if (_positionInPage >= _currentPage.DataBlockLength)
                {
                    _positionInPage = 0;

                    if (_currentPage.NextPageID == uint.MaxValue)
                        _currentPage = null;
                    else
                        _currentPage = PageFactory.GetDataPage(_currentPage.NextPageID, _engine.Reader, false);
                }
            }

            return count - bytesLeft;
        }
Пример #6
0
 public static DataPage GetDataPage(uint pageID, BinaryReader reader, bool onlyHeader)
 {
     var dataPage = new DataPage(pageID);
     ReadFromFile(dataPage, reader, onlyHeader);
     return dataPage;
 }
Пример #7
0
        public static void WriteToFile(DataPage dataPage, BinaryWriter writer)
        {
            // Seek the stream on first byte from data page
            long initPos = writer.Seek(Header.HEADER_SIZE + ((long)dataPage.PageID * BasePage.PAGE_SIZE));

            // Write data page header
            writer.Write((byte)dataPage.Type);
            writer.Write(dataPage.NextPageID);
            writer.Write(dataPage.IsEmpty);
            writer.Write(dataPage.DataBlockLength);

            // I will only save data content if the page is not empty
            if (!dataPage.IsEmpty)
            {
                // Seek the stream at the end of page header
                writer.Seek(initPos + DataPage.HEADER_SIZE);

                writer.Write(dataPage.DataBlock, 0, (int)dataPage.DataBlockLength);
            }
        }
Пример #8
0
        public static void InsertFile(IndexNode node, EntryInfo enInfo, Stream stream, Engine engine)
        {
            var buffer = new byte[DataPage.DATA_PER_PAGE];

            int      dataFreeInPage = DataPage.DATA_PER_PAGE;
            int      writePos       = 0;
            int      read           = 0;
            DataPage dataPage       = engine.GetDataPage(node.DataPageID);

            if (!dataPage.IsEmpty) // This is never to happend!!
            {
                throw new FileDBException("Page {0} is not empty", dataPage.PageID);
            }
            //-----------------------
            //write metadata
            //1. datetime of file
            DateTime filedtm = enInfo.FileDateTime;

            //--------------------------
            writePos = WriteByte(dataPage.DataBlock, 0, 1);                          //marker - 1
            writePos = WriteInt64(dataPage.DataBlock, writePos, filedtm.ToBinary()); //data part
            //--------------------------
            //2. long filename (if has long filename)
            //-----------------------
            if (enInfo.HasLongFileName)
            {
                //write full filename here
                byte[] longFileNameBuff = System.Text.Encoding.UTF8.GetBytes(enInfo.FileUrl);
                int    buffLen          = longFileNameBuff.Length;
                if (buffLen > 512)
                {
                    //for this version ***
                    throw new Exception("file name must not longer than 512 bytes");
                }
                writePos = WriteByte(dataPage.DataBlock, writePos, 2);                  //marker 2 long filename
                //--------
                writePos = WriteUInt16(dataPage.DataBlock, writePos, (ushort)buffLen);  //2 bytes length of buffer
                writePos = WriteBuffer(dataPage.DataBlock, writePos, longFileNameBuff); //buffer
                //--------
            }

            dataPage.IsEmpty         = false;
            dataPage.DataBlockLength = (short)writePos;
            dataFreeInPage          -= writePos;


            node.FileMetaDataLength = (ushort)writePos;
            //-----------------------
            bool isFirstRound = true;
            uint fileLength   = 0;

            while ((read = stream.Read(buffer, 0, dataFreeInPage)) > 0)
            {
                //if we have some data to write
                fileLength += (uint)read;
                if (!isFirstRound)
                {
                    dataPage = GetNewDataPage(dataPage, engine);
                    if (!dataPage.IsEmpty) // This is never to happend!!
                    {
                        throw new FileDBException("Page {0} is not empty", dataPage.PageID);
                    }
                }
                writePos                 = WriteBuffer(dataPage.DataBlock, writePos, buffer, read);
                dataPage.IsEmpty         = false;
                dataPage.DataBlockLength = (short)writePos;
                //----------------------------------------------
                //reset  for next
                dataFreeInPage = DataPage.DATA_PER_PAGE;
                writePos       = 0;
                isFirstRound   = false;
                //----------------------------------------------
            }


            // If the last page point to another one, i need to fix that
            if (dataPage.NextPageID != uint.MaxValue)
            {
                engine.Header.FreeDataPageID = dataPage.NextPageID;
                dataPage.NextPageID          = uint.MaxValue;
            }

            // Save the last page on disk
            PageFactory.WriteToFile(dataPage, engine.Writer);

            // Save on node index that file length
            node.FileLength = fileLength;
        }