internal EntryInfo(IndexNode node) { _id = node.ID; _fileName = node.FileName + "." + node.FileExtension; _mimeType = MimeTypeConverter.Convert(node.FileExtension); _fileLength = node.FileLength; }
public static void ReadFile(IndexNode node, EntryInfo entry, Stream stream, Engine engine) { var dataPage = PageFactory.GetDataPage(node.DataPageID, engine.Reader, false); int metaDataStartPos = 0; int metaDataLength = entry.FileMetadataLength; int dataStartPos = metaDataStartPos + metaDataLength; int curReadPos = 0; if (dataPage != null && entry.FileMetadataLength > 0) { //first round //read file meta data while (curReadPos < metaDataLength) { //1.marker byte marker = ReadByte(dataPage.DataBlock, curReadPos, out curReadPos); switch (marker) { case 1: //date time long binaryTime = ReadInt64(dataPage.DataBlock, curReadPos, out curReadPos); entry.FileDateTime = DateTime.FromBinary(binaryTime); break; case 2: //long filename int nameLen = (int)ReadUInt16(dataPage.DataBlock, curReadPos, out curReadPos); byte[] nameBuffer = new byte[nameLen]; Array.Copy(dataPage.DataBlock, curReadPos, nameBuffer, 0, nameLen); entry.FileUrl = System.Text.Encoding.UTF8.GetString(nameBuffer); curReadPos += nameLen; break; default: throw new NotSupportedException(); } } } //----------------------------------- //data part int toReadLen = dataPage.DataBlockLength - curReadPos; while (dataPage != null) { stream.Write(dataPage.DataBlock, curReadPos, toReadLen); if (dataPage.NextPageID == uint.MaxValue) { dataPage = null; } else { dataPage = PageFactory.GetDataPage(dataPage.NextPageID, engine.Reader, false); //reset curReadPos = 0; toReadLen = dataPage.DataBlockLength; } } }
internal EntryInfo(IndexNode node) { ID = node.ID; FileUrl = node.FileUrl; FileLength = node.FileLength; FileMetadataLength = node.FileMetaDataLength; //--------------------- //no datetime or other metadata here //--------------------- }
public IndexPage(uint pageID) { PageID = pageID; NextPageID = uint.MaxValue; NodeIndex = 0; Nodes = new IndexNode[IndexPage.NODES_PER_PAGE]; IsDirty = false; for (int i = 0; i < IndexPage.NODES_PER_PAGE; i++) { var node = Nodes[i] = new IndexNode(this); } }
public IndexNode Search(Guid id) { // Take the root node from inital index page IndexNode rootIndexNode = IndexFactory.GetRootIndexNode(this); var indexNode = IndexFactory.BinarySearch(id, rootIndexNode, this); // Returns null with not found the record, return false if (indexNode == null || indexNode.IsDeleted) { return(null); } return(indexNode); }
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 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); } } }
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; }
// Implement file physic storage public void Write(EntryInfo entry, Stream stream) { // Take the first index page IndexNode rootIndexNode = IndexFactory.GetRootIndexNode(this); // Search and insert the index var indexNode = IndexFactory.BinaryInsert(entry, rootIndexNode, this); // In this moment, the index are ready and saved. I use to add the file DataFactory.InsertFile(indexNode, stream, this); // Update entry information with file length (I know file length only after read all) entry.FileLength = indexNode.FileLength; // Only after insert all stream file I confirm that index node is valid indexNode.IsDeleted = false; // Mask header as dirty for save on dispose Header.IsDirty = true; }
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.UsedNodeCount]; baseLink.PageID = pageIndex.PageID; baseLink.Index = pageIndex.UsedNodeCount; 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 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?!?"); } }
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; } }
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; }
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); } }