Пример #1
0
        public static ByteStringContext <ByteStringMemoryCache> .InternalScope GetSliceFromId <TTransaction>(
            TransactionOperationContext <TTransaction> context, string id, out Slice idSlice,
            byte?separator = null)
            where TTransaction : RavenTransaction
        {
            if (_jsonParserState == null)
            {
                _jsonParserState = new JsonParserState();
            }

            _jsonParserState.Reset();

            var strLength = id.Length;

            var maxStrSize          = Encoding.GetMaxByteCount(strLength);
            var escapePositionsSize = JsonParserState.FindEscapePositionsMaxSize(id, out _);

            if (strLength > MaxIdSize)
            {
                ThrowDocumentIdTooBig(id);
            }

            var internalScope = context.Allocator.Allocate(
                maxStrSize // this buffer is allocated to also serve the GetSliceFromUnicodeKey
                + sizeof(char) * id.Length
                + escapePositionsSize
                + (separator != null ? 1 : 0),
                out var buffer);

            idSlice = new Slice(buffer);

            for (var i = 0; i < id.Length; i++)
            {
                var ch = id[i];
                if (ch > 127) // not ASCII, use slower mode
                {
                    strLength = ReadFromUnicodeKey(id, buffer, maxStrSize, separator);
                    goto Finish;
                }
                if ((ch >= 65) && (ch <= 90))
                {
                    buffer.Ptr[i] = (byte)(ch | 0x20);
                }
                else
                {
                    buffer.Ptr[i] = (byte)ch;
                }
            }

            _jsonParserState.FindEscapePositionsIn(buffer.Ptr, ref strLength, escapePositionsSize);
            if (separator != null)
            {
                buffer.Ptr[strLength] = separator.Value;
                strLength++;
            }

Finish:
            buffer.Truncate(strLength);
            return(internalScope);
        }
Пример #2
0
        private BlittableJsonReaderObject ReadObjectInternal(object builder, string documentId,
                                                             BlittableJsonDocumentBuilder.UsageMode mode, IBlittableDocumentModifier modifier = null)
        {
            _jsonParserState.Reset();
            _objectJsonParser.Reset(builder);
            _documentBuilder.Renew(documentId, mode);
            CachedProperties.NewDocument();
            _documentBuilder._modifier = modifier;
            _documentBuilder.ReadObjectDocument();
            if (_documentBuilder.Read() == false)
            {
                throw new InvalidOperationException("Partial content in object json parser shouldn't happen");
            }
            _documentBuilder.FinalizeDocument();

            _objectJsonParser.Reset(null);

            var reader = _documentBuilder.CreateReader();

            return(reader);
        }
Пример #3
0
        public static ByteStringContext.InternalScope GetLowerIdSliceAndStorageKey <TTransaction>(
            TransactionOperationContext <TTransaction> context, string str, out Slice lowerIdSlice, out Slice idSlice)
            where TTransaction : RavenTransaction
        {
            // 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();

            int strLength  = str.Length;
            int maxStrSize = Encoding.GetMaxByteCount(strLength);

            int idSize = JsonParserState.VariableSizeIntSize(strLength);

            int escapePositionsSize = JsonParserState.FindEscapePositionsMaxSize(str);

            var scope = context.Allocator.Allocate(maxStrSize   // lower key
                                                   + idSize     // the size of var int for the len of the key
                                                   + maxStrSize // actual key
                                                   + escapePositionsSize, out ByteString buffer);


            byte *ptr = buffer.Ptr;

            fixed(char *pChars = str)
            {
                for (var i = 0; i < strLength; i++)
                {
                    uint ch = pChars[i];

                    // PERF: Trick to avoid multiple compare instructions on hot loops.
                    //       This is the same as (ch >= 65 && ch <= 90)
                    if (ch - 65 <= 90 - 65)
                    {
                        ptr[i] = (byte)(ch | 0x20);
                    }
                    else
                    {
                        if (ch > 127) // not ASCII, use slower mode
                        {
                            goto UnlikelyUnicode;
                        }

                        ptr[i] = (byte)ch;
                    }

                    ptr[i + idSize + maxStrSize] = (byte)ch;
                }

                _jsonParserState.FindEscapePositionsIn(ptr, strLength, escapePositionsSize);
            }

            var writePos = ptr + maxStrSize;

            JsonParserState.WriteVariableSizeInt(ref writePos, strLength);
            escapePositionsSize = _jsonParserState.WriteEscapePositionsTo(writePos + strLength);
            idSize = escapePositionsSize + strLength + idSize;

            Slice.External(context.Allocator, ptr + maxStrSize, idSize, out idSlice);
            Slice.External(context.Allocator, ptr, str.Length, out lowerIdSlice);
            return(scope);

UnlikelyUnicode:
            scope.Dispose();
            return(UnicodeGetLowerIdAndStorageKey(context, str, out lowerIdSlice, out idSlice, maxStrSize, escapePositionsSize));
        }
Пример #4
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);
        }