[PATCH] tin 1.9.x optimize LIST ACTIVE calls on RFC 3977 servers in the -n case

Urs Janßen <[email protected]> Wed, 18 Nov 2009 22:27:28 +0100
Newsgroups gmane.network.tin.devel
Organization tin.org
Message-ID <[email protected]>
the patch below should reduce the number of LIST ACTIVE cmds. in the
-n case to a minimum on RFC 3977 servers with CAPABILTIES "LIST ACTIVE".
PIPELINE_LIMIT might be way to low for this special case. the patch
is not well tested and there is at least another place where a simmilar
optimizaion could be done (mail.c:open_newsgroups_fp() when
nntp_caps.type == CAPABILITIES && nntp_caps.list_newsgroups).

--- active.c.o	2009-08-11 21:55:17.570938906 +0100
+++ active.c	2009-11-18 22:15:21.097461569 +0100
@@ -611,22 +611,19 @@
 #ifdef NNTP_ABLE
 #	ifndef DISABLE_PIPELINING
 		/*
+		 * use "LIST ACTIVE grp" (or even LIST ACTIVE grp,...) if we have
+		 * less than PIPELINE_LIMIT groups and we use -n but not -Q
+		 *
 		 * TODO: test me. do we want this overhead? add a DISABLE_PIPELINING
 		 *       code-path? we don't have list_active set but we use some
 		 *       sort of LIST ACTIVE -> our documentation is a bit incorrect
 		 *       now.
-		 *
-		 * use "LIST ACTIVE grp" if we have less than PIPELINE_LIMIT
-		 * groups and we use -n but not -Q
-		 *
-		 * TODO: extend to use "LIST ACTIVE grp1,grp2,..." in the
-		 *       nntp_caps.type == CAPABILITIES && list_active case
 		 */
 		if (read_news_via_nntp && !list_active && ((nntp_caps.type == CAPABILITIES && nntp_caps.list_active) || nntp_caps.type != CAPABILITIES) && (show_description || check_for_new_newsgroups)) {
 			char buff[NNTP_STRLEN];
 			char *ptr, *q;
 			char moderated[PATH_LEN];
-			int i, r, j = 0;
+			int r = 0, i = 0, j = 0;
 			long count = -1L, min = 1L, max = 0L;
 			struct t_group *grpptr;
 			t_bool need_auth = FALSE;
@@ -641,17 +638,36 @@
 						if (!(q = strpbrk(ptr, ":!")))
 							continue;
 						*q = '\0';
-						snprintf(buff, sizeof(buff), "LIST ACTIVE %s", ptr);
+						if (nntp_caps.type == CAPABILITIES && nntp_caps.list_active) {
+							/* list active takes wildmats */
+							if (!i) { /* new wildmat list */
+								i++;
+								snprintf(buff, sizeof(buff), "LIST ACTIVE %s", ptr);
+								continue;
+							}
+							if (strlen(buff) + strlen(ptr) + 1 < NNTP_STRLEN) { /* append group name */
+								snprintf(buff + strlen(buff), sizeof(buff) - strlen(buff), ",%s", ptr);
+								continue;
+							}
+							i = 0; /* new wildmatlist required */
+						} else
+							snprintf(buff, sizeof(buff), "LIST ACTIVE %s", ptr);
+						put_server(buff);
+						r++;
+						*buff='\0';
+					}
+					if (*buff) {
 						put_server(buff);
+						r++;
 					}
 				}
 				fclose(fp);
 
-				if (j < PIPELINE_LIMIT) {
-					for (i = 0; i < j && !did_reconnect; i++) {
-						if ((r = get_only_respcode(buff, sizeof(buff))) != OK_GROUPS) {
+				if (r < PIPELINE_LIMIT) {
+					for (i = 0; i < r && !did_reconnect; i++) {
+						if ((j = get_only_respcode(buff, sizeof(buff))) != OK_GROUPS) {
 							/* TODO: add 483 (RFC 3977) code */
-							if (r == ERR_NOAUTH || r == NEED_AUTHINFO)
+							if (j == ERR_NOAUTH || r == NEED_AUTHINFO)
 								need_auth = TRUE;
 							continue;
 						} else {