示例#1
0
        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;
            }
        }
示例#2
0
        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);
            }
示例#4
0
        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));
        }
示例#5
0
        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);
        }