Exemple #1
0
        public void Put(QdbmKey key, byte[] value)
        {
            if (key == null || key.KeyBytes.Length == 0)
            {
                throw new ArgumentException("key must be specified", nameof(key));
            }

            if (value == null || value.Length == 0)
            {
                throw new ArgumentException("value must be specified", nameof(value));
            }

            _databaseStream.Seek(Constants.OffsetHeaderRecordCount, SeekOrigin.Begin);

            var existingRecordHeader = GetRecordHeader(key);

            var keySize   = key.KeyBytes.Length;
            var valueSize = value.Length;

            var recordHeader = new QdbmRecordHeader
            {
                KeySize   = keySize,
                ValueSize = valueSize
            };

            var record = new QdbmRecord(key, recordHeader, value);

            if (existingRecordHeader?.Size >= recordHeader.Size)
            {
                record.Header.Offset = existingRecordHeader.Offset;
                WriteRecordToDbStream(record);
            }
            else
            {
                AppendRecordToDbStream(record);
            }

            var recordOffset = record.Header.Offset;

            var bucketOffset = CalculateBucketOffset(record.Key, out var bucketId);

            _databaseStream.Seek(bucketOffset, SeekOrigin.Begin);

            var existingRecordOffset = _databaseBinaryReader.ReadInt32();

            if (existingRecordOffset == 0)
            {
                _databaseStream.Seek(bucketOffset, SeekOrigin.Begin);
                _databaseBinaryWriter.Write(recordOffset);

                _buckets[bucketId] = bucketOffset;
            }
            else
            {
                SetChildOffset(record.Key.SecondaryHashCode, existingRecordOffset, recordOffset);
            }
        }
Exemple #2
0
        private QdbmRecordHeader ReadRecordHeader(int recordOffset)
        {
            _databaseStream.Seek(recordOffset, SeekOrigin.Begin);

            var header = new QdbmRecordHeader
            {
                Offset           = recordOffset,
                Flags            = _databaseBinaryReader.ReadInt32(),
                SecondHashValue  = _databaseBinaryReader.ReadInt32(),
                KeySize          = _databaseBinaryReader.ReadInt32(),
                ValueSize        = _databaseBinaryReader.ReadInt32(),
                PaddingSize      = _databaseBinaryReader.ReadInt32(),
                LeftChildOffset  = _databaseBinaryReader.ReadInt32(),
                RightChildOffset = _databaseBinaryReader.ReadInt32()
            };

            return(header);
        }
Exemple #3
0
        private QdbmRecord ReadRecord(QdbmRecordHeader recordHeader)
        {
            _databaseStream.Seek(recordHeader.Offset + Constants.OffsetRecordKeyOffset, SeekOrigin.Begin);

            var key   = _databaseBinaryReader.ReadBytes(recordHeader.KeySize);
            var value = _databaseBinaryReader.ReadBytes(recordHeader.ValueSize);

            var qdbmKey = new QdbmKey(key);

            if (qdbmKey.SecondaryHashCode != recordHeader.SecondHashValue)
            {
                throw new InvalidOperationException("Database is corrupt.");
            }

            var qdbmRecord = new QdbmRecord(qdbmKey, recordHeader, value);

            return(qdbmRecord);
        }
Exemple #4
0
 public QdbmRecord(QdbmKey key, QdbmRecordHeader header, byte[] value)
 {
     Key    = key;
     Header = header;
     Value  = value;
 }