Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/gnu/lib/brig.c
There are no other files named brig.c in the archive.
5-May-84 14:23:30-EDT,4356;000000000001
Received: from MIT-MC by MIT-OZ via Chaosnet; 5 May 84 14:23-EDT
Received: From bostonu.csnet by csnet-relay; 5 May 84 14:12 EDT
Received: by csvaxa.ARPA (4.12/4.7)
id AA23837; Sat, 5 May 84 13:55:57 edt
Date: Sat, 5 May 84 13:55:57 edt
From: God <root%[email protected]>
Message-Id: <[email protected]>
To: [email protected]
Subject: brig.c
#include "brig.h"
#ifdef DEBUG
#include <stdio.h>
#else
#define NULL 0
/*LINTLIBRARY*/
#endif
#ifndef REGISTER
#define REGISTER register
#endif
#ifndef REGARG
#define REGARG register
#endif
char *malloc() ;
/*
* GNU LIB
*
* A brigade is a chain of buckets, a bucket
* is a structure with a pointer to next and
* an array of data.
*
* They have the property that referring to an element
* forces it to be allocated, otherwise they are referred
* to quite like arrays.
*
* USER ROUTINES:
* bopen(sz,n) n: number of items per bucket
* sz: sizeof item
* returns: ptr for later usage
* bclose(hp) hp: ptr earlier gotten from bopen()
* returns: 0 always (assume non-0 error tho)
* getbp(hp,n) hp: ptr earlier gotten from bopen()
* n: index (like an array index)
* returns: ptr to storage for item
*
* INTERNAL ROUTINES:
* newb(hp) hp: head ptr
* returns: ptr to new bucket
*
* NOTES:
* Typing of the return value from getbp() presents a
* similar problem to malloc(). Macros help a lot.
* BUGS:
* Shouldn't be any, very straightforward algorithm.
* getbp() certainly tempts the user to not check for
* null returns, malloc() should probably interrupt on
* memory failure rather than returning NULL.
* AUTHOR:
* Barry Shein, Boston University (bzs%bostonu@csnet-relay)
* 5/4/84
*/
/*
* allocate a new bucket (internal only)
*/
static buck_t *
newb(hp) REGARG bhead_t *hp ;
{
REGISTER buck_t *bp ;
/*NOSTRICT*/
if((bp = (buck_t *) malloc(sizeof *bp)) == NULL)
;
/*NOSTRICT*/
else if((bp->bdata = (char *) malloc(hp->bperb * hp->nperb)) == NULL)
/*NOSTRICT*/
free(bp) ;
else return(bp) ;
return(NULL) ;
}
/*
* Start a new brigade
*/
bhead_t *
bopen(sz,n) int sz, n ;
{
REGISTER bhead_t *res ;
/*NOSTRICT*/
if((res = (bhead_t *) malloc(sizeof *res)) == NULL)
return(NULL) ;
else
{
res->bperb = sz ;
res->nperb = n ;
}
if((res->bhead = newb(res)) == NULL)
/*NOSTRICT*/
free(res) ;
else
{
res->bhead->bnext = NULL ;
res->bhead->bfirst = 0 ;
return(res) ;
}
return(NULL) ;
}
/*
* free all memory associated with a brigade
*/
bclose(hdrp) bhead_t *hdrp ;
{
REGISTER buck_t *hp, *lp ;
lp = hdrp->bhead ;
hp = lp->bnext ;
for(;;)
{
/*NOSTRICT*/
free(lp->bdata) ;
/*NOSTRICT*/
free(lp) ;
if((lp = hp) != NULL) hp = lp->bnext ;
else break ;
}
return(0) ;
}
/*
* return a pointer to the desired item
* the type of the return should be coerced.
* This could cause portability problems to
* those machines that have different sized ptrs.
*/
char *
getbp(hp,n) REGARG bhead_t *hp ; REGARG int n ;
{
REGISTER buck_t *lp ;
lp = hp->bhead ;
for(;; lp = lp->bnext)
{
/*
* See if it is in current bucket. If so done.
*/
if((lp->bfirst <= n) && ((lp->bfirst + hp->nperb) > n))
return(lp->bdata + (hp->bperb * (n - lp->bfirst))) ;
/*
* If no next or a hole then create appropiate
* bucket
*/
if((lp->bnext == NULL) || (lp->bnext->bfirst > n))
{
buck_t *nb ;
if((nb = newb(hp)) == NULL)
return(NULL) ;
nb->bnext = lp->bnext ;
lp->bnext = nb ;
nb->bfirst = hp->nperb * (n / hp->nperb) ;
return(nb->bdata + (hp->bperb * (n - nb->bfirst))) ;
}
}
}
#ifdef DEBUG
/*
* main I used to test the code, just #define DEBUG at top and recompile
*/
#define IP(n) (*((int *) getbp(hp,n)))
main(argc,argv) int argc ; char **argv ;
{
bhead_t *hp ;
int i ;
if((hp = bopen(sizeof i,10)) == NULL)
{
fprintf(stderr,"bopen => NULL?\n") ;
exit(1) ;
}
for(i = 0 ; i < 99 ; i++)
IP(i) = i ;
IP(500) = 500 ;
IP(350) = 350 ;
IP(250) = 250 ;
IP(351) = 351 ;
for(i = 0 ; i < 99 ; i++)
printf("%d\n",IP(i)) ;
printf("%d %d %d %d\n",IP(500),IP(350),IP(250),IP(351)) ;
printf("%d\n",bclose(hp)) ;
}
#endif