Hi,

This is a patch to try to speedup MBOX by caching the structure stream to disk.

Since I started this test the management decided to switched to Maildir/courier-imap/maildrop instead.

So I wont continue testing this ... but if anybody wanna continue with it.

(Warning: This is 3rd grade coding... just a fast hack to see... dont expect much)

   Have fun.

--
Alain Hebert [EMAIL PROTECTED] PubNIX Inc. P.O. Box 175 Beaconsfield, Quebec H9W 5T7
tel 514-990-5911   http://www.pubnix.net    fax 514-990-9443

*** ./src/osdep/unix/unix.c.orig	Wed Nov 10 19:23:09 2004
--- ./src/osdep/unix/unix.c	Tue May  9 18:54:49 2006
***************
*** 126,129 ****
--- 126,137 ----
  void unix_phys_write (UNIXFILE *f,char *buf,size_t size);
  
+ /*--------------------------------------------------------------------------*
+  * XXX - Speedup Patch
+  *--------------------------------------------------------------------------*/
+ static int _save_cache(MAILSTREAM *stream);
+ static int _load_cache(MAILSTREAM *stream);
+ static int _delete_cache(MAILSTREAM *stream);
+ static char *_make_fname_cache(MAILSTREAM *stream);
+ 
  /* UNIX mail routines */
  
***************
*** 502,510 ****
      unix_abort (stream);	/* abort if can't get RW silent stream */
  				/* parse mailbox */
!   else if (unix_parse (stream,&lock,LOCK_SH)) {
      unix_unlock (LOCAL->fd,stream,&lock);
      mail_unlock (stream);
      MM_NOCRITICAL (stream);	/* done with critical */
    }
    if (!LOCAL) return NIL;	/* failure if stream died */
  				/* make sure upper level knows readonly */
--- 510,525 ----
      unix_abort (stream);	/* abort if can't get RW silent stream */
  				/* parse mailbox */
!   else
!   {
! /*--------------------------------------------------------------------------*
!  * XXX - Speedup Patch
!  *--------------------------------------------------------------------------*/
! _load_cache(stream);
!     if (unix_parse (stream,&lock,LOCK_SH)) {
      unix_unlock (LOCAL->fd,stream,&lock);
      mail_unlock (stream);
      MM_NOCRITICAL (stream);	/* done with critical */
    }
+   }
    if (!LOCAL) return NIL;	/* failure if stream died */
  				/* make sure upper level knows readonly */
***************
*** 538,541 ****
--- 553,560 ----
  				/* else dump final checkpoint */
    else if (LOCAL->dirty) unix_check (stream);
+ /*--------------------------------------------------------------------------*
+  * XXX - Speedup Patch
+  *--------------------------------------------------------------------------*/
+ _save_cache(stream);
    stream->silent = silent;	/* restore old silence state */
    unix_abort (stream);		/* now punt the file and local data */
***************
*** 1264,1267 ****
--- 1283,1290 ----
  				/* validate change in size */
    if (sbuf.st_size < LOCAL->filesize) {
+ /*--------------------------------------------------------------------------*
+  * XXX - Speedup Patch
+  *--------------------------------------------------------------------------*/
+ _delete_cache(stream);
      sprintf (tmp,"Mailbox shrank from %lu to %lu bytes, aborted",
  	     (unsigned long) LOCAL->filesize,(unsigned long) sbuf.st_size);
***************
*** 2448,2450 ****
--- 2471,2753 ----
  {
    return unix_append (stream,"mbox",af,data);
+ }
+ 
+ /*==========================================================================*
+  *
+  *==========================================================================*/
+ 
+ /*--------------------------------------------------------------------------*
+  * Make cache filename
+  *--------------------------------------------------------------------------*/
+ static	char	*_make_fname_cache(MAILSTREAM *stream)
+ {
+ 			char	*p;
+ 	static	char	*cacheFName=NULL;
+ 
+ 	if ( cacheFName )
+ 		free(cacheFName);
+ 
+ 	cacheFName=calloc(5+strlen(stream->mailbox)+1+5+1,sizeof(cacheFName[0]));
+ 	cacheFName=strcat(cacheFName,"/tmp/");
+ 
+ 	p = cacheFName+strlen(cacheFName);
+ 
+ 	cacheFName=strcat(cacheFName,stream->mailbox);
+ 
+ 	for(; p && *p; p++)
+ 		if ( *p == '/' )
+ 			*p = '_';
+ 	
+ 	cacheFName=strcat(cacheFName,".");
+ 	cacheFName=strcat(cacheFName,"cache");
+ 
+ 	return(cacheFName);
+ }
+ 
+ /*--------------------------------------------------------------------------*
+  * Save Structures
+  *--------------------------------------------------------------------------*/
+ static int _save_cache(MAILSTREAM *stream)
+ {
+ 	int		i,
+ 			rc = 0,
+ 			cFD;
+ 	char	*cacheFName;
+ 
+ 	if ( (cacheFName = _make_fname_cache(stream)) != NULL )
+ 	{
+ 		if ( (cFD=open(cacheFName,O_CREAT|O_TRUNC|O_WRONLY,S_IRUSR|S_IWUSR)) > 0 )
+ 		{
+ 			write(	cFD,
+ 					(void *) stream,
+ 					sizeof(*stream)								);
+ 			write(	cFD,
+ 					(void *) stream->local,
+ 					sizeof(UNIXLOCAL)							);
+ 			write(	cFD,
+ 					(void *) stream->cache,
+ 					stream->cachesize*sizeof(stream->cache[0])	);
+ 			write(	cFD,
+ 					(void *) stream->sc,
+ 				 	stream->cachesize*sizeof(stream->sc[0])	);
+ 
+ 			for(i=0; i < (sizeof(stream->user_flags) / sizeof(stream->user_flags[0])); i++)
+ 			{
+ 				write(cFD,(void *) &stream->user_flags[i],sizeof(stream->user_flags[i]));
+ 
+ 				if ( stream->user_flags[i] )
+ 				{
+ 					int	len;
+ 
+ 					len = strlen(stream->user_flags[i]);
+ 
+ 					write(cFD,(void *) &len,sizeof(len));
+ 					write(cFD,(void *) stream->user_flags[i],len);
+ 				}
+ 			}
+ 
+ 			for(i=0; i < stream->cachesize; i++)
+ 				if ( stream->cache[i] )
+ 					write(cFD,(void *) stream->cache[i],sizeof(*stream->cache[i]));
+ 
+ 			for(i=0; i < stream->cachesize; i++)
+ 				if ( stream->sc[i] )
+ 					write(cFD,(void *) stream->sc[i],sizeof(*stream->sc[i]));
+ 
+ 			close(cFD);
+ 
+ 			rc = 0;
+ 		}
+ 		else
+ 			rc = -2;
+ 	}
+ 	else
+ 		rc = -1;
+ 
+ 	return(rc);
+ }
+ 
+ /*--------------------------------------------------------------------------*
+  * Load Structures
+  *--------------------------------------------------------------------------*/
+ static int _load_cache(MAILSTREAM *stream)
+ {
+ 	int			i,
+ 				rc = -1,
+ 				cFD;
+ 	char		*p,
+ 				*cacheFName;
+ 	MAILSTREAM	cStream,
+ 				dStream,
+ 				*pS=stream; //&dStream; memset(pS,0,sizeof(dStream));
+ 	UNIXLOCAL	cLocal;
+ 	
+ 	if ( (cacheFName = _make_fname_cache(stream)) != NULL )
+ 	{
+ 		if ( (cFD=open(cacheFName,O_RDONLY)) > 0 )
+ 		{
+ 			read(cFD,(void *) &cStream,sizeof(cStream));
+ 			read(cFD,(void *) &cLocal,sizeof(UNIXLOCAL));
+ 
+ 			for(i = 0; i < pS->cachesize; i++)
+ 				if ( pS->cache[i] )
+ 					free(pS->cache[i]);
+ 
+ 			for(i = 0; i < pS->cachesize; i++)
+ 			{
+ 				if ( pS->sc[i] )
+ 				{
+ 					if (pS->sc[i]->from )
+ 						free(pS->sc[i]->from);
+ 
+ 					if (pS->sc[i]->to )
+ 						free(pS->sc[i]->to);
+ 
+ 					if (pS->sc[i]->cc )
+ 						free(pS->sc[i]->cc);
+ 
+ 					if (pS->sc[i]->subject )
+ 						free(pS->sc[i]->subject);
+ 
+ 					if (pS->sc[i]->original_subject )
+ 						free(pS->sc[i]->original_subject);
+ 
+ 					if (pS->sc[i]->unique )
+ 						free(pS->sc[i]->unique);
+ 
+ 					if (pS->sc[i]->message_id )
+ 						free(pS->sc[i]->message_id);
+ 
+ 					if ( pS->sc[i]->references )
+ 						mail_free_stringlist(&pS->sc[i]->references);
+ 
+ 					free(pS->sc[i]);
+ 				}
+ 			}
+ 
+ 			pS->use						= cStream.use;
+ 			pS->sequence				= cStream.sequence;
+ 			pS->inbox					= cStream.inbox;
+ 			pS->lock					= cStream.lock;
+ 			pS->debug					= cStream.debug;
+ 			pS->silent					= cStream.silent;
+ 			pS->rdonly					= cStream.rdonly;
+ 			pS->anonymous				= cStream.anonymous;
+ 			pS->scache					= cStream.scache;
+ 			pS->halfopen				= cStream.halfopen;
+ 			pS->secure					= cStream.secure;
+ 			pS->tryssl					= cStream.tryssl;
+ 			pS->mulnewsrc				= cStream.mulnewsrc;
+ 			pS->perm_seen				= cStream.perm_seen;
+ 			pS->perm_deleted			= cStream.perm_deleted;
+ 			pS->perm_flagged			= cStream.perm_flagged;
+ 			pS->perm_answered			= cStream.perm_answered;
+ 			pS->perm_draft				= cStream.perm_draft;
+ 			pS->kwd_create				= cStream.kwd_create;
+ 			pS->uid_nosticky			= cStream.uid_nosticky;
+ 			pS->unhealthy				= cStream.unhealthy;
+ 			pS->perm_user_flags			= cStream.perm_user_flags;
+ 			pS->gensym					= cStream.gensym;
+ 			pS->nmsgs					= cStream.nmsgs;
+ 			pS->recent					= cStream.recent;
+ 			pS->uid_validity			= cStream.uid_validity;
+ 			pS->uid_last				= cStream.uid_last;
+ 			pS->cachesize				= cStream.cachesize;
+ 			pS->cache					= calloc(pS->cachesize,sizeof(pS->cache[0]));
+ 			pS->sc						= calloc(pS->cachesize,sizeof(pS->sc[0]));
+ 			pS->msgno					= cStream.msgno;
+ 			pS->env						= NULL;
+ 			pS->body					= NULL;
+ 			pS->text.data				= NULL;
+ 			pS->snarf.name				= NULL;
+ 			pS->private.search.string	= NULL;
+ 			pS->private.search.text		= NULL;
+ 			pS->sparep					= NULL;
+ 			pS->spare					= cStream.spare;
+ 			pS->spare2					= cStream.spare2;
+ 			pS->spare3					= cStream.spare3;
+ 			pS->spare4					= cStream.spare4;
+ 			pS->spare5					= cStream.spare5;
+ 			pS->spare6					= cStream.spare6;
+ 			pS->spare7					= cStream.spare7;
+ 			pS->spare8					= cStream.spare8;
+ 
+ 			((UNIXLOCAL * ) pS->local)->filesize= cLocal.filesize;
+ 			((UNIXLOCAL * ) pS->local)->filetime= cLocal.filetime;
+ 
+ 			read(cFD,(void *) pS->cache,	pS->cachesize*sizeof(pS->cache[0])	);
+ 			read(cFD,(void *) pS->sc,		pS->cachesize*sizeof(pS->sc[0])		);
+ 
+ 			for(i=0; i < (sizeof(pS->user_flags) / sizeof(pS->user_flags[0])); i++)
+ 			{
+ 				read(cFD,(void *) &pS->user_flags[i],sizeof(pS->user_flags[i]));
+ 
+ 				if ( pS->user_flags[i] )
+ 				{
+ 					int		len;
+ 
+ 					read(cFD,(void *) &len,sizeof(len));
+ 
+ 					pS->user_flags[i] = calloc(1,len+1);
+ 
+ 					read(cFD,(void *) pS->user_flags[i],len);
+ 				}
+ 			}
+ 
+ 			for(i=0; i < pS->cachesize; i++)
+ 			{
+ 				if ( pS->cache[i] )
+ 				{
+ 					pS->cache[i] = calloc(1,sizeof(*pS->cache[i]));
+ 
+ 					read(cFD,(void *) pS->cache[i],sizeof(*pS->cache[i]));
+ 
+ 					pS->cache[i]->private.special.text.data		= NULL;
+ 					pS->cache[i]->private.msg.env				= NULL;
+ 					pS->cache[i]->private.msg.body				= NULL;
+ 					pS->cache[i]->private.msg.full.text.data	= NULL;
+ 					pS->cache[i]->private.msg.lines				= NULL;
+ 					pS->cache[i]->private.msg.header.text.data	= NULL;
+ 					pS->cache[i]->private.msg.text.text.data	= NULL;
+ 					pS->cache[i]->sparep						= NULL;
+ 				}
+ 			}
+ 
+ 			for(i=0; i < pS->cachesize; i++)
+ 			{
+ 				if ( pS->sc[i] )
+ 				{
+ 					pS->sc[i] = calloc(1,sizeof(*pS->sc[i]));
+ 
+ 					read(cFD,(void *) pS->sc[i],sizeof(*pS->sc[i]));
+ 				}
+ 			}
+ 
+ 			close(cFD);
+ 
+ 			rc = 0;
+ 		}
+ 		else
+ 			rc = -3;
+ 	}
+ 	else
+ 		rc = -2;
+ 
+ 	return(rc);
+ }
+ 
+ /*--------------------------------------------------------------------------*
+  * Delete cache file (in case a human touch the mailbox)
+  *--------------------------------------------------------------------------*/
+ static int _delete_cache(MAILSTREAM *stream)
+ {
+ 	int		rc = -1;
+ 	char	*cacheFName;
+ 
+ 	if ( (cacheFName = _make_fname_cache(stream)) != NULL )
+ 		unlink(cacheFName);
+ 	else
+ 		rc = -2;
+ 
+ 	return(rc);
  }

Attachment: build.sh
Description: Bourne shell script

_______________________________________________
Imap-uw mailing list
[email protected]
https://mailman1.u.washington.edu/mailman/listinfo/imap-uw

Reply via email to