// Write a new key value pair to the output file. This method assumes that the data is being fed in key-sorted order. public void WritePair(Key key, Value value) { // when prefixing the key is shortened to mininum differential remainder // i.e. skip bytes matching the previous key short prefixLen = _lastPairKey == null ? (short)0 : key.PrefixLength(_lastPairKey); _lastPairKey = key.InternalBytes; int keyLength = key.Length - prefixLen; byte[] keySize = new byte[8]; byte[] valueSize = new byte[8]; var keySizeLen = Helper.Encode7BitInt(keySize, keyLength); var valueSizeLen = Helper.Encode7BitInt(valueSize, value.Length); int bytesNeeded = keySizeLen + keyLength + valueSizeLen + value.Length + 2 + 1; // +2 prefix len bytes +1 record header // Do we need to write out a block before adding this key value pair? if ((_bufferPos + bytesNeeded) > Config.SortedBlockSize) { WriteDataBlock(); } // If we are at the beginning of the buffer, then add this key to the index. if (_bufferPos == 0) { _pageIndex.Add(key); } // This is a record header _buffer[_bufferPos] = (byte)RecordHeaderFlag.PrefixedRecord; _bufferPos += 1; // write the data out to the buffer Helper.BlockCopy(keySize, 0, _buffer, _bufferPos, keySizeLen); _bufferPos += keySizeLen; // add the length of prefix 2 bytes _buffer[_bufferPos] = (byte)(prefixLen >> 8); _buffer[_bufferPos + 1] = (byte)(prefixLen & 255); _bufferPos += 2; Helper.BlockCopy(key.InternalBytes, prefixLen, _buffer, _bufferPos, keyLength); _bufferPos += keyLength; Helper.BlockCopy(valueSize, 0, _buffer, _bufferPos, valueSizeLen); _bufferPos += valueSizeLen; Helper.BlockCopy(value.InternalBytes, 0, _buffer, _bufferPos, value.Length); _bufferPos += value.Length; WrittenSize += bytesNeeded; }
private void WriteIndexKey(Key key) { byte[] keySize = new byte[8]; int keySizeLen = Helper.Encode7BitInt(keySize, key.Length); int bytesNeeded = keySizeLen + key.Length; // Do we need to write out a block before adding this key value pair? if ((_bufferPos + bytesNeeded) > Config.SortedBlockSize) { WriteBlock(); } // write the data out to the buffer Helper.BlockCopy(keySize, 0, _buffer, _bufferPos, keySizeLen); _bufferPos += keySizeLen; Helper.BlockCopy(key.InternalBytes, 0, _buffer, _bufferPos, key.Length); _bufferPos += key.Length; }
public void AddToIndex(byte[] itemKey, IEnumerable <KeyValuePair <string, byte[]> > indexValues) { foreach (var pair in indexValues) { var IndexName = pair.Key; // Construct Index key by concatenating the indexed value and the target key byte[] indexValue = pair.Value; byte[] indexKey = new byte[itemKey.Length + indexValue.Length]; indexValue.CopyTo(indexKey, 0); itemKey.CopyTo(indexKey, indexValue.Length); KeyValueStore indexStore = GetSecondaryIndex(IndexName); // get indexkey length encoding var lenBytes = new byte[8]; var indexValueLen = Helper.Encode7BitInt(lenBytes, indexValue.Length); var indexValueLenBytes = new byte[indexValueLen]; Helper.BlockCopy(lenBytes, 0, indexValueLenBytes, 0, indexValueLen); indexStore.Set(indexKey, indexValueLenBytes); // we know the key length } }