Example #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);
        }
Example #2
0
        /// <summary>
        /// Finds the next record stored under the given key.
        /// </summary>
        /// <param name="key"> The key to search for. </param>
        /// <returns> The next record store under the given key, or
        ///  <code>null</code> if no record with that key could be found. </returns>
        public byte[] FindNext(byte[] key)
        {
            lock (this)
            {
                /* There are no keys if we could not read the slot table. */
                if (slotTable == null)
                {
                    return(null);
                }

                /* Locate the hash entry if we have not yet done so. */
                if (numberOfHashSlotsSearched == 0)
                {
                    /* Get the hash value for the key. */
                    int u = CdbUtils.Hash(key);

                    /* Unpack the information for this record. */
                    int slot = u & 255;
                    numberOfHashSlots = slotTable[(slot << 1) + 1];
                    if (numberOfHashSlots == 0)
                    {
                        return(null);
                    }
                    currentKeyHashTablePos = slotTable[slot << 1];

                    /* Store the hash value. */
                    currentKeyHashValue = u;

                    /* Locate the slot containing this key. */
                    u             = (int)((uint)u >> 8);
                    u            %= numberOfHashSlots;
                    u           <<= 3;
                    currentKeyPos = currentKeyHashTablePos + u;
                }

                /* Search all of the hash slots for this key. */
                try
                {
                    while (numberOfHashSlotsSearched < numberOfHashSlots)
                    {
                        /* Read the entry for this key from the hash slot. */
                        fileStream.Seek(currentKeyPos, SeekOrigin.Begin);

                        int h = fileStream.ReadByte() | (fileStream.ReadByte() << 8) | (fileStream.ReadByte() << 16) |
                                (fileStream.ReadByte() << 24);

                        int pos = fileStream.ReadByte() | (fileStream.ReadByte() << 8) | (fileStream.ReadByte() << 16) |
                                  (fileStream.ReadByte() << 24);
                        if (pos == 0)
                        {
                            return(null);
                        }

                        /* Advance the loop count and key position.  Wrap the
                         * key position around to the beginning of the hash slot
                         * if we are at the end of the table. */
                        numberOfHashSlotsSearched += 1;

                        currentKeyPos += 8;
                        if (currentKeyPos == (currentKeyHashTablePos + (numberOfHashSlots << 3)))
                        {
                            currentKeyPos = currentKeyHashTablePos;
                        }

                        /* Ignore this entry if the hash values do not match. */
                        if (h != currentKeyHashValue)
                        {
                            continue;
                        }

                        /* Get the length of the key and data in this hash slot
                         * entry. */
                        fileStream.Seek(pos, SeekOrigin.Begin);

                        int klen = fileStream.ReadByte() | (fileStream.ReadByte() << 8) | (fileStream.ReadByte() << 16) |
                                   (fileStream.ReadByte() << 24);
                        if (klen != key.Length)
                        {
                            continue;
                        }

                        int dlen = fileStream.ReadByte() | (fileStream.ReadByte() << 8) | (fileStream.ReadByte() << 16) |
                                   (fileStream.ReadByte() << 24);

                        /* Read the key stored in this entry and compare it to
                         * the key we were given. */
                        bool   match = true;
                        byte[] k     = new byte[klen];
                        fileStream.Read(k, 0, k.Length);
                        for (int i = 0; i < k.Length; i++)
                        {
                            if (k[i] != key[i])
                            {
                                match = false;
                                break;
                            }
                        }

                        /* No match; check the next slot. */
                        if (!match)
                        {
                            continue;
                        }

                        /* The keys match, return the data. */
                        byte[] d = new byte[dlen];
                        fileStream.Read(d, 0, d.Length);
                        return(d);
                    }
                }
                catch (IOException)
                {
                    return(null);
                }

                /* No more data values for this key. */
                return(null);
            }
        }