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); }
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); } }
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; }
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; }
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; } }
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?!?"); } }
// 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; } }
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; } }
internal DebugFile(Engine engine) { _engine = engine; }
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); } }
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; } }
private static IndexNode GetChildIndexNode(IndexLink link, Engine engine) { var pageIndex = engine.CacheIndexPage.GetPage(link.PageID); return pageIndex.Nodes[link.Index]; }
public static IndexNode GetRootIndexNode(Engine engine) { IndexPage rootIndexPage = engine.CacheIndexPage.GetPage(engine.Header.IndexRootPageID); return rootIndexPage.Nodes[0]; }