]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 7.4.1891 v7.4.1891
authorBram Moolenaar <Bram@vim.org>
Sat, 4 Jun 2016 15:17:11 +0000 (17:17 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 4 Jun 2016 15:17:11 +0000 (17:17 +0200)
Problem:    Channel reading very long lines is slow.
Solution:   Collapse multiple buffers until a NL is found.

src/channel.c
src/netbeans.c
src/proto/channel.pro
src/structs.h
src/version.c

index 5168f7410d7def0eb57f2ddf99e1ef5d74101257..ae894704ceaf85281dea76a34dd139d6ea1ccca4 100644 (file)
@@ -1592,13 +1592,17 @@ channel_get_all(channel_T *channel, int part)
 
     /* Concatenate everything into one buffer. */
     for (node = head->rq_next; node != NULL; node = node->rq_next)
-       len += (long_u)STRLEN(node->rq_buffer);
+       len += node->rq_buflen;
     res = lalloc(len, TRUE);
     if (res == NULL)
        return NULL;
-    *res = NUL;
+    p = res;
     for (node = head->rq_next; node != NULL; node = node->rq_next)
-       STRCAT(res, node->rq_buffer);
+    {
+       STRCPY(p, node->rq_buffer);
+       p += node->rq_buflen;
+    }
+    *p = NUL;
 
     /* Free all buffers */
     do
@@ -1613,31 +1617,59 @@ channel_get_all(channel_T *channel, int part)
 /*
  * Collapses the first and second buffer for "channel"/"part".
  * Returns FAIL if that is not possible.
+ * When "want_nl" is TRUE collapse more buffers until a NL is found.
  */
     int
-channel_collapse(channel_T *channel, int part)
+channel_collapse(channel_T *channel, int part, int want_nl)
 {
     readq_T *head = &channel->ch_part[part].ch_head;
     readq_T *node = head->rq_next;
+    readq_T *last_node;
+    readq_T *n;
+    char_u  *newbuf;
     char_u  *p;
+    long_u len;
 
     if (node == NULL || node->rq_next == NULL)
        return FAIL;
 
-    p = alloc((unsigned)(STRLEN(node->rq_buffer)
-                                    + STRLEN(node->rq_next->rq_buffer) + 1));
-    if (p == NULL)
+    last_node = node->rq_next;
+    len = node->rq_buflen + last_node->rq_buflen + 1;
+    if (want_nl)
+       while (last_node->rq_next != NULL
+               && vim_strchr(last_node->rq_buffer, NL) == NULL)
+       {
+           last_node = last_node->rq_next;
+           len += last_node->rq_buflen;
+       }
+
+    p = newbuf = alloc(len);
+    if (newbuf == NULL)
        return FAIL;        /* out of memory */
     STRCPY(p, node->rq_buffer);
-    STRCAT(p, node->rq_next->rq_buffer);
-    vim_free(node->rq_next->rq_buffer);
-    node->rq_next->rq_buffer = p;
-
-    /* dispose of the node and its buffer */
-    head->rq_next = node->rq_next;
-    head->rq_next->rq_prev = NULL;
+    p += node->rq_buflen;
     vim_free(node->rq_buffer);
-    vim_free(node);
+    node->rq_buffer = newbuf;
+    for (n = node; n != last_node; )
+    {
+       n = n->rq_next;
+       STRCPY(p, n->rq_buffer);
+       p += n->rq_buflen;
+       vim_free(n->rq_buffer);
+    }
+
+    /* dispose of the collapsed nodes and their buffers */
+    for (n = node->rq_next; n != last_node; )
+    {
+       n = n->rq_next;
+       vim_free(n->rq_prev);
+    }
+    node->rq_next = last_node->rq_next;
+    if (last_node->rq_next == NULL)
+       head->rq_prev = node;
+    else
+       last_node->rq_next->rq_prev = node;
+    vim_free(last_node);
     return OK;
 }
 
@@ -1673,11 +1705,13 @@ channel_save(channel_T *channel, int part, char_u *buf, int len,
            if (buf[i] != CAR || i + 1 >= len || buf[i + 1] != NL)
                *p++ = buf[i];
        *p = NUL;
+       node->rq_buflen = (long_u)(p - node->rq_buffer);
     }
     else
     {
        mch_memmove(node->rq_buffer, buf, len);
        node->rq_buffer[len] = NUL;
+       node->rq_buflen = (long_u)len;
     }
 
     if (prepend)
@@ -2024,7 +2058,7 @@ channel_exe_cmd(channel_T *channel, int part, typval_T *argv)
 #ifdef FEAT_GUI
        if (gui.in_use)
        {
-           gui_update_cursor(FALSE, FALSE);
+           gui_update_cursor(TRUE, FALSE);
            gui_mch_flush();
        }
 #endif
@@ -2349,7 +2383,7 @@ may_invoke_callback(channel_T *channel, int part)
                nl = vim_strchr(buf, NL);
                if (nl != NULL)
                    break;
-               if (channel_collapse(channel, part) == FAIL)
+               if (channel_collapse(channel, part, TRUE) == FAIL)
                    return FALSE; /* incomplete message */
            }
            if (nl[1] == NUL)
@@ -3018,7 +3052,8 @@ channel_read_block(channel_T *channel, int part, int timeout)
        if (buf != NULL && (mode == MODE_RAW
                         || (mode == MODE_NL && vim_strchr(buf, NL) != NULL)))
            break;
-       if (buf != NULL && channel_collapse(channel, part) == OK)
+       if (buf != NULL && channel_collapse(channel, part, mode == MODE_NL)
+                                                                       == OK)
            continue;
 
        /* Wait for up to the channel timeout. */
index a80067f43721b66aaa063d75aefa786cc88b261e..3eaf2a2b81629e9efaf614f7b4abaf832d7edd0b 100644 (file)
@@ -399,7 +399,7 @@ netbeans_parse_messages(void)
            /* Command isn't complete.  If there is no following buffer,
             * return (wait for more). If there is another buffer following,
             * prepend the text to that buffer and delete this one.  */
-           if (channel_collapse(nb_channel, PART_SOCK) == FAIL)
+           if (channel_collapse(nb_channel, PART_SOCK, TRUE) == FAIL)
                return;
        }
        else
index 2f2deb4bc852a8ca4131b3cf29dfbdb60d4b5888..52bced3b93b2106d67b8978fd2651149ecdc7328 100644 (file)
@@ -18,7 +18,7 @@ void channel_buffer_free(buf_T *buf);
 void channel_write_any_lines(void);
 void channel_write_new_lines(buf_T *buf);
 char_u *channel_get(channel_T *channel, int part);
-int channel_collapse(channel_T *channel, int part);
+int channel_collapse(channel_T *channel, int part, int want_nl);
 int channel_can_write_to(channel_T *channel);
 int channel_is_open(channel_T *channel);
 char *channel_status(channel_T *channel);
index d9498e4d934e3c62c084598484c38c9715b76427..5ecb806cf734397309e9e2348359c170919d62fb 100644 (file)
@@ -1309,6 +1309,7 @@ struct jobvar_S
 struct readq_S
 {
     char_u     *rq_buffer;
+    long_u     rq_buflen;
     readq_T    *rq_next;
     readq_T    *rq_prev;
 };
index ce8b8d0a65157270cb3d8f16d13968f73b844832..a90b47e65eb85b7f676ce9826f0e3c53f262c257 100644 (file)
@@ -753,6 +753,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1891,
 /**/
     1890,
 /**/