blob: b7d8fe2b9a46274b083dd82d8b85758e43c202fa [file] [log] [blame]
/*
* Copyright (c) 2000-2001 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <xfs/xfs.h>
#include <xfs/jdm.h>
#include <sys/types.h>
#include <stdlib.h>
#include <memory.h>
#include "types.h"
#include "mlog.h"
#include "bag.h"
bag_t *
bag_alloc( void )
{
bag_t *bagp;
bagp = ( bag_t * )calloc( 1, sizeof( bag_t ));
ASSERT( bagp );
return bagp;
}
void
bag_insert( bag_t *bagp,
bagelem_t *newp,
size64_t key,
void *payloadp )
{
register bagelem_t *nextp;
register bagelem_t *prevp;
ASSERT( ! newp->be_loaded );
newp->be_loaded = BOOL_TRUE;
ASSERT( ! newp->be_bagp );
newp->be_bagp = bagp;
newp->be_key = key;
newp->be_payloadp = payloadp;
if ( bagp->b_headp ) {
nextp = bagp->b_headp;
prevp = bagp->b_headp->be_prevp;
} else {
nextp = newp;
prevp = newp;
}
newp->be_nextp = nextp;
newp->be_prevp = prevp;
nextp->be_prevp = newp;
prevp->be_nextp = newp;
bagp->b_headp = newp;
}
void
bag_remove( bag_t *bagp,
bagelem_t *oldp,
size64_t *keyp,
void **payloadpp )
{
register bagelem_t *nextp;
register bagelem_t *prevp;
ASSERT( oldp->be_loaded );
ASSERT( oldp->be_bagp == bagp );
nextp = oldp->be_nextp;
prevp = oldp->be_prevp;
nextp->be_prevp = prevp;
prevp->be_nextp = nextp;
if ( bagp->b_headp == oldp ) {
if ( nextp == oldp ) {
ASSERT( prevp == oldp );
bagp->b_headp = 0;
} else {
bagp->b_headp = nextp;
}
}
*keyp = oldp->be_key;
*payloadpp = oldp->be_payloadp;
memset( ( void * )oldp, 0, sizeof( bagelem_t ));
}
bagelem_t *
bag_find( bag_t *bagp,
size64_t key,
void **payloadpp )
{
register bagelem_t *p;
for ( p = bagp->b_headp
;
p && p->be_nextp != bagp->b_headp && p->be_key != key
;
p = p->be_nextp )
;
if ( ! p || p->be_key != key ) {
*payloadpp = 0;
return 0;
} else {
ASSERT( p->be_loaded );
ASSERT( p->be_bagp == bagp );
*payloadpp = p->be_payloadp;
return p;
}
}
void
bagiter_init( bag_t *bagp, bagiter_t *iterp )
{
iterp->bi_bagp = bagp;
if ( ! bagp->b_headp ) {
iterp->bi_nextp = 0;
return;
}
iterp->bi_lastp = bagp->b_headp->be_prevp;
iterp->bi_nextp = bagp->b_headp;
}
bagelem_t *
bagiter_next( bagiter_t *iterp, void **payloadpp )
{
bagelem_t *returnp;
/* termination condition
*/
if ( ! iterp->bi_nextp ) {
*payloadpp = 0;
return 0;
}
/* save the element to be returned
*/
returnp = iterp->bi_nextp;
/* calculate next. if returning last, set next to NULL
*/
if ( iterp->bi_nextp == iterp->bi_lastp ) {
iterp->bi_nextp = 0;
} else {
iterp->bi_nextp = iterp->bi_nextp->be_nextp;
}
*payloadpp = returnp->be_payloadp;
return returnp;
}
void
bag_free( bag_t *bagp )
{
register bagelem_t *p;
p = bagp->b_headp;
while ( p ) {
register bagelem_t *nextp = p->be_nextp;
memset( ( void * )p, 0, sizeof( bagelem_t ));
p = nextp;
if ( p == bagp->b_headp ) {
break;
}
ASSERT( p );
}
memset( ( void * )bagp, 0, sizeof( bag_t ));
free( ( void * )bagp );
}