public Key(byte[] bytes, byte seqNum) { byte[] internalBytes = new byte[bytes.Length + 1]; Helper.BlockCopy(bytes, 0, internalBytes, 0, bytes.Length); internalBytes[bytes.Length] = seqNum; _bytes = new ByteArray(internalBytes); }
public Value(byte[] bytes, ValueFlag type) { byte[] b = new byte[bytes.Length + 1]; b[0] = (byte)type; Helper.BlockCopy(bytes, 0, b, 1, bytes.Length); _bytes = new ByteArray(b); }
// 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; }
/// <summary> /// Get the item key from an index /// </summary> /// <param name="indexPair"></param> /// <returns></returns> private static byte[] ItemKeyFromIndex(KeyValuePair <byte[], byte[]> indexPair, int indexKeyLen = -1) { int offset = 0; if (indexPair.Value.Length > 4) { return(indexPair.Value); } else { indexKeyLen = indexKeyLen == -1 ? Helper.Decode7BitInt(indexPair.Value, ref offset) : indexKeyLen; var objectKey = new byte[indexPair.Key.Length - indexKeyLen]; Helper.BlockCopy(indexPair.Key, indexKeyLen, objectKey, 0, indexPair.Key.Length - indexKeyLen); return(objectKey); } }
private void WriteMetadata() { MemoryStream ms = new MemoryStream(); BinaryWriter writer = new BinaryWriter(ms); writer.Write(Encoding.ASCII.GetBytes("@RAZORDB")); writer.Write7BitEncodedInt(SortedBlockTable.Magic); writer.Write(SortedBlockTable.CurrentFormatVersion); writer.Write7BitEncodedInt(totalBlocks + 1); writer.Write7BitEncodedInt(dataBlocks); writer.Write7BitEncodedInt(indexBlocks); byte[] metadata = ms.ToArray(); Helper.BlockCopy(metadata, 0, _buffer, 0, metadata.Length); // Commit the block to disk and wait for the operation to complete WriteBlock(); _fileStream.EndWrite(_async); }
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 } }
/// <summary> /// Return only the bytes for the key linked to the index (record key in this case is the index value) /// </summary> /// <param name="indexName"></param> /// <param name="lookupValue"></param> /// <returns></returns> public IEnumerable <KeyValuePair <byte[], byte[]> > FindKeysByIndexStartsWith(string indexName, byte[] lookupValue) { KeyValueStore indexStore = GetSecondaryIndex(indexName); // Loop over the values foreach (var pair in indexStore.EnumerateFromKey(lookupValue)) { // construct our index key pattern (lookupvalue | key) if (ByteArray.CompareMemCmp(pair.Key, 0, lookupValue, 0, lookupValue.Length) == 0) { int offset = 0; if (Manifest.RazorFormatVersion < 2) { if (ByteArray.CompareMemCmp(pair.Key, pair.Key.Length - pair.Value.Length, pair.Value, 0, pair.Value.Length) == 0) { yield return(new KeyValuePair <byte[], byte[]>(pair.Key, pair.Value)); } } else { int indexKeyLen = Helper.Decode7BitInt(pair.Value, ref offset); if (lookupValue.Length <= indexKeyLen) { var objectKey = ItemKeyFromIndex(pair, indexKeyLen); Helper.BlockCopy(pair.Key, indexKeyLen, objectKey, 0, pair.Key.Length - indexKeyLen); yield return(new KeyValuePair <byte[], byte[]>(pair.Key, objectKey)); } } } else { // if the above condition was not met then we must have enumerated past the end of the indexed value yield break; } } }
public static ByteArray From(byte[] block, int offset, int size) { byte[] bytes = new byte[size]; Helper.BlockCopy(block, offset, bytes, 0, size); return(new ByteArray(bytes)); }
public int CopyValueBytesTo(byte[] block, int offset) { Helper.BlockCopy(InternalBytes, 1, block, offset, Length - 1); return(Length - 1); }