[387] in Zephyr_Bugs

home help back first fref pref prev next nref lref last post

[eichin@Athena.MIT.EDU: (RT) Version 7.3P: zmailnotify can be slow]

daemon@ATHENA.MIT.EDU (Jonathan I. Kamens)
Sun Jul 5 11:15:10 1992

Date: Sun, 5 Jul 92 11:14:56 -0400
From: "Jonathan I. Kamens" <jik@pit-manager.MIT.EDU>
To: bug-zephyr@Athena.MIT.EDU


----- Forwarded message
Date: Sun, 5 Jul 92 04:09:14 -0400
From: "Mark W. Eichin" <eichin@Athena.MIT.EDU>
To: bugs@Athena.MIT.EDU
Subject: (RT) Version 7.3P: zmailnotify can be slow

System type, version:	(RT) Version 7.3P
System name:		portnoy
What's wrong:

zmailnotify calls realloc on every line of the messages that it pulls
over from the server. This can be really slow, as realloc may have to
copy the block every time, and in the worst case require order(m*n)
bytes to store an m line n byte message.
	The recent "TOP" changes ameliorate this significantly, but
the code should probably avoid the problem in any case.

What should have happened:

	I made some changes (to version 1.10 of zmailnotify.c) that
had two simple effects:
	1) once you've finished the headers (ie. you've seen a blank
line) don't bother storing any later lines, just call getline on them
and throw them away.
	2) in mbx_write, when doing the realloc, rather than grabbing
a one-line chunk, grab around 2K, and double the allocation size each
time. This bounds the space used to something like order(log_2(n)*n).

	Patches to zmailnotify.c 1.16 follow. Perhaps they'll be
useful.
				_Mark_ <eichin@athena.mit.edu>
				MIT Student Information Processing Board


RCS file: /mit/zephyr/src/clients/zmailnotify/RCS/zmailnotify.c,v
retrieving revision 1.16
diff -c -r1.16 zmailnotify.c
*** /tmp/,RCSt1014134	Sun Jul  5 04:08:22 1992
--- zmailnotify.c	Sun Jul  5 03:55:02 1992
***************
*** 57,62 ****
--- 57,65 ----
  } maillist[MAXMAIL];
  
  char *mailptr = NULL;
+ int mailptr_len = 0;
+ int mailptr_alloc = 0;
+ #define MAILPTR_INC 2000
  
  char *prog = "zmailnotify";
  
***************
*** 316,322 ****
  		free(mailptr);
  
  	mailptr = 0;
! 	
  	get_message(i);
  
  	ptr = mailptr;
--- 319,327 ----
  		free(mailptr);
  
  	mailptr = 0;
! 	mailptr_len = 0;
! 	mailptr_alloc = 0;
! 
  	get_message(i);
  
  	ptr = mailptr;
***************
*** 555,560 ****
--- 560,571 ----
  	    (void) strcpy(Errmsg, buf);
  	    return (NOTOK);
  	}
+     } else if (*buf == '\0') {
+       /* suck up all future lines, since this is after all only for headers */
+         while(! ((buf[0]=='.') && (buf[1] == '\0')) ) {
+ 	    if (getline(buf, n, f) != OK) return (NOTOK);
+ 	}
+ 	return DONE;
      }
  }
  
***************
*** 638,651 ****
  char *line;
  int dummy;				/* for consistency with pop_scan */
  {
  	if (mailptr) {
! 		mailptr = realloc(mailptr,(unsigned)(strlen(mailptr)+strlen(line)+2));
! 		(void) strcat(mailptr,line);
  	} 
  	else {
! 		mailptr = malloc((unsigned)(strlen(line)+2));
  		(void) strcpy(mailptr,line);
  	}
! 	(void) strcat(mailptr,"\n");
  	return(0);
  }
--- 649,683 ----
  char *line;
  int dummy;				/* for consistency with pop_scan */
  {
+ 	int line_len = strlen(line)+1; /* line + \0 */
+ 	
  	if (mailptr) {
! 		/* do we really need to realloc? */
! 		if(mailptr_alloc < mailptr_len + line_len +1) {
! 			/* make sure we have plenty of room */
! 			mailptr_alloc += line_len +1 + MAILPTR_INC;
! 			mailptr = realloc(mailptr,mailptr_alloc);
! 			if(!mailptr) {
! 				fprintf(stderr,"zmailnotify: realloc failed\n");
! 				exit(1);
! 			}
! 		}
! 		/* either way, stuff the data to the *right* place... */
! 		(void) strcpy(mailptr+mailptr_len-1,line);
! 		mailptr_len += line_len -1;
  	} 
  	else {
! 		/* initial allocation - at least MAILPTR_INC */
! 		mailptr_alloc = MAILPTR_INC>line_len+1?MAILPTR_INC:line_len+1;
! 		mailptr = malloc(mailptr_alloc);
! 		if(!mailptr) {
! 			fprintf(stderr,"zmailnotify: malloc failed\n");
! 			exit(1);
! 		}
! 		mailptr_len = line_len;
  		(void) strcpy(mailptr,line);
  	}
! 	(void) strcpy(mailptr+mailptr_len-1,"\n");
! 	mailptr_len++;
  	return(0);
  }

----- End of forwarded message

home help back first fref pref prev next nref lref last post