/// <summary> /// Add a key/data pair to the database. /// </summary> /// <param name="key">The key.</param> /// <param name="data">The data.</param> public void Add(byte[] key, byte[] data) { if (_file == null) { throw new ObjectDisposedException(GetType().Name); } var bytes = new byte[8]; Cdb.PackInt32((UInt32)key.Length, bytes, 0); Cdb.PackInt32((UInt32)data.Length, bytes, 4); // Write the record: keylen, datalen, key, data. _file.Write(bytes, 0, bytes.Length); _file.Write(key, 0, key.Length); _file.Write(data, 0, data.Length); // Add hash and offset to the in-memory list: UInt32 hash = Cdb.Hash(key); _hashInfo.Add(new HashPos(hash, _pos)); _hashSize[hash & 255] += 1; // one more entry // Update the file position pointer: AdvancePos(8); // key and data length AdvancePos((UInt32)key.Length); AdvancePos((UInt32)data.Length); }
/// <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 } }