From: "Adeodato Simó" <dato@net.com.org.es>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Clemens Buchacher <drizzd@aon.at>,
Johannes Schindelin <Johannes.Schindelin@gmx.de>,
Pierre Habouzit <madcoder@debian.org>,
davidel@xmailserver.org, Francis Galiegue <fg@one2team.net>,
Git ML <git@vger.kernel.org>
Subject: Re: [PATCH 0/3] Teach Git about the patience diff algorithm
Date: Thu, 8 Jan 2009 20:55:11 +0100 [thread overview]
Message-ID: <20090108195511.GA8734@chistera.yi.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 1062 bytes --]
* Linus Torvalds [Fri, 02 Jan 2009 08:42:04 -0800]:
> Yes, this one is a real patience diff change, but it's also the same one
> that I've seen in the google fanboi findings. What google did _not_ show
> was any real-life examples, or anybody doing any critical analysis.
This comes a bit late and maybe it's redundant, but somebody just sent
to a Debian mailing list a patch that was hard to read, and patience
improved it. (I realize it's quite similar in spirit to the "toy
patience example" that google returns, but this at list is a *real*
example where patience helped me read a patch.)
I'm also attaching bzr diff output, because it's still more readable
IMHO. (I realize that's independent of patience, as you explained, but
I'm making a point that it'd be nice to have this addressed by somebody
knowledgeable.)
Thanks,
--
Adeodato Simó dato at net.com.org.es
Debian Developer adeodato at debian.org
- Are you sure we're good?
- Always.
-- Rory and Lorelai
[-- Attachment #2: git.diff --]
[-- Type: text/x-diff, Size: 3615 bytes --]
diff --git util_sock.c util_sock.c
index e20768e..f7b9145 100644
--- util_sock.c
+++ util_sock.c
@@ -1037,40 +1037,109 @@ NTSTATUS read_data(int fd, char *buffer, size_t N)
}
/****************************************************************************
- Write data to a fd.
+ Write all data from an iov array
****************************************************************************/
-ssize_t write_data(int fd, const char *buffer, size_t N)
+ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
{
- size_t total=0;
- ssize_t ret;
- char addr[INET6_ADDRSTRLEN];
+ int i;
+ size_t to_send;
+ ssize_t thistime;
+ size_t sent;
+ struct iovec *iov_copy, *iov;
- while (total < N) {
- ret = sys_write(fd,buffer + total,N - total);
+ to_send = 0;
+ for (i=0; i<iovcnt; i++) {
+ to_send += orig_iov[i].iov_len;
+ }
- if (ret == -1) {
- if (fd == get_client_fd()) {
- /* Try and give an error message saying
- * what client failed. */
- DEBUG(0,("write_data: write failure in "
- "writing to client %s. Error %s\n",
- get_peer_addr(fd,addr,sizeof(addr)),
- strerror(errno) ));
- } else {
- DEBUG(0,("write_data: write failure. "
- "Error = %s\n", strerror(errno) ));
+ thistime = sys_writev(fd, orig_iov, iovcnt);
+ if ((thistime <= 0) || (thistime == to_send)) {
+ return thistime;
+ }
+ sent = thistime;
+
+ /*
+ * We could not send everything in one call. Make a copy of iov that
+ * we can mess with. We keep a copy of the array start in iov_copy for
+ * the TALLOC_FREE, because we're going to modify iov later on,
+ * discarding elements.
+ */
+
+ iov_copy = (struct iovec *)TALLOC_MEMDUP(
+ talloc_tos(), orig_iov, sizeof(struct iovec) * iovcnt);
+
+ if (iov_copy == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ iov = iov_copy;
+
+ while (sent < to_send) {
+ /*
+ * We have to discard "thistime" bytes from the beginning
+ * iov array, "thistime" contains the number of bytes sent
+ * via writev last.
+ */
+ while (thistime > 0) {
+ if (thistime < iov[0].iov_len) {
+ char *new_base =
+ (char *)iov[0].iov_base + thistime;
+ iov[0].iov_base = new_base;
+ iov[0].iov_len -= thistime;
+ break;
}
- return -1;
+ thistime -= iov[0].iov_len;
+ iov += 1;
+ iovcnt -= 1;
}
- if (ret == 0) {
- return total;
+ thistime = sys_writev(fd, iov, iovcnt);
+ if (thistime <= 0) {
+ break;
}
+ sent += thistime;
+ }
+
+ TALLOC_FREE(iov_copy);
+ return sent;
+}
+
+/****************************************************************************
+ Write data to a fd.
+****************************************************************************/
+
+/****************************************************************************
+ Write data to a fd.
+****************************************************************************/
+
+ssize_t write_data(int fd, const char *buffer, size_t N)
+{
+ ssize_t ret;
+ struct iovec iov;
+
+ iov.iov_base = CONST_DISCARD(char *, buffer);
+ iov.iov_len = N;
+
+ ret = write_data_iov(fd, &iov, 1);
+ if (ret >= 0) {
+ return ret;
+ }
- total += ret;
+ if (fd == get_client_fd()) {
+ char addr[INET6_ADDRSTRLEN];
+ /*
+ * Try and give an error message saying what client failed.
+ */
+ DEBUG(0, ("write_data: write failure in writing to client %s. "
+ "Error %s\n", get_peer_addr(fd,addr,sizeof(addr)),
+ strerror(errno)));
+ } else {
+ DEBUG(0,("write_data: write failure. Error = %s\n",
+ strerror(errno) ));
}
- return (ssize_t)total;
+
+ return -1;
}
/****************************************************************************
[-- Attachment #3: git_patience.diff --]
[-- Type: text/x-diff, Size: 3538 bytes --]
diff --git util_sock.c util_sock.c
index e20768e..f7b9145 100644
--- util_sock.c
+++ util_sock.c
@@ -1037,40 +1037,109 @@ NTSTATUS read_data(int fd, char *buffer, size_t N)
}
/****************************************************************************
+ Write all data from an iov array
+****************************************************************************/
+
+ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
+{
+ int i;
+ size_t to_send;
+ ssize_t thistime;
+ size_t sent;
+ struct iovec *iov_copy, *iov;
+
+ to_send = 0;
+ for (i=0; i<iovcnt; i++) {
+ to_send += orig_iov[i].iov_len;
+ }
+
+ thistime = sys_writev(fd, orig_iov, iovcnt);
+ if ((thistime <= 0) || (thistime == to_send)) {
+ return thistime;
+ }
+ sent = thistime;
+
+ /*
+ * We could not send everything in one call. Make a copy of iov that
+ * we can mess with. We keep a copy of the array start in iov_copy for
+ * the TALLOC_FREE, because we're going to modify iov later on,
+ * discarding elements.
+ */
+
+ iov_copy = (struct iovec *)TALLOC_MEMDUP(
+ talloc_tos(), orig_iov, sizeof(struct iovec) * iovcnt);
+
+ if (iov_copy == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ iov = iov_copy;
+
+ while (sent < to_send) {
+ /*
+ * We have to discard "thistime" bytes from the beginning
+ * iov array, "thistime" contains the number of bytes sent
+ * via writev last.
+ */
+ while (thistime > 0) {
+ if (thistime < iov[0].iov_len) {
+ char *new_base =
+ (char *)iov[0].iov_base + thistime;
+ iov[0].iov_base = new_base;
+ iov[0].iov_len -= thistime;
+ break;
+ }
+ thistime -= iov[0].iov_len;
+ iov += 1;
+ iovcnt -= 1;
+ }
+
+ thistime = sys_writev(fd, iov, iovcnt);
+ if (thistime <= 0) {
+ break;
+ }
+ sent += thistime;
+ }
+
+ TALLOC_FREE(iov_copy);
+ return sent;
+}
+
+/****************************************************************************
+ Write data to a fd.
+****************************************************************************/
+
+/****************************************************************************
Write data to a fd.
****************************************************************************/
ssize_t write_data(int fd, const char *buffer, size_t N)
{
- size_t total=0;
ssize_t ret;
- char addr[INET6_ADDRSTRLEN];
+ struct iovec iov;
- while (total < N) {
- ret = sys_write(fd,buffer + total,N - total);
+ iov.iov_base = CONST_DISCARD(char *, buffer);
+ iov.iov_len = N;
- if (ret == -1) {
- if (fd == get_client_fd()) {
- /* Try and give an error message saying
- * what client failed. */
- DEBUG(0,("write_data: write failure in "
- "writing to client %s. Error %s\n",
- get_peer_addr(fd,addr,sizeof(addr)),
- strerror(errno) ));
- } else {
- DEBUG(0,("write_data: write failure. "
- "Error = %s\n", strerror(errno) ));
- }
- return -1;
- }
-
- if (ret == 0) {
- return total;
- }
+ ret = write_data_iov(fd, &iov, 1);
+ if (ret >= 0) {
+ return ret;
+ }
- total += ret;
+ if (fd == get_client_fd()) {
+ char addr[INET6_ADDRSTRLEN];
+ /*
+ * Try and give an error message saying what client failed.
+ */
+ DEBUG(0, ("write_data: write failure in writing to client %s. "
+ "Error %s\n", get_peer_addr(fd,addr,sizeof(addr)),
+ strerror(errno)));
+ } else {
+ DEBUG(0,("write_data: write failure. Error = %s\n",
+ strerror(errno) ));
}
- return (ssize_t)total;
+
+ return -1;
}
/****************************************************************************
[-- Attachment #4: bzr.diff --]
[-- Type: text/x-diff, Size: 3432 bytes --]
--- util_sock.c
+++ util_sock.c
@@ -1037,40 +1037,109 @@
}
/****************************************************************************
+ Write all data from an iov array
+****************************************************************************/
+
+ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
+{
+ int i;
+ size_t to_send;
+ ssize_t thistime;
+ size_t sent;
+ struct iovec *iov_copy, *iov;
+
+ to_send = 0;
+ for (i=0; i<iovcnt; i++) {
+ to_send += orig_iov[i].iov_len;
+ }
+
+ thistime = sys_writev(fd, orig_iov, iovcnt);
+ if ((thistime <= 0) || (thistime == to_send)) {
+ return thistime;
+ }
+ sent = thistime;
+
+ /*
+ * We could not send everything in one call. Make a copy of iov that
+ * we can mess with. We keep a copy of the array start in iov_copy for
+ * the TALLOC_FREE, because we're going to modify iov later on,
+ * discarding elements.
+ */
+
+ iov_copy = (struct iovec *)TALLOC_MEMDUP(
+ talloc_tos(), orig_iov, sizeof(struct iovec) * iovcnt);
+
+ if (iov_copy == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ iov = iov_copy;
+
+ while (sent < to_send) {
+ /*
+ * We have to discard "thistime" bytes from the beginning
+ * iov array, "thistime" contains the number of bytes sent
+ * via writev last.
+ */
+ while (thistime > 0) {
+ if (thistime < iov[0].iov_len) {
+ char *new_base =
+ (char *)iov[0].iov_base + thistime;
+ iov[0].iov_base = new_base;
+ iov[0].iov_len -= thistime;
+ break;
+ }
+ thistime -= iov[0].iov_len;
+ iov += 1;
+ iovcnt -= 1;
+ }
+
+ thistime = sys_writev(fd, iov, iovcnt);
+ if (thistime <= 0) {
+ break;
+ }
+ sent += thistime;
+ }
+
+ TALLOC_FREE(iov_copy);
+ return sent;
+}
+
+/****************************************************************************
+ Write data to a fd.
+****************************************************************************/
+
+/****************************************************************************
Write data to a fd.
****************************************************************************/
ssize_t write_data(int fd, const char *buffer, size_t N)
{
- size_t total=0;
ssize_t ret;
- char addr[INET6_ADDRSTRLEN];
-
- while (total < N) {
- ret = sys_write(fd,buffer + total,N - total);
-
- if (ret == -1) {
- if (fd == get_client_fd()) {
- /* Try and give an error message saying
- * what client failed. */
- DEBUG(0,("write_data: write failure in "
- "writing to client %s. Error %s\n",
- get_peer_addr(fd,addr,sizeof(addr)),
- strerror(errno) ));
- } else {
- DEBUG(0,("write_data: write failure. "
- "Error = %s\n", strerror(errno) ));
- }
- return -1;
- }
-
- if (ret == 0) {
- return total;
- }
-
- total += ret;
- }
- return (ssize_t)total;
+ struct iovec iov;
+
+ iov.iov_base = CONST_DISCARD(char *, buffer);
+ iov.iov_len = N;
+
+ ret = write_data_iov(fd, &iov, 1);
+ if (ret >= 0) {
+ return ret;
+ }
+
+ if (fd == get_client_fd()) {
+ char addr[INET6_ADDRSTRLEN];
+ /*
+ * Try and give an error message saying what client failed.
+ */
+ DEBUG(0, ("write_data: write failure in writing to client %s. "
+ "Error %s\n", get_peer_addr(fd,addr,sizeof(addr)),
+ strerror(errno)));
+ } else {
+ DEBUG(0,("write_data: write failure. Error = %s\n",
+ strerror(errno) ));
+ }
+
+ return -1;
}
/****************************************************************************
next prev reply other threads:[~2009-01-08 19:56 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-04 0:40 libxdiff and patience diff Pierre Habouzit
2008-11-04 3:17 ` Davide Libenzi
2008-11-04 8:33 ` Pierre Habouzit
2008-11-04 5:39 ` Johannes Schindelin
2008-11-04 8:30 ` Pierre Habouzit
2008-11-04 14:34 ` Johannes Schindelin
2008-11-04 15:23 ` Pierre Habouzit
2008-11-04 15:57 ` Johannes Schindelin
2008-11-04 16:15 ` Pierre Habouzit
2009-01-01 16:38 ` [PATCH 0/3] Teach Git about the patience diff algorithm Johannes Schindelin
2009-01-01 16:38 ` [PATCH 1/3] Implement " Johannes Schindelin
2009-01-01 16:39 ` [PATCH 2/3] Introduce the diff option '--patience' Johannes Schindelin
2009-01-01 16:39 ` [PATCH 3/3] bash completions: Add the --patience option Johannes Schindelin
2009-01-01 19:45 ` [PATCH 0/3] Teach Git about the patience diff algorithm Linus Torvalds
2009-01-01 20:00 ` Linus Torvalds
2009-01-02 18:17 ` Johannes Schindelin
2009-01-02 18:49 ` Linus Torvalds
2009-01-02 19:07 ` Johannes Schindelin
2009-01-02 18:51 ` Jeff King
2009-01-02 21:59 ` [PATCH 1/3 v2] Implement " Johannes Schindelin
2009-01-02 21:59 ` Johannes Schindelin
2009-01-01 20:46 ` [PATCH 0/3] Teach Git about " Adeodato Simó
2009-01-02 1:56 ` Linus Torvalds
2009-01-02 10:55 ` Clemens Buchacher
2009-01-02 10:58 ` Clemens Buchacher
2009-01-02 16:42 ` Linus Torvalds
2009-01-02 18:46 ` Johannes Schindelin
2009-01-02 19:03 ` Linus Torvalds
2009-01-02 19:22 ` Johannes Schindelin
2009-01-02 19:39 ` Jeff King
2009-01-02 19:50 ` Jeff King
2009-01-02 20:52 ` Jeff King
2009-01-02 23:05 ` Linus Torvalds
2009-01-03 16:24 ` Bazaar's patience diff as GIT_EXTERNAL_DIFF Adeodato Simó
2009-01-02 21:59 ` [PATCH 0/3] Teach Git about the patience diff algorithm Johannes Schindelin
2009-01-08 19:55 ` Adeodato Simó [this message]
2009-01-08 20:06 ` Adeodato Simó
2009-01-09 6:54 ` Junio C Hamano
2009-01-09 13:07 ` Johannes Schindelin
2009-01-09 15:59 ` Adeodato Simó
2009-01-09 18:09 ` Linus Torvalds
2009-01-09 18:13 ` Linus Torvalds
2009-01-09 20:53 ` Junio C Hamano
2009-01-10 11:36 ` Johannes Schindelin
2009-01-02 11:03 ` Junio C Hamano
2009-01-02 18:50 ` Adeodato Simó
2009-01-06 11:17 ` Pierre Habouzit
2009-01-06 11:39 ` Pierre Habouzit
2009-01-06 19:40 ` Johannes Schindelin
2009-01-07 14:39 ` Pierre Habouzit
2009-01-07 17:01 ` Johannes Schindelin
2009-01-07 17:04 ` [PATCH v3 1/3] Implement " Johannes Schindelin
2009-01-07 18:10 ` Davide Libenzi
2009-01-07 18:32 ` Johannes Schindelin
2009-01-07 20:09 ` Davide Libenzi
2009-01-07 20:19 ` Johannes Schindelin
2009-01-07 18:59 ` Linus Torvalds
2009-01-07 20:00 ` Johannes Schindelin
2009-01-07 20:11 ` Davide Libenzi
2009-01-07 20:15 ` [PATCH 0/3] Teach Git about " Sam Vilain
2009-01-07 20:25 ` Linus Torvalds
2009-01-08 2:31 ` Sam Vilain
2009-01-07 20:38 ` Johannes Schindelin
2009-01-07 20:48 ` Junio C Hamano
2009-01-07 22:00 ` Johannes Schindelin
2009-01-07 22:45 ` Pierre Habouzit
2009-01-07 23:03 ` Johannes Schindelin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090108195511.GA8734@chistera.yi.org \
--to=dato@net.com.org.es \
--cc=Johannes.Schindelin@gmx.de \
--cc=davidel@xmailserver.org \
--cc=drizzd@aon.at \
--cc=fg@one2team.net \
--cc=git@vger.kernel.org \
--cc=madcoder@debian.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.