Example #1
0
        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);
        }
Example #2
0
        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.


            }
        }
Example #3
0
 private void SetEntryBytes(byte[] data)
 {
     GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
     entry = (DirectoryEntry)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(DirectoryEntry));
     handle.Free();
 }
Example #4
0
        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;
        }
Example #5
0
        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;
        }
Example #6
0
        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;
        }
Example #7
0
        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;
        }
Example #8
0
        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;
            }
        }
Example #9
0
        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;
                }
            }
        }
Example #10
0
        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]);
            }

        }