(websocket) use persistent member variable as temp variables to encode/decode zlib messages in order to reduce transient allocations
This commit is contained in:
		@@ -1,6 +1,10 @@
 | 
			
		||||
# Changelog
 | 
			
		||||
All changes to this project will be documented in this file.
 | 
			
		||||
 | 
			
		||||
## [9.2.4] - 2020-04-13
 | 
			
		||||
 | 
			
		||||
(websocket) use persistent member variable as temp variables to encode/decode zlib messages in order to reduce transient allocations
 | 
			
		||||
 | 
			
		||||
## [9.2.3] - 2020-04-13
 | 
			
		||||
 | 
			
		||||
(ws) add a --runtime option to ws cobra_subscribe to optionally limit how much time it will run
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ namespace ix
 | 
			
		||||
    struct WebSocketMessage
 | 
			
		||||
    {
 | 
			
		||||
        WebSocketMessageType type;
 | 
			
		||||
        std::string str;
 | 
			
		||||
        const std::string& str;
 | 
			
		||||
        size_t wireSize;
 | 
			
		||||
        WebSocketErrorInfo errorInfo;
 | 
			
		||||
        WebSocketOpenInfo openInfo;
 | 
			
		||||
@@ -34,7 +34,7 @@ namespace ix
 | 
			
		||||
                         WebSocketCloseInfo c,
 | 
			
		||||
                         bool b = false)
 | 
			
		||||
            : type(t)
 | 
			
		||||
            , str(std::move(s))
 | 
			
		||||
            , str(s)
 | 
			
		||||
            , wireSize(w)
 | 
			
		||||
            , errorInfo(e)
 | 
			
		||||
            , openInfo(o)
 | 
			
		||||
 
 | 
			
		||||
@@ -87,6 +87,9 @@ namespace ix
 | 
			
		||||
        //
 | 
			
		||||
        size_t output;
 | 
			
		||||
 | 
			
		||||
        // Clear output
 | 
			
		||||
        out.clear();
 | 
			
		||||
 | 
			
		||||
        if (in.empty())
 | 
			
		||||
        {
 | 
			
		||||
            // See issue #167
 | 
			
		||||
@@ -174,6 +177,9 @@ namespace ix
 | 
			
		||||
        _inflateState.avail_in = (uInt) inFixed.size();
 | 
			
		||||
        _inflateState.next_in = (unsigned char*) (const_cast<char*>(inFixed.data()));
 | 
			
		||||
 | 
			
		||||
        // Clear output
 | 
			
		||||
        out.clear();
 | 
			
		||||
 | 
			
		||||
        do
 | 
			
		||||
        {
 | 
			
		||||
            _inflateState.avail_out = (uInt) _compressBufferSize;
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,7 @@ namespace ix
 | 
			
		||||
    WebSocketTransport::WebSocketTransport()
 | 
			
		||||
        : _useMask(true)
 | 
			
		||||
        , _blockingSend(false)
 | 
			
		||||
        , _compressedMessage(false)
 | 
			
		||||
        , _receivedMessageCompressed(false)
 | 
			
		||||
        , _readyState(ReadyState::CLOSED)
 | 
			
		||||
        , _closeCode(WebSocketCloseConstants::kInternalErrorCode)
 | 
			
		||||
        , _closeReason(WebSocketCloseConstants::kInternalErrorMessage)
 | 
			
		||||
@@ -493,7 +493,7 @@ namespace ix
 | 
			
		||||
                                                 ? MessageKind::MSG_TEXT
 | 
			
		||||
                                                 : MessageKind::MSG_BINARY;
 | 
			
		||||
 | 
			
		||||
                    _compressedMessage = _enablePerMessageDeflate && ws.rsv1;
 | 
			
		||||
                    _receivedMessageCompressed = _enablePerMessageDeflate && ws.rsv1;
 | 
			
		||||
 | 
			
		||||
                    // Continuation message needs to follow a non-fin TEXT or BINARY message
 | 
			
		||||
                    if (!_chunks.empty())
 | 
			
		||||
@@ -516,9 +516,9 @@ namespace ix
 | 
			
		||||
                if (ws.fin && _chunks.empty())
 | 
			
		||||
                {
 | 
			
		||||
                    emitMessage(
 | 
			
		||||
                        _fragmentedMessageKind, frameData, _compressedMessage, onMessageCallback);
 | 
			
		||||
                        _fragmentedMessageKind, frameData, _receivedMessageCompressed, onMessageCallback);
 | 
			
		||||
 | 
			
		||||
                    _compressedMessage = false;
 | 
			
		||||
                    _receivedMessageCompressed = false;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
@@ -535,11 +535,11 @@ namespace ix
 | 
			
		||||
                    {
 | 
			
		||||
                        emitMessage(_fragmentedMessageKind,
 | 
			
		||||
                                    getMergedChunks(),
 | 
			
		||||
                                    _compressedMessage,
 | 
			
		||||
                                    _receivedMessageCompressed,
 | 
			
		||||
                                    onMessageCallback);
 | 
			
		||||
 | 
			
		||||
                        _chunks.clear();
 | 
			
		||||
                        _compressedMessage = false;
 | 
			
		||||
                        _receivedMessageCompressed = false;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
@@ -712,17 +712,16 @@ namespace ix
 | 
			
		||||
        // When the RSV1 bit is 1 it means the message is compressed
 | 
			
		||||
        if (compressedMessage && messageKind != MessageKind::FRAGMENT)
 | 
			
		||||
        {
 | 
			
		||||
            std::string decompressedMessage;
 | 
			
		||||
            bool success = _perMessageDeflate->decompress(message, decompressedMessage);
 | 
			
		||||
            bool success = _perMessageDeflate->decompress(message, _decompressedMessage);
 | 
			
		||||
 | 
			
		||||
            if (messageKind == MessageKind::MSG_TEXT && !validateUtf8(decompressedMessage))
 | 
			
		||||
            if (messageKind == MessageKind::MSG_TEXT && !validateUtf8(_decompressedMessage))
 | 
			
		||||
            {
 | 
			
		||||
                close(WebSocketCloseConstants::kInvalidFramePayloadData,
 | 
			
		||||
                      WebSocketCloseConstants::kInvalidFramePayloadDataMessage);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                onMessageCallback(decompressedMessage, wireSize, !success, messageKind);
 | 
			
		||||
                onMessageCallback(_decompressedMessage, wireSize, !success, messageKind);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
@@ -759,7 +758,6 @@ namespace ix
 | 
			
		||||
 | 
			
		||||
        size_t payloadSize = message.size();
 | 
			
		||||
        size_t wireSize = message.size();
 | 
			
		||||
        std::string compressedMessage;
 | 
			
		||||
        bool compressionError = false;
 | 
			
		||||
 | 
			
		||||
        std::string::const_iterator message_begin = message.begin();
 | 
			
		||||
@@ -767,7 +765,7 @@ namespace ix
 | 
			
		||||
 | 
			
		||||
        if (compress)
 | 
			
		||||
        {
 | 
			
		||||
            if (!_perMessageDeflate->compress(message, compressedMessage))
 | 
			
		||||
            if (!_perMessageDeflate->compress(message, _compressedMessage))
 | 
			
		||||
            {
 | 
			
		||||
                bool success = false;
 | 
			
		||||
                compressionError = true;
 | 
			
		||||
@@ -776,10 +774,10 @@ namespace ix
 | 
			
		||||
                return WebSocketSendInfo(success, compressionError, payloadSize, wireSize);
 | 
			
		||||
            }
 | 
			
		||||
            compressionError = false;
 | 
			
		||||
            wireSize = compressedMessage.size();
 | 
			
		||||
            wireSize = _compressedMessage.size();
 | 
			
		||||
 | 
			
		||||
            message_begin = compressedMessage.begin();
 | 
			
		||||
            message_end = compressedMessage.end();
 | 
			
		||||
            message_begin = _compressedMessage.begin();
 | 
			
		||||
            message_end = _compressedMessage.end();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -165,7 +165,7 @@ namespace ix
 | 
			
		||||
        MessageKind _fragmentedMessageKind;
 | 
			
		||||
 | 
			
		||||
        // Ditto for whether a message is compressed
 | 
			
		||||
        bool _compressedMessage;
 | 
			
		||||
        bool _receivedMessageCompressed;
 | 
			
		||||
 | 
			
		||||
        // Fragments are 32K long
 | 
			
		||||
        static constexpr size_t kChunkSize = 1 << 15;
 | 
			
		||||
@@ -189,6 +189,9 @@ namespace ix
 | 
			
		||||
        WebSocketPerMessageDeflateOptions _perMessageDeflateOptions;
 | 
			
		||||
        std::atomic<bool> _enablePerMessageDeflate;
 | 
			
		||||
 | 
			
		||||
        std::string _decompressedMessage;
 | 
			
		||||
        std::string _compressedMessage;
 | 
			
		||||
 | 
			
		||||
        // Used to control TLS connection behavior
 | 
			
		||||
        SocketTLSOptions _socketTLSOptions;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,4 +6,4 @@
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define IX_WEBSOCKET_VERSION "9.2.3"
 | 
			
		||||
#define IX_WEBSOCKET_VERSION "9.2.4"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user