public static void ReadFromFile(IndexPage indexPage, BinaryReader reader) { // Seek the stream to the fist byte on page long initPos = reader.Seek(Header.HEADER_SIZE + ((long)indexPage.PageID * BasePage.PAGE_SIZE)); if (reader.ReadByte() != (byte)PageType.Index) throw new FileDBException("PageID {0} is not a Index Page", indexPage.PageID); indexPage.NextPageID = reader.ReadUInt32(); indexPage.NodeIndex = reader.ReadByte(); // Seek the stream to end of header data page reader.Seek(initPos + IndexPage.HEADER_SIZE); for (int i = 0; i <= indexPage.NodeIndex; i++) { var node = indexPage.Nodes[i]; node.ID = reader.ReadGuid(); node.IsDeleted = reader.ReadBoolean(); node.Right.Index = reader.ReadByte(); node.Right.PageID = reader.ReadUInt32(); node.Left.Index = reader.ReadByte(); node.Left.PageID = reader.ReadUInt32(); node.DataPageID = reader.ReadUInt32(); node.FileName = reader.ReadString(IndexNode.FILENAME_SIZE); node.FileExtension = reader.ReadString(IndexNode.FILE_EXTENSION_SIZE); node.FileLength = reader.ReadUInt32(); } }
public static void CreateEmptyFile(BinaryWriter writer) { // Create new header instance var header = new Header(); header.IndexRootPageID = 0; header.FreeIndexPageID = 0; header.FreeDataPageID = uint.MaxValue; header.LastFreeDataPageID = uint.MaxValue; header.LastPageID = 0; HeaderFactory.WriteToFile(header, writer); // Create a first fixed index page var pageIndex = new IndexPage(0); pageIndex.NodeIndex = 0; pageIndex.NextPageID = uint.MaxValue; // Create first fixed index node, with fixed middle guid var indexNode = pageIndex.Nodes[0]; indexNode.ID = new Guid(new byte[] { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127 }); indexNode.IsDeleted = true; indexNode.Right = new IndexLink(); indexNode.Left = new IndexLink(); indexNode.DataPageID = uint.MaxValue; indexNode.FileName = string.Empty; indexNode.FileExtension = string.Empty; PageFactory.WriteToFile(pageIndex, writer); }
public IndexPage GetFreeIndexPage() { var freeIndexPage = CacheIndexPage.GetPage(Header.FreeIndexPageID); // Check if "free page" has no more index to be used if (freeIndexPage.UsedNodeCount >= IndexPage.NODES_PER_PAGE - 1) { Header.LastPageID++; // Take last page and increase Header.IsDirty = true; var newIndexPage = new IndexPage(Header.LastPageID); // Create a new index page freeIndexPage.NextPageID = newIndexPage.PageID; // Point older page to the new page Header.FreeIndexPageID = Header.LastPageID; // Update last index page CacheIndexPage.AddPage(freeIndexPage, true); return newIndexPage; } else { // Has more free index on same index page? return them freeIndexPage.IncNodeUsed(); // Reserve space return freeIndexPage; } }
public const int INDEX_NODE_SIZE = 81; // Node Index size #endregion Fields #region Constructors public IndexNode(IndexPage indexPage) { ID = Guid.Empty; IsDeleted = true; // Start with index node mark as deleted. Update this after save all stream on disk Right = new IndexLink(); Left = new IndexLink(); DataPageID = uint.MaxValue; IndexPage = indexPage; }
public static void WriteToFile(IndexPage indexPage, BinaryWriter writer) { // Seek the stream to the fist byte on page long initPos = writer.SetWritePos(Header.FILE_START_HEADER_SIZE + (indexPage.PageID * BasePage.PAGE_SIZE)); // Write page header writer.Write((byte)indexPage.Type); writer.Write(indexPage.NextPageID); writer.Write(indexPage.UsedNodeCount); // Seek the stream to end of header index page writer.SetWritePos(initPos + IndexPage.INDEX_HEADER_SIZE); //46 for (int i = 0; i <= indexPage.UsedNodeCount; i++) { var node = indexPage.Nodes[i]; writer.Write(node.ID); //16 writer.Write(node.IsDeleted); //1 writer.Write(node.Right.Index); //1 writer.Write(node.Right.PageID); //4 writer.Write(node.Left.Index);//1 writer.Write(node.Left.PageID); //4 writer.Write(node.DataPageID); //4 writer.Write(node.FileMetaDataLength); //2 writer.Write(node.FileLength); //4 byte[] fileUrlBytes = System.Text.Encoding.UTF8.GetBytes(node.FileUrl); if (fileUrlBytes.Length >= ushort.MaxValue) { throw new FileDBException("filename is too long!"); } int diff = fileUrlBytes.Length - IndexNode.FILENAME_SIZE; if (diff >= 0) { //limit writer.Write((byte)(IndexNode.FILENAME_SIZE + 1)); //1 writer.Write(fileUrlBytes, 0, IndexNode.FILENAME_SIZE); } else { writer.Write((byte)(fileUrlBytes.Length)); writer.Write(fileUrlBytes); //diff //write padding writer.Write(new byte[-diff]); } } }
public static void ReadFromFile(IndexPage indexPage, BinaryReader reader) { // Seek the stream to the first byte on page long initPos = reader.SetReadPos(Header.FILE_START_HEADER_SIZE + (indexPage.PageID * BasePage.PAGE_SIZE)); if (reader.ReadByte() != (byte)PageType.Index) throw new FileDBException("PageID {0} is not a Index Page", indexPage.PageID); indexPage.NextPageID = reader.ReadUInt32(); indexPage.SetUsedNodeCount(reader.ReadByte()); // Seek the stream to end of header data page reader.SetReadPos(initPos + IndexPage.INDEX_HEADER_SIZE); //in this version //each node uses buffer= 16+1+1+4+1+4+4+8+4+2+36 =81 //IndexPage.NODES_PER_PAGE = 50; //so it use 81*50 = 4050 //IndexPage.INDEX_HEADER_SIZE =46 //so => 4050 +46 = 4096 //and each page has BasePage.PAGE_SIZE = 4096 => matched for (int i = 0; i <= indexPage.UsedNodeCount; i++) { var node = indexPage.Nodes[i]; node.ID = reader.ReadGuid(); //16 node.IsDeleted = reader.ReadBoolean(); //1 node.Right.Index = reader.ReadByte(); //1 node.Right.PageID = reader.ReadUInt32(); //4 node.Left.Index = reader.ReadByte(); //1 node.Left.PageID = reader.ReadUInt32();//4 node.DataPageID = reader.ReadUInt32();//4 node.FileMetaDataLength = reader.ReadUInt16();//2 node.FileLength = reader.ReadUInt32();//4 int filenameCount = reader.ReadByte(); //1 if (filenameCount > IndexNode.FILENAME_SIZE) { node.FileUrl = reader.ReadUtf8String(IndexNode.FILENAME_SIZE); } else { string filename = reader.ReadUtf8String(IndexNode.FILENAME_SIZE); node.FileUrl = filename.Substring(0, filenameCount); } } }
public void AddPage(IndexPage indexPage, bool markAsDirty) { if(!_cache.ContainsKey(indexPage.PageID)) { if(_cache.Count >= CACHE_SIZE) { // Remove fist page that are not the root page (because I use too much) var pageToRemove = _cache.First(x => x.Key != _rootPageID); if (pageToRemove.Value.IsDirty) { PageFactory.WriteToFile(pageToRemove.Value, _writer); pageToRemove.Value.IsDirty = false; } _cache.Remove(pageToRemove.Key); } _cache.Add(indexPage.PageID, indexPage); } if(markAsDirty) indexPage.IsDirty = true; }
public static void ReadFromFile(IndexPage indexPage, BinaryReader reader) { // Seek the stream to the fist byte on page long initPos = reader.Seek(Header.HEADER_SIZE + ((long)indexPage.PageID * BasePage.PAGE_SIZE)); if (reader.ReadByte() != (byte)PageType.Index) { throw new FileDBException("PageID {0} is not a Index Page", indexPage.PageID); } indexPage.NextPageID = reader.ReadUInt32(); indexPage.NodeIndex = reader.ReadByte(); // Seek the stream to end of header data page reader.Seek(initPos + IndexPage.HEADER_SIZE); for (int i = 0; i <= indexPage.NodeIndex; i++) { var node = indexPage.Nodes[i]; node.ID = reader.ReadGuid(); node.IsDeleted = reader.ReadBoolean(); node.Right.Index = reader.ReadByte(); node.Right.PageID = reader.ReadUInt32(); node.Left.Index = reader.ReadByte(); node.Left.PageID = reader.ReadUInt32(); node.DataPageID = reader.ReadUInt32(); node.FileName = reader.ReadString(IndexNode.FILENAME_SIZE); node.FileExtension = reader.ReadString(IndexNode.FILE_EXTENSION_SIZE); node.FileLength = reader.ReadUInt32(); } }
public void AddPage(IndexPage indexPage) { AddPage(indexPage, false); }
public static IndexNode GetRootIndexNode(Engine engine) { IndexPage rootIndexPage = engine.CacheIndexPage.GetPage(engine.Header.IndexRootPageID); return(rootIndexPage.Nodes[0]); }
public static void WriteToFile(IndexPage indexPage, BinaryWriter writer) { // Seek the stream to the fist byte on page long initPos = writer.Seek(Header.HEADER_SIZE + ((long)indexPage.PageID * BasePage.PAGE_SIZE)); // Write page header writer.Write((byte)indexPage.Type); writer.Write(indexPage.NextPageID); writer.Write(indexPage.NodeIndex); // Seek the stream to end of header index page writer.Seek(initPos + IndexPage.HEADER_SIZE); for (int i = 0; i <= indexPage.NodeIndex; i++) { var node = indexPage.Nodes[i]; writer.Write(node.ID); writer.Write(node.IsDeleted); writer.Write(node.Right.Index); writer.Write(node.Right.PageID); writer.Write(node.Left.Index); writer.Write(node.Left.PageID); writer.Write(node.DataPageID); writer.Write(node.FileName.ToBytes(IndexNode.FILENAME_SIZE)); writer.Write(node.FileExtension.ToBytes(IndexNode.FILE_EXTENSION_SIZE)); writer.Write(node.FileLength); } }
public static IndexPage GetIndexPage(uint pageID, BinaryReader reader) { var indexPage = new IndexPage(pageID); ReadFromFile(indexPage, reader); return indexPage; }