Exemple #1
0
        private int _loop;         // num of hash slots searched under current key

        /// <summary>
        /// Open a constant database from the given file.
        /// </summary>
        /// <param name="filePath">Path to the CDB file.</param>
        public CdbFile(string filePath)
        {
            _cdbFile = File.OpenRead(filePath);

            _heads = new UInt32[256 * 2];

            var bytes = new byte[2048];

            CdbRead(bytes, bytes.Length);

            for (int i = 0, offset = 0; i < 256; i++)
            {
                UInt32 pos = Cdb.UnpackInt32(bytes, offset);
                offset += 4;
                UInt32 len = Cdb.UnpackInt32(bytes, offset);
                offset += 4;

                _heads[i << 1]       = pos;
                _heads[(i << 1) + 1] = len;
            }

            _loop = 0;
        }
Exemple #2
0
        /// <summary>
        /// Find the next record stored under the given <paramref name="key"/>.
        /// </summary>
        /// <returns>The next record stored under the given key,
        /// or <c>null</c> if no more records can be found.</returns>
        public byte[] FindNext(byte[] key)
        {
            // We change object state in here, so nobody must intervene!
            lock (_syncLock)
            {
                if (_cdbFile == null)
                {
                    throw new ObjectDisposedException(GetType().Name);
                }

                // Initialize: locate hash table and entry in it:
                if (_loop == 0)
                {
                    UInt32 u = Cdb.Hash(key);

                    // Get hash table len&pos for this key:
                    UInt32 slot = u & 255;
                    _hslots = _heads[(slot << 1) + 1];
                    if (_hslots == 0)
                    {
                        return(null);
                    }
                    _hpos = _heads[slot << 1];

                    // Remember this key's hash:
                    _khash = u;

                    // Locate the slot in the table at _hpos:
                    u   >>= 8;
                    u    %= _hslots;
                    u   <<= 3;
                    _kpos = _hpos + u;
                }

                // Search: iterate all hash slots for the given key:
                var bytes = new byte[8];
                while (_loop < _hslots)
                {
                    // Read the entry for this key from the hash slot
                    CdbRead(bytes, 8, _kpos);
                    UInt32 h   = Cdb.UnpackInt32(bytes, 0);
                    UInt32 pos = Cdb.UnpackInt32(bytes, 4);
                    if (pos == 0)
                    {
                        break;
                    }

                    // Advance loop counter and key position.
                    // Wrap key position if at end of hash table.
                    _loop += 1;
                    _kpos += 8;
                    if (_kpos == (_hpos + (_hslots << 3)))
                    {
                        _kpos = _hpos;
                    }

                    // Different hash? Probe next slot...
                    if (h != _khash)
                    {
                        continue;
                    }

                    // Jump to the record and see if key matches:
                    CdbRead(bytes, 8, pos);
                    UInt32 klen = Cdb.UnpackInt32(bytes, 0);
                    if (klen != key.Length)
                    {
                        continue;
                    }
                    if (!CdbMatch(key))
                    {
                        continue;
                    }
                    UInt32 dlen = Cdb.UnpackInt32(bytes, 4);

                    // Keys match: fetch the data
                    var data = new byte[dlen];
                    CdbRead(data, data.Length);
                    return(data);
                }

                return(null);                // No such key
            }
        }