Пример #1
0
        private void Connect(string fileName, FileAccess fileAccess)
        {
            if (!File.Exists(fileName))
                FileDB.CreateEmptyFile(fileName);

            // Não permite acesso somente gravação (transforma em leitura/gravação)
            var fa = fileAccess == FileAccess.Write || fileAccess == FileAccess.ReadWrite ? FileAccess.ReadWrite : FileAccess.Read;

            _fileStream = new FileStream(fileName, FileMode.Open, fa, FileShare.ReadWrite, (int)BasePage.PAGE_SIZE, FileOptions.None);

            _engine = new Engine(_fileStream);
        }
Пример #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
        private static IndexNode BinaryInsertNode(IndexLink baseLink, IndexNode baseNode, EntryInfo entry, Engine engine)
        {
            // Must insert my new nodo
            var pageIndex = engine.GetFreeIndexPage();
            var newNode = pageIndex.Nodes[pageIndex.NodeIndex];

            baseLink.PageID = pageIndex.PageID;
            baseLink.Index = pageIndex.NodeIndex;

            newNode.UpdateFromEntry(entry);
            newNode.DataPageID = DataFactory.GetStartDataPageID(engine);

            if (pageIndex.PageID != baseNode.IndexPage.PageID)
                engine.CacheIndexPage.AddPage(baseNode.IndexPage, true);

            engine.CacheIndexPage.AddPage(pageIndex, true);

            return newNode;
        }
Пример #4
0
        public static void InsertFile(IndexNode node, Stream stream, Engine engine)
        {
            DataPage dataPage = null;
            var buffer = new byte[DataPage.DATA_PER_PAGE];
            uint totalBytes = 0;

            int read = 0;
            int dataPerPage = (int)DataPage.DATA_PER_PAGE;

            while ((read = stream.Read(buffer, 0, dataPerPage)) > 0)
            {
                totalBytes += (uint)read;

                if (dataPage == null) // First read
                    dataPage = engine.GetPageData(node.DataPageID);
                else
                    dataPage = GetNewDataPage(dataPage, engine);

                if (!dataPage.IsEmpty) // This is never to happend!!
                    throw new FileDBException("Page {0} is not empty", dataPage.PageID);

                Array.Copy(buffer, dataPage.DataBlock, read);
                dataPage.IsEmpty = false;
                dataPage.DataBlockLength = (short)read;
            }

            // 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;
            }

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

            // Save on node index that file length
            node.FileLength = totalBytes;
        }
Пример #5
0
        public static uint GetStartDataPageID(Engine engine)
        {
            if (engine.Header.FreeDataPageID != uint.MaxValue) // I have free page inside the disk file. Use it
            {
                // Take the first free data page
                var startPage = PageFactory.GetDataPage(engine.Header.FreeDataPageID, engine.Reader, true);

                engine.Header.FreeDataPageID = startPage.NextPageID; // and point the free page to new free one

                // If the next page is MAX, fix too LastFreeData

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

                return startPage.PageID;
            }
            else // Don't have free data pages, create new one.
            {
                engine.Header.LastPageID++;
                return engine.Header.LastPageID;
            }
        }
Пример #6
0
        public static IndexNode BinaryInsert(EntryInfo target, IndexNode baseNode, Engine engine)
        {
            var dif = baseNode.ID.CompareTo(target.ID);

            if (dif == 1) // > Maior (Right)
            {
                if (baseNode.Right.IsEmpty)
                    return BinaryInsertNode(baseNode.Right, baseNode, target, engine);
                else
                    return BinaryInsert(target, GetChildIndexNode(baseNode.Right, engine), engine);
            }
            else if (dif == -1) // < Menor (Left)
            {
                if (baseNode.Left.IsEmpty)
                    return BinaryInsertNode(baseNode.Left, baseNode, target, engine);
                else
                    return BinaryInsert(target, GetChildIndexNode(baseNode.Left, engine), engine);
            }
            else
            {
                throw new FileDBException("Same GUID?!?");
            }
        }
Пример #7
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;
            }
        }
Пример #8
0
        public static IndexNode BinarySearch(Guid target, IndexNode baseNode, Engine engine)
        {
            var dif = baseNode.ID.CompareTo(target);

            if (dif == 1) // > Maior (Right)
            {
                if (baseNode.Right.IsEmpty) // If there no ones on right, GUID not found
                    return null;
                else
                    return BinarySearch(target, GetChildIndexNode(baseNode.Right, engine), engine); // Recursive call on right node
            }
            else if (dif == -1) // < Menor (Left)
            {
                if (baseNode.Left.IsEmpty) // If there no ones on left, GUID not found
                    return null;
                else
                    return BinarySearch(target, GetChildIndexNode(baseNode.Left, engine), engine); // Recursive call on left node
            }
            else
            {
                // Found it
                return baseNode;
            }
        }
Пример #9
0
 internal DebugFile(Engine engine)
 {
     _engine = engine;
 }
Пример #10
0
        public static void ReadFile(IndexNode node, Stream stream, Engine engine)
        {
            var dataPage = PageFactory.GetDataPage(node.DataPageID, engine.Reader, false);

            while (dataPage != null)
            {
                stream.Write(dataPage.DataBlock, 0, dataPage.DataBlockLength);

                if (dataPage.NextPageID == uint.MaxValue)
                    dataPage = null;
                else
                    dataPage = PageFactory.GetDataPage(dataPage.NextPageID, engine.Reader, false);
            }
        }
Пример #11
0
        public static void MarkAsEmpty(uint firstPageID, Engine engine)
        {
            var dataPage = PageFactory.GetDataPage(firstPageID, engine.Reader, true);
            uint lastPageID = uint.MaxValue;
            var cont = true;

            while (cont)
            {
                dataPage.IsEmpty = true;

                PageFactory.WriteToFile(dataPage, engine.Writer);

                if (dataPage.NextPageID != uint.MaxValue)
                {
                    lastPageID = dataPage.NextPageID;
                    dataPage = PageFactory.GetDataPage(lastPageID, engine.Reader, true);
                }
                else
                {
                    cont = false;
                }
            }

            // Fix header to correct pointer
            if (engine.Header.FreeDataPageID == uint.MaxValue) // No free pages
            {
                engine.Header.FreeDataPageID = firstPageID;
                engine.Header.LastFreeDataPageID = lastPageID == uint.MaxValue ? firstPageID : lastPageID;
            }
            else
            {
                // Take the last statment available
                var lastPage = PageFactory.GetDataPage(engine.Header.LastFreeDataPageID, engine.Reader, true);

                // Point this last statent to first of next one
                if (lastPage.NextPageID != uint.MaxValue || !lastPage.IsEmpty) // This is never to happend!!
                    throw new FileDBException("The page is not empty");

                // Update this last page to first new empty page
                lastPage.NextPageID = firstPageID;

                // Save on disk this update
                PageFactory.WriteToFile(lastPage, engine.Writer);

                // Point header to the new empty page
                engine.Header.LastFreeDataPageID = lastPageID == uint.MaxValue ? firstPageID : lastPageID;
            }
        }
Пример #12
0
 private static IndexNode GetChildIndexNode(IndexLink link, Engine engine)
 {
     var pageIndex = engine.CacheIndexPage.GetPage(link.PageID);
     return pageIndex.Nodes[link.Index];
 }
Пример #13
0
 public static IndexNode GetRootIndexNode(Engine engine)
 {
     IndexPage rootIndexPage = engine.CacheIndexPage.GetPage(engine.Header.IndexRootPageID);
     return rootIndexPage.Nodes[0];
 }