public PlateFile2(string filename, int filecount) { fileStream = File.Open(filename, FileMode.Create); //Initialize the header header.Signature = 0x17914242; header.HashBuckets = NextPowerOfTwo(filecount); header.HashTableLocation = Marshal.SizeOf(header); header.FirstDirectoryEntry = header.HashTableLocation + header.HashBuckets * 8; header.NextFreeDirectoryEntry = header.FirstDirectoryEntry + Marshal.SizeOf(entry); header.FileCount = 0; header.FreeEntries = header.HashBuckets - 1; //Write the header and the empty Hash area. O/S will zero the data Byte[] headerData = GetHeaderBytes(); fileStream.Write(headerData, 0, headerData.Length); fileStream.Seek(header.NextFreeDirectoryEntry + Marshal.SizeOf(entry) * header.HashBuckets, SeekOrigin.Begin); fileStream.WriteByte(42); fileStream.Seek(header.FirstDirectoryEntry, SeekOrigin.Begin); entry = new DirectoryEntry(); entry.size = (uint)header.FreeEntries * (uint)Marshal.SizeOf(entry); entry.location = header.FirstDirectoryEntry; byte[] entryData = GetEntryBytes(); fileStream.Write(entryData, 0, entryData.Length); fileStream.Seek(0, SeekOrigin.Begin); }
public void AddFile(string inputFilename, int tag, int level, int x, int y) { FileInfo fi = new FileInfo(inputFilename); if (fi.Exists) { Byte[] entryData = null; // Check for empty directory and add new Directory Block if (header.FreeEntries == 0) { // Write Directory Header Block entry = new DirectoryEntry(); entry.size = 8192 * (uint)Marshal.SizeOf(entry); entry.NextEntryInChain = header.FirstDirectoryEntry; entryData = GetEntryBytes(); header.FirstDirectoryEntry = fileStream.Seek(0, SeekOrigin.End); fileStream.Write(entryData, 0, entryData.Length); // Allocate a new 8k entries header.FreeEntries = 8192; header.NextFreeDirectoryEntry = fileStream.Seek(0, SeekOrigin.End); fileStream.Seek(8192 * Marshal.SizeOf(entry), SeekOrigin.End); fileStream.WriteByte(42); } long position = fileStream.Seek(0, SeekOrigin.End); entry = new DirectoryEntry(tag, level, x, y, position, (UInt32)fi.Length); UInt32 index = entry.ComputeHash() % (UInt32)header.HashBuckets; byte[] buf = null; // Copy the input file stream to the end of the file using (FileStream ifs = File.Open(inputFilename, FileMode.Open, FileAccess.Read, FileShare.Read)) { int len = (int)fi.Length; buf = new byte[fi.Length]; ifs.Read(buf, 0, len); fileStream.Write(buf, 0, len); ifs.Close(); } long hep = GetHashEntryPosition(index); entry.NextEntryInChain = hep; // Update the Hash Table WriteHashEntryPosition(index, header.NextFreeDirectoryEntry); // Write the directory entry fileStream.Seek(header.NextFreeDirectoryEntry, SeekOrigin.Begin); entryData = GetEntryBytes(); fileStream.Write(entryData, 0, entryData.Length); // Update Header header.FileCount++; header.NextFreeDirectoryEntry += Marshal.SizeOf(entry); header.FreeEntries--; // Write it back to file Byte[] headerData = GetHeaderBytes(); fileStream.Seek(0, SeekOrigin.Begin); fileStream.Write(headerData, 0, headerData.Length); //todo check for file count and extend file when we get to end. } }
private void SetEntryBytes(byte[] data) { GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); entry = (DirectoryEntry)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(DirectoryEntry)); handle.Free(); }
public Stream GetFileStreamFullSearch(int tag, int level, int x, int y) { entry = new DirectoryEntry(tag, level, x, y, 0, 0); UInt32 index = entry.ComputeHash() % (UInt32)(header.HashBuckets); long hep = GetHashEntryPosition(index); DirectoryEntry de; DirectoryEntry den = new DirectoryEntry(); while (hep != 0) { de = GetDirectoryEntry(hep); if ((de.x == x) && (de.y == y) && ((de.tag == tag) || (tag == -1)) && (de.level == level)) { if (den.tag < de.tag) { den = de; if (tag != -1) { break; } } } hep = de.NextEntryInChain; } if (den.location != 0) { MemoryStream ms = null; byte[] buffer = new byte[den.size]; fileStream.Seek(den.location, SeekOrigin.Begin); fileStream.Read(buffer, 0, (int)den.size); ms = new MemoryStream(buffer); return ms; } return null; }
public int GetTotalFiles() { DirectoryEntry de = new DirectoryEntry(0, 0, 0, 0, 0, 0); int total = 0; for (UInt32 i = 0; i < header.HashBuckets; i++) { long hep = GetHashEntryPosition(i); while (hep != 0) { total++; de = GetDirectoryEntry(hep); hep = de.NextEntryInChain; } } return total; }
public string GetLongestChainID() { DirectoryEntry de = new DirectoryEntry(0, 0, 0, 0, 0, 0); int longest = 0; int current = 0; string id = ""; for (UInt32 i = 0; i < header.HashBuckets; i++) { long hep = GetHashEntryPosition(i); current = 0; while (hep != 0) { current++; de = GetDirectoryEntry(hep); hep = de.NextEntryInChain; } if (current > longest) { longest = current; id = i.ToString(); } } return id; }
public int GetLongestChain() { DirectoryEntry de = new DirectoryEntry(0, 0, 0, 0, 0, 0); int longest = 0; int current = 0; for (UInt32 i = 0; i < header.HashBuckets; i++) { long hep = GetHashEntryPosition(i); current = 0; while (hep != 0) { current++; de = GetDirectoryEntry(hep); hep = de.NextEntryInChain; } if (current > longest) { longest = current; } } return longest; }
public IEnumerable<DirectoryEntry> GetDirectoryEntries() { DirectoryEntry de = new DirectoryEntry(0, 0, 0, 0, 0, 0); long hep = header.FirstDirectoryEntry; while (hep != 0) { de = GetDirectoryEntry(hep); de.location = hep; if (de.size != 0) { yield return de; } hep = de.NextEntryInChain; } }
public IEnumerable<DirectoryEntry> GetEntries() { DirectoryEntry de = new DirectoryEntry(0, 0, 0, 0, 0, 0); for (UInt32 i = 0; i < header.HashBuckets; i++) { long hep = GetHashEntryPosition(i); while (hep != 0) { de = GetDirectoryEntry(hep); yield return de; hep = de.NextEntryInChain; } } }
public void Optimize() { DirectoryEntry de = new DirectoryEntry(0, 0, 0, 0, 0, 0); // preload the directory & hashtable here to make sure reads are serial and in system cache List<List<DirectoryEntry>> list = new List<List<DirectoryEntry>>(); byte[] buf = new byte[header.HashBuckets * 8]; fileStream.Read(buf, 0, (int)buf.Length); de = GetDirectoryEntry(header.FirstDirectoryEntry); buf = new byte[de.size]; fileStream.Read(buf, 0, (int)de.size); for (UInt32 i = 0; i < header.HashBuckets; i++) { List<DirectoryEntry> dirList = new List<DirectoryEntry>(); long hep = GetHashEntryPosition(i); while (hep != 0) { de = GetDirectoryEntry(hep); dirList.Add(de); hep = de.NextEntryInChain; } dirList.Sort(); list.Add(dirList); } long curPos = header.FirstDirectoryEntry + Marshal.SizeOf(entry); long[] hashTable = new long[header.HashBuckets]; for (int i = 0; i < header.HashBuckets; i++) { List<DirectoryEntry> dir = list[i]; if (dir.Count > 0) { hashTable[i] = curPos; for (int j = 0; j < dir.Count; j++) { de = dir[j]; if (j == dir.Count - 1) { de.NextEntryInChain = 0; } else { de.NextEntryInChain = curPos + Marshal.SizeOf(entry); } fileStream.Seek(curPos, SeekOrigin.Begin); de.Write(fileStream); curPos += Marshal.SizeOf(entry); } } } // Write table seperately to sequence writes for (int i = 0; i < header.HashBuckets; i++) { WriteHashEntryPosition((uint)i, hashTable[i]); } }