Summary of (Re: Recompiling News 2.11 with dbm routines using gcc1.34)

Lenny Tropiano lenny at icus.islp.ny.us
Sun Mar 19 18:04:23 AEST 1989


In article <180 at dms3b1.UUCP> dave at dms3b1.UUCP (Dave Hanna) writes:
|>In article <633 at icus.islp.ny.us> lenny at icus.islp.ny.us (*I*) write:

...[Talk about me trying to get the news up to patch level 17, recompiled
    with the dbm routines, and lastly using gcc]...

|>With your experience and history, I have no doubt that you'll be successful,
|>but I want to wish you good luck, and do let us know how it works out.

Well thanks for the vote of confidence.  I first want to thank all those
who replied, a little too many to mention here.  I must have gotten about
15 copies of the mdbm patches to use with expire (*sigh*), but thanks 
nevertheless.   I'll enclose that patch that allows you to use the mdbm
routines in place of the dbm routines, since the mdbm routines use a 
different extension on the indexed files.  This way (using the patch), those
files will be linked, and you'll have no problem. (Make sure you compile
with the -DDBM and -DMDBM flags)

Well here's a quick summary of my trials and tribulations of compiling
this bugger.   I'm finally up to patchlevel 17 of the news, and it is
using the mdbm routines.  This wasn't without some headaches along the
way.  I must have compiled the netnews software at least 5 times this
past week (ugh).  Patchlevel 17 did bring apon some bugs, but after
accumulating a bunch of patches that were posted to the net shortly after
the release of that, most, if not all, of the bad bugs were banished
forever (or so I hope).

I did compile the news with the gcc compiler (once) but gave up after
it started core dumping all over the place.  It wasn't something I
really wanted to deal with at 3:00AM in the morning.  I recompiled with
the UNIX PC compiler, and installed it ... just in time for my days worth
of news to be sent.

A few people helpfully pointed out the problems with gcc and the dbm 
routines (where the core dump probably originated at).  Brant Cheikes
kindly gave me this information, but I also got it from a few other
sources :-)

|Some of the dbm routines return structs, rather than struct *'s.
|Pcc and Gcc use incompatible struct-passing facilities.  The upshot is
|that if you compile with Gcc, you either must also compile your dbm
|routines with Gcc, *or* you must use the -fpcc-struct-return option
|(check that, I may not have gotten the name just right).
|
|Personally, I have a /usr/lib/libpdbm.a containing the pcc-compiled
|dbm routines, and a libgdbm.a for the Gcc-compiled routines.  Why?
|Because I've heard that the pcc-struct-return option (new in 1.34, I
|believe) is a bit buggy.
|...
|Brant Cheikes
|University of Pennsylvania, Department of Computer and Information Science
|brant at manta.pha.pa.us, brant at linc.cis.upenn.edu, bpa!manta!brant

Gcc was a nice thought, but right now I don't have time to deal with
possibly buggy code for the -fpcc-struct-return option.   Maybe when it's
fixed in 1.35, I'll deal with it again.

Robert Granvin (rjg at sialis) pointed out that he is (and has been for a while) 
using the dbz.c set of routines that basically mimics the dbm routines store()
and fetch(), which will satisfy the requirements for netnews at least.  It's
a short program so I'll include it here.  All was necessary was to define
-DDBM, and link it with dbz.o ... (instead of -ldbm or -lmdbm)...  This seems
a little easier, but who knows.

A good idea that was pointed out to me, unfortunately 1 day too late, was
a way to save the current history.  I just removed the history.d/[0-9] files,
and then did the /usr/lib/news/expire -R to [re]build the history files 
as DBM files (note this took over 1.5 hours on my machine with all the news 
I had).   Kent Forschmiedt (kent at happym) suggested I do this:

|o 2.11.14 does not keep a whole history file, only the ten pieces in 
|   history.d, so cat them together and sort them:
|
|   cat history.d/[0-9] | sort +1.6 -2 +1 >history
|
|o When everything has compiled, run expire -R to create the dbm files.
|
|o If you are using rn, you need to fix it, too.  This is easy.  Run
|  Configure as usual, do anything you need to do to it, and add
|  "#define DBM" to defs.h.

News unbatches *so* much faster now.  It used to take about 12-15 hours
to unbatch 8000-10000 blocks of compressed news.  Now it's done in about
2-4 hours.  A big difference!   I've noticed that expire's take longer,
but that's because it has to recreate the history dbm files each time
expire is run.  This I don't care too much about, since it's chugging along
at 3:00AM, and what do I care.

For those who care, here's what my current history files look like for 15
days worth of history:

2480 -rw-r--r--  1 news    news  1269622 Mar 19 02:27 /usr/lib/news/history
7980 -rw-r--r--  2 news    news  4085760 Mar 19 02:27 /usr/lib/news/history.dat
   9 -rw-r--r--  2 news    news     4352 Mar 19 02:26 /usr/lib/news/history.dir
   9 -rw-r--r--  2 news    news     4352 Mar 19 02:26 /usr/lib/news/history.map
7980 -rw-r--r--  2 news    news  4085760 Mar 19 02:27 /usr/lib/news/history.pag

Well if anything else is needed that I can be some assistance to, please
let me know.

-Lenny

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  mdbm.pat dbz.c
# Wrapped by lenny at icus on Sun Mar 19 03:02:47 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f mdbm.pat -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"mdbm.pat\"
else
echo shar: Extracting \"mdbm.pat\" \(1034 characters\)
sed "s/^X//" >mdbm.pat <<'END_OF_mdbm.pat'
X*** expire.c.old	Mon Mar 13 17:11:14 1989
X--- expire.c	Mon Mar 13 17:38:30 1989
X***************
X*** 841,846 ****
X--- 851,864 ----
X  			(void) sprintf(tempname,"%s.dir", ARTFILE);
X  			(void) strcpy(rindex(NARTFILE, '.'), ".dir");
X  			(void) rename(NARTFILE, tempname);
X+ #ifdef	MDBM
X+ 			(void) sprintf(tempname, "%s.dat", ARTFILE);
X+ 			(void) strcpy(rindex(NARTFILE, '.'), ".dat");
X+ 			(void) rename(NARTFILE, tempname);
X+ 			(void) sprintf(tempname, "%s.map", ARTFILE);
X+ 			(void) strcpy(rindex(NARTFILE, '.'), ".map");
X+ 			(void) rename(NARTFILE, tempname);
X+ #endif	/* MDBM */
X  		}
X  #endif
X  	}
X***************
X*** 1251,1256 ****
X--- 1284,1297 ----
X  		(void) UNLINK(tempname);
X  		(void) sprintf(tempname,"%s.dir", NARTFILE);
X  		(void) UNLINK(tempname);
X+ 		
X+ #ifdef	MDBM
X+ 		(void) sprintf(tempname, "%s.dat", NARTFILE);
X+ 		(void) UNLINK(tempname);
X+ 		(void) sprintf(tempname, "%s.map", NARTFILE);
X+ 		(void) UNLINK(tempname);
X+ #endif	/* MDBM */
X+ 
X  #else	/* !DBM */
X  		(void) UNLINK(ARTFILE);
X  #endif	/* !DBM */
END_OF_mdbm.pat
if test 1034 -ne `wc -c <mdbm.pat`; then
    echo shar: \"mdbm.pat\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f dbz.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"dbz.c\"
else
echo shar: Extracting \"dbz.c\" \(5385 characters\)
sed "s/^X//" >dbz.c <<'END_OF_dbz.c'
X/*
X
Xdbz.c  V1.0 
X
XCopyright 1988 Jon Zeeff (umix!b-tech!zeeff)  
XYou can use this code in any manner, as long as you leave my name on it
Xand don't hold me responsible for any problems with it.
X
XThese routines replace dbm as used by the usenet news software 
X(it's not a full dbm replacement by any means).  It's fast and 
Xsimple.  
X
XBSD sites will notice some savings in disk space.  Sys V sites without 
Xdbm will notice much faster operation.  
X
XThis code relies on the fact that news stores a pointer to the history 
Xfile as the dbm data and that keys always end with > (meaning that a 
Xfull key should never match a partial key and that you don't need to 
Xkeep track of key size).  It doesn't store another copy of the key 
Xlike dbm does so it saves disk space.  All you can do is fetch() and 
Xstore() data.  
X
XJust make news with the dbm option and link with dbz.o.
X
X*/
X
X/* 
X   Set this to the something several times larger than the maximum # of 
X   lines in a history file.  It should be a prime number.
X*/
X
X#define INDEX_SIZE 99991 
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <fcntl.h>
X#include <string.h>
X
Xlong	lseek();
X
Xtypedef struct {
X	char	*dptr;
X	int	dsize;
X} datum;
X
Xstatic char	buffer[1024];   /* used for fetch returns */
Xstatic int	data_file;
Xstatic FILE *index_file = NULL;
Xstatic long	data_ptr;
X
Xdbminit(name)
Xchar	*name;
X{
X	char	string[1024];
X	FILE * fopen();
X
X	if (index_file != NULL) 
X		return - 1;    /* init already called once */
X
X	data_file = open(name, O_RDWR);
X
X	strcpy(string, name);
X	strcat(string, ".pag");
X	index_file = fopen(string, "r+");
X
X	if (index_file == NULL) 
X		return - 1;
X
X	return 0;
X
X}
X
X
Xdbmclose()
X{
X	if (index_file) {
X		fclose(index_file);
X		index_file = NULL;
X		close(data_file);
X	}
X	return 0;
X}
X
X
Xdatum
Xfetch(key)
Xdatum key;
X{
X	long	index_ptr;
X	long	data_ptr;
X	datum output;
X	char	*strchr();
X	long	hash();
X	long	get_ptr();
X	char	*p;
X
X	for (index_ptr = hash(key.dptr, key.dsize); (data_ptr = get_ptr(index_ptr)) != -1; ++index_ptr) {
X		/* we got a pointer into the history file, go see if it's the right one */
X
X		lseek(data_file, data_ptr, 0);
X		read(data_file, buffer, (unsigned)key.dsize);
X		p = buffer;	/* convert string to lower case, as inews calls us that way */
X		while (*p) {	/* - ahby at bungia.mn.org */
X			*p = tolower(*p);
X			p++;
X		}
X
X		/* we can get away without the length info since we know that a 
X       lhs portion of one key != any full key */
X
X		/* We use size - 1 since key has a null but hist file doesn't */
X
X		if (strncmp(key.dptr, buffer, key.dsize - 1) == 0) {
X			/* we found it */
X			output.dptr = (char *) & data_ptr;
X			/* output.dptr = buffer;  /* replaced per bug fix */
X			/* output.dsize = strchr(buffer,'\n')-buffer + 1; not used by news */
X			return output;
X		}
X	}
X
X	/* we didn't find it */
X
X	output.dptr = NULL;
X	output.dsize = 0;
X	return output;
X
X}
X
X
X/* add an entry to the database */
X
Xstore(key, data)
Xdatum key;
Xdatum data;
X{
X
X	return put_ptr(hash(key.dptr, key.dsize), *((long *)data.dptr));
X
X}
X
X
X/* get a data file pointer from the specified location in the index file */
X
Xstatic long	
Xget_ptr(index_ptr)
Xlong	index_ptr;
X{
X	long	data_ptr = 0;
X	int	count;
X
X	/* seek to where it should be */
X	fseek(index_file, (long)(index_ptr * sizeof(long)), 0);
X
X	/* read it */
X	count = fread((char *) & data_ptr, sizeof(long), 1, index_file);
X
X	if (count != 1 || data_ptr == 0) 
X		return - 1;
X
X	data_ptr -= sizeof(long);
X
X	return data_ptr;
X}
X
X
X/* put a data file pointer into the specified location in the index file */
X/* move down further if slots are full */
X
Xstatic 
Xput_ptr(index_ptr, data_ptr)
Xlong	index_ptr;
Xlong	data_ptr;
X{
X	long	i = INDEX_SIZE;
X
X	/* find an empty slot */
X	while (i-- && get_ptr(index_ptr) != -1) 
X		index_ptr = ++index_ptr % INDEX_SIZE;
X
X	/* seek to spot */
X	fseek(index_file, (long)(index_ptr * sizeof(long)), 0);
X
X	/* write in data */
X	data_ptr += sizeof(long);
X	fwrite((char *) & data_ptr, sizeof(long), 1, index_file);
X
X	if (i > 0) 
X		return 0;
X	return - 1;
X
X}
X
X
X/* 
X   A hash function 
X*/
X
X/* some random # tables */
X
Xstatic int	tab1[16] = {
X	1, 13, 17, 7, 26, 53, 32, 36, 39, 41, 45, 48, 6, 60, 61, 57};
X
X
Xstatic long	tab2[64] = {
X	2839722806L,
X	2810802562L,
X	3339723161L,
X	1058549169L,
X	1994454359L,
X	3332972616L,
X	2024961869L,
X	1295774230L,
X	1401270575L,
X	550463474L,
X	4149832130L,
X	593802817L,
X	19870556L,
X	217796119L,
X	2030513628L,
X	2224253180L,
X	4086624884L,
X	2108878202L,
X	4081713897L,
X	1450431192L,
X	2682324517L,
X	3815655141L,
X	3437116049L,
X	1509200303L,
X	3320765546L,
X	592632684L,
X	4115672507L,
X	891714445L,
X	2101308635L,
X	1818339936L,
X	1641458119L,
X	2428086168L,
X	955496606L,
X	3732124452L,
X	263468725L,
X	4181304149L,
X	1757671992L,
X	4105130351L,
X	415998664L,
X	266182449L,
X	4145924110L,
X	3676915477L,
X	3152392912L,
X	3169100473L,
X	3094692794L,
X	449386310L,
X	279014040L,
X	1239368031L,
X	4072577141L,
X	2519571281L,
X	1138855693L,
X	2110586520L,
X	2544733821L,
X	621089071L,
X	828396835L,
X	901327585L,
X	1528193535L,
X	2448354394L,
X	3531633039L,
X	3272908074L,
X	2376181107L,
X	1827926286L,
X	2717853871L,
X	3969548575L};
X
X
Xstatic long	
Xhash(string, size)
Xchar	*string;
Xint	size;
X{
X	int	value1 = 0;
X	long	value2 = 0;
X
X	register unsigned	c;
X
X	while (size--) {
X		c = *string++;
X		value2 += tab2[(value1 += tab1[c & 15]) & 63];
X		value2 += tab2[(value1 += tab1[(c >> 4) & 15]) & 63];
X	}
X
X	if (value2 < 0) 
X		value2 = -value2;
X
X	return value2 % INDEX_SIZE;
X
X}
X
X
END_OF_dbz.c
if test 5385 -ne `wc -c <dbz.c`; then
    echo shar: \"dbz.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
-- 
Lenny Tropiano             ICUS Software Systems         [w] +1 (516) 582-5525
lenny at icus.islp.ny.us      Telex; 154232428 ICUS         [h] +1 (516) 968-8576
{talcott,decuac,boulder,hombre,pacbell,sbcs}!icus!lenny  attmail!icus!lenny
        ICUS Software Systems -- PO Box 1; Islip Terrace, NY  11752



More information about the Unix-pc.general mailing list