public static Decode7BitInt ( byte workingArray, int &offset ) : int | ||
workingArray | byte | |
offset | int | |
return | int |
private static Key ReadKey(byte[] block, ref int offset) { int keySize = Helper.Decode7BitInt(block, ref offset); var key = ByteArray.From(block, offset, keySize); offset += keySize; // if the next keySize bit is zero then we have exhausted this block. Set to -1 to terminate enumeration if (block[offset] == 0) { offset = -1; } return(new Key(key)); }
private static Value ReadValue(ref byte[] block, ref int offset) { int valueSize = Helper.Decode7BitInt(block, ref offset); var val = Value.From(block, offset, valueSize); offset += valueSize; // if the next keySize bit is zero then we have exhausted this block. Set to -1 to terminate enumeration if (offset >= Config.SortedBlockSize || block[offset] == (byte)RecordHeaderFlag.EndOfBlock) { offset = -1; } return(val); }
private KeyValuePair <Key, Value> ReadPair(ref byte[] lastKey, ref byte[] block, ref int offset) { bool isPrefixed = block[offset] == (byte)RecordHeaderFlag.PrefixedRecord; offset += FormatVersion < 2 ? 5 : 1; // skip bytes of old tree blocks int keySize = Helper.Decode7BitInt(block, ref offset); short prefixLen = isPrefixed ? (short)(block[offset] << 8 | block[offset + 1]) : (short)0; offset += isPrefixed ? 2 : 0; Key key = prefixLen > 0 ? Key.KeyFromPrefix(lastKey, prefixLen, block, offset, keySize) : new Key(ByteArray.From(block, offset, keySize)); offset += keySize; lastKey = key.InternalBytes; return(new KeyValuePair <Key, Value>(key, ReadValue(ref block, ref offset))); }
/// <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); } }
public IEnumerable <KeyValuePair <byte[], byte[]> > Find(string indexName, byte[] lookupValue) { KeyValueStore indexStore = GetSecondaryIndex(indexName); // Loop over the values foreach (var pair in indexStore.EnumerateFromKey(lookupValue)) { var key = pair.Key; var value = pair.Value; // construct our index key pattern (lookupvalue | key) if (ByteArray.CompareMemCmp(key, 0, lookupValue, 0, lookupValue.Length) == 0) { int offset = 0; byte[] objectKey = null; if (indexStore.RazorFormatVersion < 2) { if (ByteArray.CompareMemCmp(key, key.Length - value.Length, value, 0, value.Length) == 0) { objectKey = pair.Value; } } else { int indexKeyLen = Helper.Decode7BitInt(pair.Value, ref offset); if (lookupValue.Length == indexKeyLen) { // Lookup the value of the actual object using the key that was found // get the object key from the index value tail objectKey = ItemKeyFromIndex(pair, indexKeyLen); } } if (objectKey != null) { var primaryValue = this.Get(objectKey); if (primaryValue != null) { yield return(new KeyValuePair <byte[], byte[]>(objectKey, primaryValue)); } } } else { // if the above condition was not met then we must have enumerated past the end of the indexed value yield break; } } }
public void DumpContents(Action <string> msg) { msg(string.Format("Path: {0}", _path)); msg(string.Format("BaseFileName: {0} Level: {1} Version: {2}", _baseFileName, _level, _version)); msg(string.Format("Data Blocks: {0}\nIndex Blocks: {1}\nTotal Blocks: {2}", _dataBlocks, _indexBlocks, _totalBlocks)); msg(""); for (int i = 0; i < _dataBlocks; i++) { msg(string.Format("\n*** Data Block {0} ***", i)); byte[] block = ReadBlock(new byte[Config.SortedBlockSize], i, null); int offset = FormatVersion < 2 ? 2 : 0; // handle old format with 2 bytes for offset to treehead while (offset < Config.SortedBlockSize && block[offset] != (byte)RecordHeaderFlag.EndOfBlock) { // Record var recHdr = (RecordHeaderFlag)block[offset]; msg(string.Format("{0:X4} \"{1}\" {2}", offset, BytesToString(block, offset, 1), (recHdr).ToString())); offset++; bool isPrefixed = recHdr == RecordHeaderFlag.PrefixedRecord; // handle old tree bytes offset += isPrefixed ? 0 : 4; // Key int keyOffset = offset; int keySize = Helper.Decode7BitInt(block, ref offset); msg(string.Format("{0:X4} \"{1}\" KeySize: {2}", keyOffset, BytesToString(block, keyOffset, offset - keyOffset), keySize)); if (isPrefixed) { short prefixLen = (short)(block[offset] << 8 | block[offset + 1]); msg(string.Format("{0:X4} \"{1}\" PrefixLen: {2}", keyOffset, BytesToString(block, offset, 2), prefixLen)); offset += 2; } msg(string.Format("{0:X4} \"{1}\"", offset, BytesToString(block, offset, keySize))); offset += keySize; // Data int dataOffset = offset; int dataSize = Helper.Decode7BitInt(block, ref offset); msg(string.Format("{0:X4} \"{1}\" DataSize: {2}", dataOffset, BytesToString(block, dataOffset, offset - dataOffset), dataSize)); msg(string.Format("{0:X4} \"{1}\"", offset, BytesToString(block, offset, dataSize))); offset += dataSize; } } }
private bool ScanBlockForKey(byte[] block, Key key, out Value value) { int offset = FormatVersion < 2 ? 2 : 0; // handle old format with 2 bytes for offset to treehead value = Value.Empty; while (offset >= 0 && offset < Config.SortedBlockSize && ((block[offset] & (byte)(RecordHeaderFlag.Record | RecordHeaderFlag.PrefixedRecord)) == block[offset])) { // read record header bool isPrefixed = block[offset] == (byte)RecordHeaderFlag.PrefixedRecord; offset += FormatVersion < 2 ? 5 : 1; // skip bytes of old tree blocks int keySize = Helper.Decode7BitInt(block, ref offset); int cmp; if (isPrefixed) { var prefixLen = (short)(block[offset] << 8 | block[offset + 1]); // prefix used len in two bytes offset += 2; cmp = key.PrefixCompareTo(_lastScanKey, prefixLen, block, offset, keySize, out _lastScanKey); } else { cmp = key.CompareTo(block, offset, keySize); } offset += keySize; if (cmp == 0) { // Found it value = ReadValue(ref block, ref offset); return(true); } else if (cmp < 0) { return(false); } // Skip past the value int valueSize = Helper.Decode7BitInt(block, ref offset); offset += valueSize; } return(false); }
private RawRecord ReadRawRecord(ref byte[] block, ref int offset) { var hdrFlag = (RecordHeaderFlag)block[offset]; #if DEBUG if ((byte)(hdrFlag & (RecordHeaderFlag.Record | RecordHeaderFlag.PrefixedRecord)) == 0x00) { System.Diagnostics.Debugger.Break(); } #endif offset += FormatVersion < 2 ? 5 : 1; // skip bytes of old tree blocks bool isPrefixed = hdrFlag == RecordHeaderFlag.PrefixedRecord; int keySize = Helper.Decode7BitInt(block, ref offset); short prefixLen = isPrefixed ? (short)(block[offset] << 8 | block[offset + 1]) : (short)0; offset += isPrefixed ? 2 : 0; Key key = new Key(ByteArray.From(block, offset, keySize)); offset += keySize; return(new RawRecord(key, ReadValue(ref block, ref offset), hdrFlag)); }
/// <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; } } }