/*static char *SCCSID = "@(#)cbr.c	6.2 92/01/31";*/
#define ASWAP0 ASWAP0
#include <os2.h>
#include "const.h"
#include "misc.h"
#include "chain.h"
#include "buf.h"
#include "dir.h"
#include "storage.h"
#include "volume.h"
#include "tables.h"
#include "superb.h"
#include "pb_ifs.h"
#include "pbmacros.h"
#include "lw.h"
#include "frame.h"
#include "fsdata.h"
#include "pr_BITMP.h"
#include "pr_CACHE.h"
#include "pr_MISC.h"


/*
 ***	CBR - Count Bit Run Length
 *
 *	CBR counts the number of contiguous one bits from a
 *	specified position within the bit map.
 *
 *	CBR is called when we can't get the allocation that we
 *	want and we're settling for the best we can find.  This
 *	should be infrequent and generally would apply to big files,
 *	so we don't need to bust a gut to shave the cycles.
 *	We also don't need to put a limit on the scan, since if we
 *	had more space than we want (and would therefore waste time
 *	counting it) we wouldn't be calling this guy.
 *
 *	Note that we don't have to worry about running off the
 *	end of the bitmap, since all bitmaps end with at least
 *	one 00 byte; we'll see those zeros and quit.
 *
 *	ENTRY	offulStart = first bit to investigate
 *
 *	RETURNS count of bits available
 *		Yields CPU
 *
 *	HISTORY
 *	    23-Aug-1988 17:02:26 by Jon Parati [jonpa]	Wrote it
 *	    05-Oct-1988 16:45:37 by Jon Parati [jonpa]	Banding & Speed up
 */

USHORT
CBR ( offulStart, pfrm )
ULONG offulStart;		/* offset into bitmap of first bit to search */
PFRAME pfrm;
{
    register USHORT i;	/* index */
    register USHORT cb; /* count of bits */
    PBYTE pb;	    /* pointer into bitmap bits */
    BYTE bFirstBit;	/* bit index of first bit */
    PBANDTAB pbtb;
    PBUFNODE pbuf;

#ifdef DEBUG
    if( offulStart > pfrm->pvol->cSectsOnVol )
	INTERR( "cbr: starting sector not on volume" );
#endif

    if( offulStart == pfrm->pvol->cSectsOnVol )
	/* Last file sector is last volume sector */
	return 0;

    /* Initialize vars */
    pbtb = pfrm->pvol->apbndList [USSHIFTRUL (offulStart, BANDSHIFT)];
    i = (USHORT)(offulStart % BANDSIZE);
    bFirstBit = (BYTE)(i % 8);
    i /= 8;

    /*
     * Load the bandtab
     */

    /* DEBUG - This is a good place for statistical stuff */
                                                          //#85759
    if ((pb = LSDBM(&pbtb->scpMap, BP_KEEP, &pbuf, pfrm)) == NULL)
      return 0;

    pb = &pb[i];

    /* check if first byte goes on into next byte */
    if( (cb = abRCont[*pb]) >= (8 - bFirstBit) )
	{
	/*
	 * run spans more than 1 byte
	 */

	/* Count the number of filled bytes */
	/* BUGBUG - Gordon's code does not check for running off of
	 *	    bitmap, but we will since it is not that much
	 *	    of a runtime hit
	 */
	pb++;
	for( i = (USHORT)pbtb->cbMapLen -i -1; i != 0 && *pb == 0xFF; i-- )
	    {
	    pb++;
	    cb += 8;
	    }

	if( i )
	    {
     /* still on the bitmap so count the bits in the last byte */
	    cb += abLCont[*pb];
	    }

	 return cb;

	}
    else
	{
	/*
	 * run contained in first byte
	 */
	/*
	 * NOTE: bits are numbered 01234567 so "LeftCont" means
	 * contiguous from bit 0 upward.  Therefore we must
	 * use a '>>' to shift to what Gordon calls LEFT.
	 */

//RightContig means from bit 0 upward towards bit n in the string
//LeftContig means from bit n downward towards bit n-m in the string
//where n>m positionally

	 return abLCont[ *pb >> bFirstBit ];

	}

}
