private static void UnicodeGetLowerKeySliceAndStorageKey(JsonOperationContext context, string str, out byte *lowerKey, out int lowerSize, out byte *key, out int keySize) { // See comment in GetLowerKeySliceAndStorageKey for the format _jsonParserState.Reset(); var byteCount = Utf8.GetMaxByteCount(str.Length); _jsonParserState.FindEscapePositionsIn(str); var maxKeyLenSize = JsonParserState.VariableSizeIntSize(byteCount); var escapePositionsSize = _jsonParserState.GetEscapePositionsSize(); var buffer = context.GetNativeTempBuffer( sizeof(char) * str.Length // for the lower calls + byteCount // lower key + maxKeyLenSize // the size of var int for the len of the key + byteCount // actual key + escapePositionsSize); fixed(char *pChars = str) { var destChars = (char *)buffer; for (var i = 0; i < str.Length; i++) { destChars[i] = char.ToLowerInvariant(pChars[i]); } lowerKey = buffer + str.Length * sizeof(char); lowerSize = Utf8.GetBytes(destChars, str.Length, lowerKey, byteCount); if (lowerSize > 512) { ThrowKeyTooBig(str); } key = buffer + str.Length * sizeof(char) + byteCount; var writePos = key; keySize = Utf8.GetBytes(pChars, str.Length, writePos + maxKeyLenSize, byteCount); var actualKeyLenSize = JsonParserState.VariableSizeIntSize(keySize); if (actualKeyLenSize < maxKeyLenSize) { var movePtr = maxKeyLenSize - actualKeyLenSize; key += movePtr; writePos += movePtr; } JsonParserState.WriteVariableSizeInt(ref writePos, keySize); _jsonParserState.WriteEscapePositionsTo(writePos + keySize); keySize += escapePositionsSize + maxKeyLenSize; } }
private void SetStringBuffer(string str) { // max possible size - we avoid using GetByteCount because profiling showed it to take 2% of runtime // the buffer might be a bit longer, but we'll reuse it, and it is better than the computing cost int size = Encoding.UTF8.GetMaxByteCount(str.Length); _state.FindEscapePositionsIn(str); size += _state.GetEscapePositionsSize(); _state.StringBuffer = _ctx.GetNativeTempBuffer(size); fixed(char *pChars = str) { _state.StringSize = Utf8Encoding.GetBytes(pChars, str.Length, _state.StringBuffer, size); var escapePos = _state.StringBuffer + _state.StringSize; _state.WriteEscapePositionsTo(escapePos); } }
public unsafe StringCollectionValue(List <string> values, JsonOperationContext context) { #if DEBUG _values = values; #endif if (values.Count == 0) { ThrowEmptyFacets(); } _hashCode = values.Count; _hash = (uint)values.Count; int size = 0; foreach (var value in values) { size += value.Length; } var buffer = context.GetNativeTempBuffer(size * sizeof(char)); var destChars = (char *)buffer; var position = 0; foreach (var value in values) { for (var i = 0; i < value.Length; i++) { destChars[position++] = value[i]; } unchecked { _hashCode = _hashCode * 397 ^ value.GetHashCode(); } } _hash = Hashing.XXHash32.Calculate(buffer, size); }
private static unsafe uint CalculateQueryFieldsHash(FacetQuery query, JsonOperationContext context) { int size = 0; // ReSharper disable once LoopCanBeConvertedToQuery foreach (var s in query.FieldsToFetch) { size += s.Length; } var buffer = context.GetNativeTempBuffer(size * sizeof(char)); var destChars = (char *)buffer; var position = 0; foreach (var field in query.FieldsToFetch) { for (var i = 0; i < field.Length; i++) { destChars[position++] = field[i]; } } return(Hashing.XXHash32.Calculate(buffer, size)); }
public static void GetLowerKeySliceAndStorageKey(JsonOperationContext context, string str, out byte *lowerKey, out int lowerSize, out byte *key, out int keySize) { // Because we need to also store escape positions for the key when we store it // we need to store it as a lazy string value. // But lazy string value has two lengths, one is the string length, and the other // is the actual data size with the escape positions // In order to resolve this, we process the key to find escape positions, then store it // in the table using the following format: // // [var int - string len, string bytes, number of escape positions, escape positions] // // The total length of the string is stored in the actual table (and include the var int size // prefix. if (_jsonParserState == null) { _jsonParserState = new JsonParserState(); } _jsonParserState.Reset(); keySize = JsonParserState.VariableSizeIntSize(str.Length); _jsonParserState.FindEscapePositionsIn(str); var escapePositionsSize = _jsonParserState.GetEscapePositionsSize(); var buffer = context.GetNativeTempBuffer( str.Length // lower key + keySize // the size of var int for the len of the key + str.Length // actual key + escapePositionsSize); for (var i = 0; i < str.Length; i++) { var ch = str[i]; if (ch > 127) // not ASCII, use slower mode { goto UnlikelyUnicode; } if ((ch >= 65) && (ch <= 90)) { buffer[i] = (byte)(ch | 0x20); } else { buffer[i] = (byte)ch; } buffer[i + keySize + str.Length] = (byte)ch; } var writePos = buffer + str.Length; JsonParserState.WriteVariableSizeInt(ref writePos, str.Length); _jsonParserState.WriteEscapePositionsTo(writePos + str.Length); keySize = escapePositionsSize + str.Length + keySize; key = buffer + str.Length; lowerKey = buffer; lowerSize = str.Length; return; UnlikelyUnicode: UnicodeGetLowerKeySliceAndStorageKey(context, str, out lowerKey, out lowerSize, out key, out keySize); }