Patch 7.4.1891
Problem:    Channel reading very long lines is slow.
Solution:   Collapse multiple buffers until a NL is found.
Files:      src/channel.c, src/netbeans.c, src/proto/channel.pro,
            src/structs.h


*** ../vim-7.4.1890/src/channel.c       2016-06-02 20:05:22.480384217 +0200
--- src/channel.c       2016-06-04 17:14:10.898148509 +0200
***************
*** 1592,1604 ****
  
      /* Concatenate everything into one buffer. */
      for (node = head->rq_next; node != NULL; node = node->rq_next)
!       len += (long_u)STRLEN(node->rq_buffer);
      res = lalloc(len, TRUE);
      if (res == NULL)
        return NULL;
!     *res = NUL;
      for (node = head->rq_next; node != NULL; node = node->rq_next)
!       STRCAT(res, node->rq_buffer);
  
      /* Free all buffers */
      do
--- 1592,1608 ----
  
      /* Concatenate everything into one buffer. */
      for (node = head->rq_next; node != NULL; node = node->rq_next)
!       len += node->rq_buflen;
      res = lalloc(len, TRUE);
      if (res == NULL)
        return NULL;
!     p = res;
      for (node = head->rq_next; node != NULL; node = node->rq_next)
!     {
!       STRCPY(p, node->rq_buffer);
!       p += node->rq_buflen;
!     }
!     *p = NUL;
  
      /* Free all buffers */
      do
***************
*** 1613,1643 ****
  /*
   * Collapses the first and second buffer for "channel"/"part".
   * Returns FAIL if that is not possible.
   */
      int
! channel_collapse(channel_T *channel, int part)
  {
      readq_T *head = &channel->ch_part[part].ch_head;
      readq_T *node = head->rq_next;
      char_u  *p;
  
      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)
        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;
      vim_free(node->rq_buffer);
!     vim_free(node);
      return OK;
  }
  
--- 1617,1675 ----
  /*
   * 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, 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;
  
!     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);
!     p += node->rq_buflen;
      vim_free(node->rq_buffer);
!     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,1683 ****
--- 1705,1717 ----
            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,2030 ****
  #ifdef FEAT_GUI
        if (gui.in_use)
        {
!           gui_update_cursor(FALSE, FALSE);
            gui_mch_flush();
        }
  #endif
--- 2058,2064 ----
  #ifdef FEAT_GUI
        if (gui.in_use)
        {
!           gui_update_cursor(TRUE, FALSE);
            gui_mch_flush();
        }
  #endif
***************
*** 2349,2355 ****
                nl = vim_strchr(buf, NL);
                if (nl != NULL)
                    break;
!               if (channel_collapse(channel, part) == FAIL)
                    return FALSE; /* incomplete message */
            }
            if (nl[1] == NUL)
--- 2383,2389 ----
                nl = vim_strchr(buf, NL);
                if (nl != NULL)
                    break;
!               if (channel_collapse(channel, part, TRUE) == FAIL)
                    return FALSE; /* incomplete message */
            }
            if (nl[1] == NUL)
***************
*** 3018,3024 ****
        if (buf != NULL && (mode == MODE_RAW
                         || (mode == MODE_NL && vim_strchr(buf, NL) != NULL)))
            break;
!       if (buf != NULL && channel_collapse(channel, part) == OK)
            continue;
  
        /* Wait for up to the channel timeout. */
--- 3052,3059 ----
        if (buf != NULL && (mode == MODE_RAW
                         || (mode == MODE_NL && vim_strchr(buf, NL) != NULL)))
            break;
!       if (buf != NULL && channel_collapse(channel, part, mode == MODE_NL)
!                                                                       == OK)
            continue;
  
        /* Wait for up to the channel timeout. */
*** ../vim-7.4.1890/src/netbeans.c      2016-04-30 18:06:47.114331342 +0200
--- src/netbeans.c      2016-06-04 16:57:10.998162539 +0200
***************
*** 399,405 ****
            /* 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)
                return;
        }
        else
--- 399,405 ----
            /* 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, TRUE) == FAIL)
                return;
        }
        else
*** ../vim-7.4.1890/src/proto/channel.pro       2016-06-02 20:05:22.480384217 
+0200
--- src/proto/channel.pro       2016-06-04 16:58:02.154161835 +0200
***************
*** 18,24 ****
  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_can_write_to(channel_T *channel);
  int channel_is_open(channel_T *channel);
  char *channel_status(channel_T *channel);
--- 18,24 ----
  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 want_nl);
  int channel_can_write_to(channel_T *channel);
  int channel_is_open(channel_T *channel);
  char *channel_status(channel_T *channel);
*** ../vim-7.4.1890/src/structs.h       2016-06-03 19:05:37.287245034 +0200
--- src/structs.h       2016-06-04 17:05:51.546155378 +0200
***************
*** 1309,1314 ****
--- 1309,1315 ----
  struct readq_S
  {
      char_u    *rq_buffer;
+     long_u    rq_buflen;
      readq_T   *rq_next;
      readq_T   *rq_prev;
  };
*** ../vim-7.4.1890/src/version.c       2016-06-04 16:24:28.918189529 +0200
--- src/version.c       2016-06-04 17:15:34.778147355 +0200
***************
*** 755,756 ****
--- 755,758 ----
  {   /* Add new patch number below this line */
+ /**/
+     1891,
  /**/

-- 
"Oh, no!  NOT the Spanish Inquisition!"
"NOBODY expects the Spanish Inquisition!!!"
                                -- Monty Python sketch --
"Oh, no!  NOT another option!"
"EVERYBODY expects another option!!!"
                                -- Discussion in vim-dev mailing list --

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui