NNTPC: performance patch for "list active group.name"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




Currently I'm running nntpcached on a somewhat memory-starved system.
Users were complaining that it took too long for trn or tin to start
up.  As these times varied from 20 minutes to ten hours, I had to
agree.  It turns out that there's a simple performance modification
that can be made to improve the common-case scenario: requesting the
active file entry for a single, specific group.  Rather than scanning
through the entire active list sequentially, doing a glob match
against each one, the patch notices when there are no metacharacters
in the pattern and traverses the hash table/tree to get directly to
the desired group.

FWIW, that full search takes about a minute and a half.  Repeat for
every subscribed-to group at newsreader startup time, and you can see
why it might take a really long time to get through that part.  This
is, of course, only a problem on memory-starved systems.  It has no
effect on the initial startup delay (twenty minutes for us).  This is
purely a memory system problem with no obvious and straight-forward
work-around.

I made the change in 1.0.1, but diff'ing against 1.0.5 shows no
other changes in the relevant part of list.c.  Therefore, I suspect
this will work on any of the 1.0.* versions to date.

The hash table size should also be increased, but since our server is
already tight on memory, I haven't done this as yet.  Our upstream
provider has 41000 groups, and the distributed hash table size is
31337.  A more appropriate value would be something like 100313, to
allow a little more room for growth.

	Dworkin
================================================================
*** ../nntpcache-1.0.5/list.c	Fri Feb 28 19:54:10 1997
--- list.c	Tue Apr 22 15:15:23 1997
***************
*** 473,478 ****
--- 440,490 ----
  		emitrn (NNTP_XGTITLE_OK);
  	else
  		emitrn (NNTP_LIST_FOLLOWS);
+ #if 1
+ 	if (group_pat!=NULL && strchr(group_pat, '*')==NULL && strchr(group_pat, '?')==NULL)
+ 	{
+ 		struct newsgroup *p = newsgroup_find_add(group_pat, NULL, FALSE);
+ 		if (p != NULL)
+ 		{
+ 		  switch (list->type)
+ 		  {
+ 		    case l_active:
+ 		    {
+ 		      int hi, lo;
+ 		      if (!p->moderation)
+ 			      break;
+ 		      hi = MAX(p->hi, p->hi_server);
+ 		      if (p->lo>0)
+ 			      lo = p->lo;
+ 		      else
+ 			      lo = 0;
+ 		      if (p->lo_server>0)
+ 		      {
+ 			if (lo>0)
+ 				lo = MIN(lo, p->lo_server);
+ 			else
+ 				lo = p->lo_server;
+ 		      }
+ 		      emitf ("%s %d %d %c\r\n", p->group, hi, lo, p->moderation);
+ 		      break;
+ 		    }
+ 		    case l_active_times:
+ 		    if (p->creation_time && p->creator)
+ 			    emitf ("%s %lu %s\r\n", p->group, p->creation_time, p->creator);
+ 		    break;
+ 		    case l_xgtitle:
+ 		    case l_newsgroups:
+ 		    if (p->desc)
+ 			    emitf ("%s\t%s\r\n", p->group, p->desc);
+ 		    break;
+ 		    default:
+ 		    break;
+ 		  }
+ 		}
+ 		emitrn (".");
+ 		return TRUE;
+ 	}
+ #endif
  	for (n=Ni->newsgroup_head; n; n=n->next)
  	{
  #ifdef READ_LOCKS


[Index of Archives]     [Yosemite]     [Yosemite Campsites]     [Bugtraq]     [Linux]     [Trn]

Powered by Linux