//------------------------------------------------------------------------------
// DBRootExtentTracker constructor
//
// Mutex lock not needed in this function as it is only called from main thread
// before processing threads are spawned.
//------------------------------------------------------------------------------
DBRootExtentTracker::DBRootExtentTracker ( OID oid,
    int  colWidth,
    Log* logger,
    const BRM::EmDbRootHWMInfo_v& emDbRootHWMInfo ) :
    fOID(oid),
    fLog(logger),
    fCurrentDBRootIdx(-1),
    fEmptyOrDisabledPM(false),
    fEmptyPM(true),
    fDisabledHWM(false)
{
    fBlksPerExtent = (long long)BRMWrapper::getInstance()->getExtentRows() *
        (long long)colWidth / (long long)BYTE_PER_BLOCK;

    for (unsigned int i=0; i<emDbRootHWMInfo.size(); i++)
    {
        DBRootExtentInfo dbRootExtent(
            colWidth,
            emDbRootHWMInfo[i].dbRoot,
            emDbRootHWMInfo[i].partitionNum,
            emDbRootHWMInfo[i].segmentNum,
            emDbRootHWMInfo[i].startLbid,
            emDbRootHWMInfo[i].localHWM,
            emDbRootHWMInfo[i].totalBlocks,
            emDbRootHWMInfo[i].status);

        fDBRootExtentList.push_back( dbRootExtent );
    }

    std::sort( fDBRootExtentList.begin(), fDBRootExtentList.end() );

    if (fLog)
    {
        // Always log this info for now; may control with debug later
        //if (fLog->isDebug(DEBUG_1))
        {
            std::ostringstream oss;
            oss << "Starting DBRoot info for OID " << fOID;
            for (unsigned int k=0; k<fDBRootExtentList.size(); k++)
            {
                oss << std::endl;
                oss << "  DBRoot-" << fDBRootExtentList[k].fDbRoot <<
                    ", part/seg/hwm/LBID/totBlks/state: "          <<
                    fDBRootExtentList[k].fPartition                <<
                    "/" << fDBRootExtentList[k].fSegment           <<
                    "/" << fDBRootExtentList[k].fLocalHwm          <<
                    "/" << fDBRootExtentList[k].fStartLbid         <<
                    "/" << fDBRootExtentList[k].fDBRootTotalBlocks <<
                    "/" << stateStrings[ fDBRootExtentList[k].fState ];
            }
            fLog->logMsg( oss.str(), MSGLVL_INFO2 );
        }
    }
}
//------------------------------------------------------------------------------
// DBRootExtentTracker constructor
//
// Mutex lock not needed in this function as it is only called from main thread
// before processing threads are spawned.
//------------------------------------------------------------------------------
DBRootExtentTracker::DBRootExtentTracker ( OID oid,
    const std::vector<int>& colWidths,
    const std::vector<BRM::EmDbRootHWMInfo_v>& dbRootHWMInfoColVec,
    unsigned int columnIdx,
    Log* logger ) :
    fOID(oid),
    fLog(logger),
    fCurrentDBRootIdx(-1),
    fEmptyOrDisabledPM(false),
    fEmptyPM(true),
    fDisabledHWM(false)
{
    const BRM::EmDbRootHWMInfo_v& emDbRootHWMInfo =
        dbRootHWMInfoColVec[columnIdx];
    int colWidth = colWidths[columnIdx];

    fBlksPerExtent = (long long)BRMWrapper::getInstance()->getExtentRows() *
        (long long)colWidth / (long long)BYTE_PER_BLOCK;

    std::vector<bool> resetState;
    for (unsigned int i=0; i<emDbRootHWMInfo.size(); i++)
    {
        resetState.push_back(false);
        DBRootExtentInfoState state = determineState(
            colWidths[columnIdx],
            emDbRootHWMInfo[i].localHWM,
            emDbRootHWMInfo[i].totalBlocks,
            emDbRootHWMInfo[i].status);

        // For a full extent...
        // check to see if any of the column HWMs are partially full, in which
        // case we consider all the columns for that DBRoot to be partially
        // full.  (This can happen if a table has columns with varying widths,
        // as the HWM may be at the last extent block for a shorter column, and
        // still have free blocks for wider columns.)
        if (state == DBROOT_EXTENT_EXTENT_BOUNDARY)
        {
            for (unsigned int kCol=0; kCol<dbRootHWMInfoColVec.size(); kCol++)
            {
                const BRM::EmDbRootHWMInfo_v& emDbRootHWMInfo2 =
                    dbRootHWMInfoColVec[kCol];
                DBRootExtentInfoState state2 = determineState(
                    colWidths[kCol],
                    emDbRootHWMInfo2[i].localHWM,
                    emDbRootHWMInfo2[i].totalBlocks,
                    emDbRootHWMInfo2[i].status);
                if (state2 == DBROOT_EXTENT_PARTIAL_EXTENT)
                {
                    state = DBROOT_EXTENT_PARTIAL_EXTENT;
                    resetState[ resetState.size()-1 ] = true;
                    break;
                }
            }
        }

        DBRootExtentInfo dbRootExtent(
            emDbRootHWMInfo[i].dbRoot,
            emDbRootHWMInfo[i].partitionNum,
            emDbRootHWMInfo[i].segmentNum,
            emDbRootHWMInfo[i].startLbid,
            emDbRootHWMInfo[i].localHWM,
            emDbRootHWMInfo[i].totalBlocks,
            state);

        fDBRootExtentList.push_back( dbRootExtent );
    }

    std::sort( fDBRootExtentList.begin(), fDBRootExtentList.end() );

    if (fLog)
    {
        // Always log this info for now; may control with debug later
        //if (fLog->isDebug(DEBUG_1))
        {
            std::ostringstream oss;
            oss << "Starting DBRoot info for OID " << fOID;
            for (unsigned int k=0; k<fDBRootExtentList.size(); k++)
            {
                oss << std::endl;
                oss << "  DBRoot-" << fDBRootExtentList[k].fDbRoot <<
                    ", part/seg/hwm/LBID/totBlks/state: "          <<
                    fDBRootExtentList[k].fPartition                <<
                    "/" << fDBRootExtentList[k].fSegment           <<
                    "/" << fDBRootExtentList[k].fLocalHwm          <<
                    "/" << fDBRootExtentList[k].fStartLbid         <<
                    "/" << fDBRootExtentList[k].fDBRootTotalBlocks <<
                    "/" << stateStrings[ fDBRootExtentList[k].fState ];
                if (resetState[k])
                    oss << ".";
            }
            fLog->logMsg( oss.str(), MSGLVL_INFO2 );
        }
    }
}