Exemplo n.º 1
0
        /// <summary>
        /// Adds a key to the constant database.
        /// </summary>
        /// <param name="key">The key to add to the database.</param>
        /// <param name="data">The data associated with this key.</param>
        /// <exception cref="System.IO.IOException">If an error occurs adding the key
        ///  to the database.</exception>
        public void Add(byte[] key, byte[] data)
        {
            /* Write out the key length. */
            CdbUtils.WriteLittleEndianInt32(fileStream, key.Length);

            /* Write out the data length. */
            CdbUtils.WriteLittleEndianInt32(fileStream, data.Length);

            /* Write out the key. */
            fileStream.Write(key, 0, key.Length);

            /* Write out the data. */
            fileStream.Write(data, 0, data.Length);


            /* Add the hash pointer to our list. */
            int hash = CdbUtils.Hash(key);

            hashPointers.Add(new CdbHashPointer(hash, currentKeyPos));

            /* Add this item to the count. */
            tableCount[hash & 0xff]++;


            /* Update the file position pointer. */
            PosPlus(8);
            PosPlus(key.Length);
            PosPlus(data.Length);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Finalizes the constant database.
        /// </summary>
        /// <exception cref="System.IO.IOException">If an error occurs closing out the
        ///  database.</exception>
        public void Finish()
        {
            if (fileStream == null)
            {
                return;
            }

            /* Find the start of each hash table. */
            int curEntry = 0;

            for (int i = 0; i < 256; i++)
            {
                curEntry     += tableCount[i];
                tableStart[i] = curEntry;
            }

            /* Create a new hash pointer list in order by hash table. */
            CdbHashPointer[] slotPointers = new CdbHashPointer[hashPointers.Count];
            foreach (CdbHashPointer hp in hashPointers)
            {
                slotPointers[--tableStart[hp.HashValue & 0xff]] = hp;
            }

            /* Write out each of the hash tables, building the slot table in
             * the process. */
            byte[] slotTable = new byte[2048];
            for (int i = 0; i < 256; i++)
            {
                /* Get the length of the hashtable. */
                int len = tableCount[i] * 2;

                /* Store the position of this table in the slot table. */
                slotTable[(i * 8) + 0]     = unchecked ((byte)(currentKeyPos & 0xff));
                slotTable[(i * 8) + 1]     = unchecked ((byte)(((int)((uint)currentKeyPos >> 8)) & 0xff));
                slotTable[(i * 8) + 2]     = unchecked ((byte)(((int)((uint)currentKeyPos >> 16)) & 0xff));
                slotTable[(i * 8) + 3]     = unchecked ((byte)(((int)((uint)currentKeyPos >> 24)) & 0xff));
                slotTable[(i * 8) + 4 + 0] = unchecked ((byte)(len & 0xff));
                slotTable[(i * 8) + 4 + 1] = unchecked ((byte)(((int)((uint)len >> 8)) & 0xff));
                slotTable[(i * 8) + 4 + 2] = unchecked ((byte)(((int)((uint)len >> 16)) & 0xff));
                slotTable[(i * 8) + 4 + 3] = unchecked ((byte)(((int)((uint)len >> 24)) & 0xff));

                /* Build the hash table. */
                int curSlotPointer         = tableStart[i];
                CdbHashPointer[] hashTable = new CdbHashPointer[len];
                for (int u = 0; u < tableCount[i]; u++)
                {
                    /* Get the hash pointer. */
                    CdbHashPointer hp = slotPointers[curSlotPointer++];

                    /* Locate a free space in the hash table. */
                    int @where = ((int)((uint)hp.HashValue >> 8)) % len;
                    while (hashTable[@where] != null)
                    {
                        if (++@where == len)
                        {
                            @where = 0;
                        }
                    }

                    /* Store the hash pointer. */
                    hashTable[@where] = hp;
                }

                /* Write out the hash table. */
                for (int u = 0; u < len; u++)
                {
                    CdbHashPointer hp = hashTable[u];
                    if (hp != null)
                    {
                        CdbUtils.WriteLittleEndianInt32(fileStream, hashTable[u].HashValue);
                        CdbUtils.WriteLittleEndianInt32(fileStream, hashTable[u].EntryPos);
                    }
                    else
                    {
                        CdbUtils.WriteLittleEndianInt32(fileStream, 0);
                        CdbUtils.WriteLittleEndianInt32(fileStream, 0);
                    }
                    PosPlus(8);
                }
            }

            /* Seek back to the beginning of the file and write out the
             * slot table. */
            fileStream.Seek(0, SeekOrigin.Begin);
            fileStream.Write(slotTable, 0, slotTable.Length);

            /* Close the file. */
            fileStream.Dispose();
            fileStream = null;
        }