//-------------------------------------------------------------------------
// Desc: Class for displaying an RCACHE structure in HTML on a web page.
// Tabs: 3
//
// Copyright (c) 2001-2006 Novell, Inc. All Rights Reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the GNU General Public
// License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will 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, contact Novell, Inc.
//
// To contact Novell about this file by physical or electronic mail,
// you may find current contact information at www.novell.com
//
// $Id: imonrche.cpp 12329 2006-01-20 17:49:30 -0700 (Fri, 20 Jan 2006) ahodgkinson $
//-------------------------------------------------------------------------
#include "flaimsys.h"
#define GENERIC_SIZE 1024
FSTATIC void flmBuildRCacheLink(
char * pszString,
RCACHE * pRCache,
char * pszURLString);
/****************************************************************************
Desc: procedure to display the contents of the RCache Manager
****************************************************************************/
RCODE F_RCacheMgrPage::display(
FLMUINT uiNumParams,
const char ** ppszParams)
{
RCODE rc = FERR_OK;
FLMBOOL bUsage;
FLMBOOL bRefresh;
FLMBYTE * pszTemp = NULL;
if( RC_BAD( rc = f_alloc( 150, &pszTemp)))
{
printErrorPage( rc, TRUE, (char *)"Failed to allocate temporary buffer");
goto Exit;
}
// Determine if we are being requested to refresh this page or not and if
// we are being asked to show the Usage Statistics.
bRefresh = DetectParameter( uiNumParams, ppszParams, "Refresh");
bUsage = DetectParameter( uiNumParams, ppszParams, "Usage");
// Invoke the public function to display the Usage structure.
if (bUsage)
{
RCACHE_MGR LocalRCacheMgr;
RCACHE_MGR * pRCacheMgr;
f_mutexLock( gv_FlmSysData.hShareMutex);
f_mutexLock( gv_FlmSysData.RCacheMgr.hMutex);
f_memcpy(
&LocalRCacheMgr,
(char *)&gv_FlmSysData.RCacheMgr,
sizeof(LocalRCacheMgr));
f_mutexUnlock( gv_FlmSysData.RCacheMgr.hMutex);
f_mutexUnlock( gv_FlmSysData.hShareMutex);
pRCacheMgr = &LocalRCacheMgr;
rc = writeUsage(
&pRCacheMgr->Usage,
bRefresh,
"/RCacheMgr?Usage",
"RCache Manager Usage Statistics");
goto Exit;
}
stdHdr();
fnPrintf( m_pHRequest, HTML_DOCTYPE);
fnPrintf( m_pHRequest, "\n");
if (bRefresh)
{
// Send back the page with a refresh command in the header
fnPrintf( m_pHRequest,
"
"
""
"gv_FlmSysData.RCacheMgr\n",
m_pszURLString);
// Add the function to generate a popup framed window only if this is not
// showing the Usage statistics.
printStyle();
popupFrame();
fnPrintf( m_pHRequest, "\n");
fnPrintf( m_pHRequest, "\n");
f_sprintf( (char *)pszTemp,
"Stop Auto-refresh",
m_pszURLString);
}
else
{
// Add the function to generate a popup framed window if not
// displaying the Usage.
fnPrintf( m_pHRequest, "gv_FlmSysData.RCacheMgr\n");
printStyle();
popupFrame();
fnPrintf( m_pHRequest, "\n");
// Send back a page without the refresh command
fnPrintf( m_pHRequest, "\n");
f_sprintf( (char *)pszTemp,
"Start Auto-refresh (5 sec.)",
m_pszURLString);
}
// Begin the table
printTableStart( "RCache Manager", 4, 100);
printTableRowStart();
printColumnHeading( "", JUSTIFY_LEFT, FLM_IMON_COLOR_PUTTY_1, 4, 1, FALSE);
fnPrintf( m_pHRequest, "Refresh, ",
m_pszURLString);
fnPrintf( m_pHRequest, "%s\n", pszTemp);
printColumnHeadingClose();
printTableRowEnd();
// Write out the table headings
printTableRowStart();
printColumnHeading( "Byte Offset (hex)");
printColumnHeading( "Field Name");
printColumnHeading( "Field Type");
printColumnHeading( "Value");
printTableRowEnd();
write_data();
fnPrintf( m_pHRequest, "\n");
Exit:
fnEmit();
if (pszTemp)
{
f_free( &pszTemp);
}
return( rc);
}
/****************************************************************************
Desc: private procedure to generate the HTML page
****************************************************************************/
void F_RCacheMgrPage::write_data( void)
{
RCODE rc = FERR_OK;
char szTemp[100];
RCACHE_MGR LocalRCacheMgr;
RCACHE_MGR * pRCacheMgr;
FLMBOOL bFlaimLocked = FALSE;
RCACHE * pPurgeList = NULL;
RCACHE * pMRURecord = NULL;
RCACHE * pLRURecord = NULL;
char szAddress[20];
char szOffset[8];
FLMBOOL bHighlight = FALSE;
// First, get a local copy of the RCacheMgr structure so we don't interfere
// with the operation of the database.
f_mutexLock( gv_FlmSysData.hShareMutex);
f_mutexLock( gv_FlmSysData.RCacheMgr.hMutex);
bFlaimLocked = TRUE;
f_memcpy(&LocalRCacheMgr,
&gv_FlmSysData.RCacheMgr,
sizeof(LocalRCacheMgr));
pRCacheMgr = &LocalRCacheMgr;
// Make copies of needed records so we can use them later.
if (pRCacheMgr->pPurgeList)
{
if (RC_BAD( rc = f_alloc( sizeof(RCACHE), &pPurgeList)))
{
goto Exit;
}
f_memcpy( pPurgeList, pRCacheMgr->pPurgeList, sizeof(RCACHE));
}
if (pRCacheMgr->pMRURecord)
{
if (RC_BAD( rc = f_alloc( sizeof(RCACHE), &pMRURecord)))
{
goto Exit;
}
f_memcpy( pMRURecord, pRCacheMgr->pMRURecord, sizeof(RCACHE));
}
if (pRCacheMgr->pLRURecord)
{
if (RC_BAD( rc = f_alloc( sizeof(RCACHE), &pLRURecord)))
{
goto Exit;
}
f_memcpy( pLRURecord, pRCacheMgr->pLRURecord, sizeof(RCACHE));
}
f_mutexUnlock( gv_FlmSysData.RCacheMgr.hMutex);
f_mutexUnlock( gv_FlmSysData.hShareMutex);
bFlaimLocked = FALSE;
// pPurgeList
if (pRCacheMgr->pPurgeList)
{
printAddress( pPurgeList->pFile, szAddress);
f_sprintf((char *)szTemp,
"%s/RCache?Container=%lu?DRN=%lu?File=%s?Version=%lu",
m_pszURLString,
(unsigned long)pPurgeList->uiContainer,
(unsigned long)pPurgeList->uiDrn,
szAddress,
(unsigned long)pPurgeList->uiLowTransId);
}
printHTMLLink(
"pPurgeList",
"RCACHE *",
(void *)pRCacheMgr,
(void *)&pRCacheMgr->pPurgeList,
(void *)pRCacheMgr->pPurgeList,
(char*)szTemp,
(bHighlight = ~bHighlight));
// pMRURecord
if (pRCacheMgr->pMRURecord)
{
printAddress( pMRURecord->pFile, szAddress);
f_sprintf((char *)szTemp,
"%s/RCache?Container=%lu?DRN=%lu?File=%s?Version=%lu",
m_pszURLString,
(unsigned long)pMRURecord->uiContainer,
(unsigned long)pMRURecord->uiDrn,
szAddress,
(unsigned long)pMRURecord->uiLowTransId);
}
printHTMLLink(
"pMRURecord",
"RCACHE *",
(void *)pRCacheMgr,
(void *)&pRCacheMgr->pMRURecord,
(void *)pRCacheMgr->pMRURecord,
(char*)szTemp,
(bHighlight = ~bHighlight));
// pLRURecord
if (pRCacheMgr->pLRURecord)
{
printAddress( pRCacheMgr->pLRURecord->pFile, szAddress);
f_sprintf((char *)szTemp,
"%s/RCache?Container=%lu?DRN=%ld?File=%s?Version=%ld",
m_pszURLString,
(unsigned long)pLRURecord->uiContainer,
(unsigned long)pLRURecord->uiDrn,
szAddress,
(unsigned long)pLRURecord->uiLowTransId);
}
printHTMLLink(
"pLRURecord",
"RCACHE *",
(void *)pRCacheMgr,
(void *)&pRCacheMgr->pLRURecord,
(void *)pRCacheMgr->pLRURecord,
(char*)szTemp,
(bHighlight = ~bHighlight));
// Usage
printTableRowStart( (bHighlight = ~bHighlight));
f_sprintf( (char *)szTemp, "%s/RCacheMgr?Usage",
m_pszURLString);
printOffset( (void *)pRCacheMgr, (void *)&pRCacheMgr->Usage, szOffset);
fnPrintf( m_pHRequest, TD_s, szOffset); // Field offset
fnPrintf( m_pHRequest, TD_a_p_s, szTemp, "Usage"); // Link & Name
fnPrintf( m_pHRequest, TD_s, "FLM_CACHE_USAGE"); // Type
fnPrintf( m_pHRequest, TD_a_p_x, szTemp, (FLMUINT)&pRCacheMgr->Usage); // Link & Value
printTableRowEnd();
// ppHashBuckets
if (pRCacheMgr->ppHashBuckets)
{
f_sprintf( (char *)szTemp, "%s/RCHashBucket?Start=0",
m_pszURLString);
}
printHTMLLink(
"ppHashBuckets",
"RCACHE **",
(void *)pRCacheMgr,
(void *)&pRCacheMgr->ppHashBuckets,
(void *)pRCacheMgr->ppHashBuckets,
(char*)szTemp,
(bHighlight = ~bHighlight));
// uiNumBuckets
printHTMLUint(
"uiNumBuckets",
"FLMUINT",
(void *)pRCacheMgr,
(void *)&pRCacheMgr->uiNumBuckets,
pRCacheMgr->uiNumBuckets,
(bHighlight = ~bHighlight));
// uiHashMask
printHTMLUint(
"uiHashMask",
"FLMUINT",
(void *)pRCacheMgr,
(void *)&pRCacheMgr->uiHashMask,
pRCacheMgr->uiHashMask,
(bHighlight = ~bHighlight));
// uiPendingReads
printHTMLUint(
"uiPendingReads",
"FLMUINT",
(void *)pRCacheMgr,
(void *)&pRCacheMgr->uiPendingReads,
pRCacheMgr->uiPendingReads,
(bHighlight = ~bHighlight));
// uiIoWaits
printHTMLUint(
"uiIoWaits",
"FLMUINT",
(void *)pRCacheMgr,
(void *)&pRCacheMgr->uiIoWaits,
pRCacheMgr->uiIoWaits,
(bHighlight = ~bHighlight));
// hMutex
printAddress( &pRCacheMgr->hMutex, szAddress);
printHTMLString(
"hMutex",
"F_MUTEX",
(void *)pRCacheMgr,
(void *)&pRCacheMgr->hMutex,
(char*)szAddress,
(bHighlight = ~bHighlight));
#ifdef FLM_DEBUG
// bDebug
printHTMLString(
"bDebug",
"F_MUTEX",
(void *)pRCacheMgr,
(void *)&pRCacheMgr->bDebug,
(char *)(pRCacheMgr->bDebug ? "Yes" : "No"),
(bHighlight = ~bHighlight));
#endif
Exit:
printTableEnd();
if (bFlaimLocked)
{
f_mutexUnlock( gv_FlmSysData.RCacheMgr.hMutex);
f_mutexUnlock( gv_FlmSysData.hShareMutex);
bFlaimLocked = FALSE;
}
if (pPurgeList)
{
f_free( &pPurgeList);
}
if (pMRURecord)
{
f_free( &pMRURecord);
}
if (pLRURecord)
{
f_free( &pLRURecord);
}
}
/****************************************************************************
Desc: Implements the RCache display function.
*****************************************************************************/
RCODE F_RCachePage::display(
FLMUINT uiNumParams,
const char ** ppszParams)
{
RCODE rc = FERR_OK;
char szContainer[GENERIC_SIZE];
FLMUINT uiContainer;
char szDrn[GENERIC_SIZE];
FLMUINT uiDrn;
char szVersion[GENERIC_SIZE];
FLMUINT uiVersion;
char szTemp[GENERIC_SIZE];
RCACHE * pRCache = NULL;
RCACHE * pOlderRCache;
RCACHE * pNewerRCache;
char szFile[GENERIC_SIZE];
FFILE * pFile;
char szFrom[GENERIC_SIZE];
char szBucket[GENERIC_SIZE];
FLMUINT uiBucket;
FLMBOOL bRCLocked = FALSE;
FLMBOOL bpFileInc = FALSE;
FLMBYTE * pszTemp = NULL;
if( RC_BAD( rc = f_alloc( 150, &pszTemp)))
{
printErrorPage( rc, TRUE, (char *)"Failed to allocate temporary buffer");
goto Exit;
}
// Check to see if this page is being invoked from the RCHashBucket
// Page. If it is, then all we will need is the Bucket and we should
// be able to find the RCache block.
if (RC_BAD( rc = ExtractParameter( uiNumParams,
ppszParams,
"From",
sizeof( szFrom),
szFrom)))
{
if (rc != FERR_NOT_FOUND)
{
goto Exit;
}
else
{
szFrom[0] = '\0';
}
}
if (f_strcmp( szFrom, "RCHashBucket")==0)
{
if (RC_BAD(rc = ExtractParameter(uiNumParams,
ppszParams,
"Bucket",
sizeof( szBucket),
szBucket)))
{
goto Exit;
}
uiBucket = f_atoud( szBucket);
// We need to lock the RCache Manager before messing with the RCache records
f_mutexLock( gv_FlmSysData.hShareMutex);
f_mutexLock( gv_FlmSysData.RCacheMgr.hMutex);
bRCLocked = TRUE;
if ((pRCache = gv_FlmSysData.RCacheMgr.ppHashBuckets[uiBucket]) == NULL)
{
goto Exit;
}
uiContainer = pRCache->uiContainer;
uiDrn = pRCache->uiDrn;
uiVersion = pRCache->uiLowTransId;
pFile = pRCache->pFile;
pRCache = NULL; // We will retrieve this again later.
f_mutexUnlock( gv_FlmSysData.RCacheMgr.hMutex);
f_mutexUnlock( gv_FlmSysData.hShareMutex);
bRCLocked = FALSE;
}
else
{
// Container tag
if (RC_BAD( rc = ExtractParameter( uiNumParams,
ppszParams,
"Container",
sizeof( szContainer),
szContainer)))
{
goto Exit;
}
uiContainer = f_atoud( szContainer);
// DRN tag
if (RC_BAD(rc = ExtractParameter( uiNumParams,
ppszParams,
"DRN",
sizeof( szDrn),
szDrn)))
{
goto Exit;
}
uiDrn = f_atoud( szDrn);
// File tag
if (RC_BAD(rc = ExtractParameter( uiNumParams,
ppszParams,
"File",
sizeof( szFile),
szFile)))
{
goto Exit;
}
pFile = (FFILE *)f_atoud( szFile);
// Version tag
if (RC_BAD(rc = ExtractParameter( uiNumParams,
ppszParams,
"Version",
sizeof( szVersion),
szVersion)))
{
goto Exit;
}
uiVersion = f_atoud( szVersion);
}
stdHdr();
fnPrintf( m_pHRequest, HTML_DOCTYPE);
fnPrintf( m_pHRequest, "\n");
// Determine if we are being requested to refresh this page or not.
if (DetectParameter( uiNumParams, ppszParams, "Refresh"))
{
// Send back the page with a refresh command in the header
f_sprintf((char *)szTemp,
"%s/RCache?Refresh?Container=%s?DRN=%s?File=%s?Version=%s",
m_pszURLString,
szContainer, szDrn, szFile, szVersion);
fnPrintf( m_pHRequest,
""
""
"RCache\n",
szTemp);
printStyle();
fnPrintf( m_pHRequest, "\n");
f_sprintf((char *)szTemp,
"%s/RCache?Container=%s?DRN=%s?File=%s?Version=%s",
m_pszURLString,
szContainer, szDrn, szFile, szVersion);
fnPrintf( m_pHRequest, "\n");
f_sprintf( (char *)pszTemp,
"Stop Auto-refresh", szTemp);
}
else
{
fnPrintf( m_pHRequest, "RCache\n");
printStyle();
fnPrintf( m_pHRequest, "\n");
f_sprintf((char *)szTemp,
"%s/RCache?Refresh?Container=%s?DRN=%s?File=%s?Version=%s",
m_pszURLString,
szContainer, szDrn, szFile, szVersion);
fnPrintf( m_pHRequest, "\n");
f_sprintf( (char *)pszTemp,
"Start Auto-refresh (5 sec.)", szTemp);
}
// Prepare the Refresh link.
f_sprintf((char *)szTemp,
"%s/RCache?Container=%s?DRN=%s?File=%s?Version=%s",
m_pszURLString,
szContainer, szDrn, szFile, szVersion);
// Need to lock the record Cache mutex first...
f_mutexLock( gv_FlmSysData.hShareMutex);
f_mutexLock( gv_FlmSysData.RCacheMgr.hMutex);
bRCLocked = TRUE;
flmRcaFindRec( pFile, F_SEM_NULL, uiContainer, uiDrn, uiVersion, TRUE,
0, &pRCache, &pNewerRCache, &pOlderRCache);
// We want to hold the RCache and pFile in memory while we render this page.
if (pRCache)
{
RCA_INCR_USE_COUNT( pRCache->uiFlags);
if (++pRCache->pFile->uiUseCount == 1)
{
flmUnlinkFileFromNUList( pFile);
}
bpFileInc = TRUE;
}
f_mutexUnlock( gv_FlmSysData.RCacheMgr.hMutex);
f_mutexUnlock( gv_FlmSysData.hShareMutex);
bRCLocked = FALSE;
if (pRCache)
{
// Begin the table
printTableStart( "RCache", 4);
printTableRowStart();
printColumnHeading( "", JUSTIFY_LEFT, FLM_IMON_COLOR_PUTTY_1, 4, 1, FALSE);
fnPrintf( m_pHRequest, "Refresh, ", szTemp);
fnPrintf( m_pHRequest, "%s\n", pszTemp);
printColumnHeadingClose();
printTableRowEnd();
// Write out the table headings
printTableRowStart();
printColumnHeading( "Byte Offset (hex)");
printColumnHeading( "Field Name");
printColumnHeading( "Field Type");
printColumnHeading( "Value");
printTableRowEnd();
write_data(pRCache);
}
else
{
// Return an error page
fnPrintf( m_pHRequest,
"Unable to find the RCache structure that you requested."
" This is probably because the state of the cache changed "
"between the time that you displayed the previous page and the time "
"that you clicked on the link that brought you here.\n"
"
Click on your browser's \"Back\" button, then click \"Reload\" "
"and then try the link again.
\n");
}
fnPrintf( m_pHRequest, "\n");
fnEmit();
// Now decrement the use count on the pFile and on the RCache
if (pRCache)
{
if (bpFileInc)
{
if (--pRCache->pFile->uiUseCount == 0)
{
flmLinkFileToNUList( pRCache->pFile);
}
bpFileInc = FALSE;
}
RCA_DECR_USE_COUNT( pRCache->uiFlags);
}
Exit:
if ( bRCLocked)
{
f_mutexUnlock( gv_FlmSysData.RCacheMgr.hMutex);
f_mutexUnlock( gv_FlmSysData.hShareMutex);
}
if (pszTemp)
{
f_free( &pszTemp);
}
return( rc);
}
/****************************************************************************
Desc: This is procedure for generating HTML content for an RCACHE structure
****************************************************************************/
void F_RCachePage::write_data(
RCACHE * pRCache)
{
char szTemp[GENERIC_SIZE];
char szAddress[20];
FLMBOOL bHighlight = FALSE;
F_UNREFERENCED_PARM( fnPrintf);
if (!pRCache)
{
flmAssert(0);
return;
}
else
{
// pRecord
if (pRCache->pRecord)
{
printAddress( pRCache->pFile, szAddress);
f_sprintf((char *)szTemp,
"%s/Record?Container=%lu?DRN=%lu?File=%s?Version=%lu",
m_pszURLString,
(unsigned long)pRCache->uiContainer,
(unsigned long)pRCache->uiDrn,
szAddress,
(unsigned long)pRCache->uiLowTransId);
}
printHTMLLink(
"pRecord",
"FlmRecord *",
(void *)pRCache,
(void *)&pRCache->pRecord,
(void *)pRCache->pRecord,
(char*)szTemp,
(bHighlight = ~bHighlight));
// pFile
if (pRCache->pFile)
{
printAddress( pRCache->pFile, szAddress);
f_sprintf((char *)szTemp,
"%s/FFile?From=RCache?Bucket=%lu?Address=%s",
m_pszURLString,
(unsigned long)pRCache->pFile->uiBucket,
szAddress);
}
printHTMLLink(
"pFile",
"FFILE *",
(void *)pRCache,
(void *)&pRCache->pFile,
(void *)pRCache->pFile,
(char*)szTemp,
(bHighlight = ~bHighlight));
// uiContainer
printHTMLUint(
"uiContainer",
"FLMUINT",
(void *)pRCache,
(void *)&pRCache->uiContainer,
pRCache->uiContainer,
(bHighlight = ~bHighlight));
// uiDrn
printHTMLUint(
"uiDrn",
"FLMUINT",
(void *)pRCache,
(void *)&pRCache->uiDrn,
pRCache->uiDrn,
(bHighlight = ~bHighlight));
// uiLowTransId
printHTMLUint(
"uiLowTransId",
"FLMUINT",
(void *)pRCache,
(void *)&pRCache->uiLowTransId,
pRCache->uiLowTransId,
(bHighlight = ~bHighlight));
// uiHighTransId
printHTMLUint(
"uiHighTransId",
"FLMUINT",
(void *)pRCache,
(void *)&pRCache->uiHighTransId,
pRCache->uiHighTransId,
(bHighlight = ~bHighlight));
// pNextInBucket
if (pRCache->pNextInBucket)
{
printAddress( pRCache->pNextInBucket->pFile, szAddress);
f_sprintf((char *)szTemp,
"%s/RCache?Container=%lu?DRN=%lu?File=%s?Version=%lu",
m_pszURLString,
(unsigned long)pRCache->pNextInBucket->uiContainer,
(unsigned long)pRCache->pNextInBucket->uiDrn,
szAddress,
(unsigned long)pRCache->pNextInBucket->uiLowTransId);
}
printHTMLLink(
"pNextInBucket",
"RCACHE *",
(void *)pRCache,
(void *)&pRCache->pNextInBucket,
(void *)pRCache->pNextInBucket,
(char*)szTemp,
(bHighlight = ~bHighlight));
// pPrevInBucket
if (pRCache->pPrevInBucket)
{
printAddress( pRCache->pPrevInBucket->pFile, szAddress);
f_sprintf((char *)szTemp,
"%s/RCache?Container=%lu?DRN=%lu?File=%s?Version=%lu",
m_pszURLString,
(unsigned long)pRCache->pPrevInBucket->uiContainer,
(unsigned long)pRCache->pPrevInBucket->uiDrn,
szAddress,
(unsigned long)pRCache->pPrevInBucket->uiLowTransId);
}
printHTMLLink(
"pPrevInBucket",
"RCACHE *",
(void *)pRCache,
(void *)&pRCache->pPrevInBucket,
(void *)pRCache->pPrevInBucket,
(char*)szTemp,
(bHighlight = ~bHighlight));
// pNextInFile
if (pRCache->pNextInFile)
{
printAddress( pRCache->pNextInFile->pFile, szAddress);
f_sprintf((char *)szTemp,
"%s/RCache?Container=%lu?DRN=%lu?File=%s?Version=%lu",
m_pszURLString,
(unsigned long)pRCache->pNextInFile->uiContainer,
(unsigned long)pRCache->pNextInFile->uiDrn,
szAddress,
(unsigned long)pRCache->pNextInFile->uiLowTransId);
}
printHTMLLink(
"pNextInFile",
"RCACHE *",
(void *)pRCache,
(void *)&pRCache->pNextInFile,
(void *)pRCache->pNextInFile,
(char*)szTemp,
(bHighlight = ~bHighlight));
// pPrevInFile
if (pRCache->pPrevInFile)
{
printAddress( pRCache->pPrevInFile->pFile, szAddress);
f_sprintf((char *)szTemp,
"%s/RCache?Container=%lu?DRN=%lu?File=%s?Version=%lu",
m_pszURLString,
(unsigned long)pRCache->pPrevInFile->uiContainer,
(unsigned long)pRCache->pPrevInFile->uiDrn,
szAddress,
(unsigned long)pRCache->pPrevInFile->uiLowTransId);
}
printHTMLLink(
"pPrevInFile",
"RCACHE *",
(void *)pRCache,
(void *)&pRCache->pPrevInFile,
(void *)pRCache->pPrevInFile,
(char*)szTemp,
(bHighlight = ~bHighlight));
// pNextInGlobal
if (pRCache->pNextInGlobal)
{
printAddress( pRCache->pNextInGlobal->pFile, szAddress);
f_sprintf((char *)szTemp,
"%s/RCache?Container=%lu?DRN=%lu?File=%s?Version=%lu",
m_pszURLString,
(unsigned long)pRCache->pNextInGlobal->uiContainer,
(unsigned long)pRCache->pNextInGlobal->uiDrn,
szAddress,
(unsigned long)pRCache->pNextInGlobal->uiLowTransId);
}
printHTMLLink(
"pNextInGlobal",
"RCACHE *",
(void *)pRCache,
(void *)&pRCache->pNextInGlobal,
(void *)pRCache->pNextInGlobal,
(char*)szTemp,
(bHighlight = ~bHighlight));
// pPrevInGlobal
if (pRCache->pPrevInGlobal)
{
printAddress( pRCache->pPrevInGlobal->pFile, szAddress);
f_sprintf((char *)szTemp,
"%s/RCache?Container=%lu?DRN=%lu?File=%s?Version=%lu",
m_pszURLString,
(unsigned long)pRCache->pPrevInGlobal->uiContainer,
(unsigned long)pRCache->pPrevInGlobal->uiDrn,
szAddress,
(unsigned long)pRCache->pPrevInGlobal->uiLowTransId);
}
printHTMLLink(
"pPrevInGlobal",
"RCACHE *",
(void *)pRCache,
(void *)&pRCache->pPrevInGlobal,
(void *)pRCache->pPrevInGlobal,
(char*)szTemp,
(bHighlight = ~bHighlight));
// pOlderVersion
if (pRCache->pOlderVersion)
{
printAddress( pRCache->pOlderVersion->pFile, szAddress);
f_sprintf((char *)szTemp,
"%s/RCache?Container=%lu?DRN=%lu?File=%s?Version=%lu",
m_pszURLString,
(unsigned long)pRCache->pOlderVersion->uiContainer,
(unsigned long)pRCache->pOlderVersion->uiDrn,
szAddress,
(unsigned long)pRCache->pOlderVersion->uiLowTransId);
}
printHTMLLink(
"pOlderVersion",
"RCACHE *",
(void *)pRCache,
(void *)&pRCache->pOlderVersion,
(void *)pRCache->pOlderVersion,
(char*)szTemp,
(bHighlight = ~bHighlight));
// pNewerVersion
if (pRCache->pNewerVersion)
{
printAddress( pRCache->pNewerVersion->pFile, szAddress);
f_sprintf((char *)szTemp,
"%s/RCache?Container=%lu?DRN=%lu?File=%s?Version=%lu",
m_pszURLString,
(unsigned long)pRCache->pNewerVersion->uiContainer,
(unsigned long)pRCache->pNewerVersion->uiDrn,
szAddress,
(unsigned long)pRCache->pNewerVersion->uiLowTransId);
}
printHTMLLink(
"pNewerVersion",
"RCACHE *",
(void *)pRCache,
(void *)&pRCache->pNewerVersion,
(void *)pRCache->pNewerVersion,
(char*)szTemp,
(bHighlight = ~bHighlight));
// pNotifyList
if (pRCache->pNotifyList)
{
printAddress( pRCache->pNotifyList, szAddress);
f_sprintf((char *)szTemp, "%s/FNOTIFY?From=RCache?Address=%s",
m_pszURLString,
szAddress);
}
printHTMLLink(
"pNotifyList",
"FNOTIFY *",
(void *)pRCache,
(void *)&pRCache->pNotifyList,
(void *)pRCache->pNotifyList,
(char*)szTemp,
(bHighlight = ~bHighlight));
// uiFlags
printHTMLUint(
"uiFlags",
"FLMUINT",
(void *)pRCache,
(void *)&pRCache->uiFlags,
pRCache->uiFlags,
(bHighlight = ~bHighlight));
printTableEnd();
}
}
/****************************************************************************
Desc: Implements the Record display function.
*****************************************************************************/
RCODE F_RecordPage::display(
FLMUINT uiNumParams,
const char ** ppszParams)
{
RCODE rc = FERR_OK;
char szContainer[GENERIC_SIZE];
FLMUINT uiContainer;
char szDrn[GENERIC_SIZE];
FLMUINT uiDrn;
char szVersion[GENERIC_SIZE];
FLMUINT uiVersion;
char szTemp[GENERIC_SIZE];
RCACHE * pRCache = NULL;
RCACHE * pOlderRCache;
RCACHE * pNewerRCache;
char szFile[GENERIC_SIZE];
FFILE * pFile;
FlmRecord * pRecord = NULL;
FLMBOOL bpFileInc = FALSE;
FLMBYTE * pszTemp = NULL;
if( RC_BAD( rc = f_alloc( 150, &pszTemp)))
{
printErrorPage( rc, TRUE, (char *)"Failed to allocate temporary buffer");
goto Exit;
}
// Container tag
if (RC_BAD( rc = ExtractParameter( uiNumParams,
ppszParams,
"Container",
sizeof( szContainer),
szContainer)))
{
goto Exit;
}
uiContainer = f_atoud( szContainer);
// DRN tag
if (RC_BAD( rc = ExtractParameter( uiNumParams,
ppszParams,
"DRN",
sizeof( szDrn),
szDrn)))
{
goto Exit;
}
uiDrn = f_atoud( szDrn);
// File tag
if (RC_BAD( rc = ExtractParameter( uiNumParams,
ppszParams,
"File",
sizeof( szFile),
szFile)))
{
goto Exit;
}
pFile = (FFILE *)f_atoud( szFile);
// Version tag
if (RC_BAD( rc = ExtractParameter( uiNumParams,
ppszParams,
"Version",
sizeof( szVersion),
szVersion)))
{
goto Exit;
}
uiVersion = f_atoud( szVersion);
stdHdr();
fnPrintf( m_pHRequest, HTML_DOCTYPE);
fnPrintf( m_pHRequest, "\n");
// Determine if we are being requested to refresh this page or not.
if (DetectParameter( uiNumParams, ppszParams, "Refresh"))
{
// Send back the page with a refresh command in the header
f_sprintf((char *)szTemp,
"%s/Record?Refresh?Container=%s?DRN=%s?File=%s?Version=%s",
m_pszURLString,
szContainer, szDrn, szFile, szVersion);
fnPrintf( m_pHRequest,
""
"Database iMonitor - gv_FlmSysData\n", szTemp);
printRecordStyle();
printStyle();
fnPrintf( m_pHRequest, "\n");
fnPrintf( m_pHRequest, "\n");
f_sprintf((char *)szTemp,
"%s/Record?Container=%s?DRN=%s?File=%s?Version=%s",
m_pszURLString,
szContainer, szDrn, szFile, szVersion);
f_sprintf( (char *)pszTemp,
"Stop Auto-refresh", szTemp);
}
else
{
fnPrintf( m_pHRequest, "Database iMonitor - gv_FlmSysData\n");
printRecordStyle();
printStyle();
fnPrintf( m_pHRequest, "\n");
fnPrintf( m_pHRequest, "\n");
f_sprintf((char *)szTemp,
"%s/Record?Refresh?Container=%s?DRN=%s?File=%s?Version=%s",
m_pszURLString,
szContainer, szDrn, szFile, szVersion);
f_sprintf( (char *)pszTemp,
"Start Auto-refresh (5 sec.)", szTemp);
}
// Prepare the refresh link.
f_sprintf((char *)szTemp,
"%s/Record?Container=%s?DRN=%s?File=%s?Version=%s",
m_pszURLString,
szContainer, szDrn, szFile, szVersion);
// Need to lock the record Cache mutex first...
f_mutexLock( gv_FlmSysData.hShareMutex);
f_mutexLock( gv_FlmSysData.RCacheMgr.hMutex);
flmRcaFindRec( pFile, F_SEM_NULL, uiContainer, uiDrn, uiVersion,
TRUE, 0, &pRCache, &pNewerRCache, &pOlderRCache);
if (pRCache)
{
// Keep the record in memory until we finish rendering this page
RCA_INCR_USE_COUNT( pRCache->uiFlags);
if (++pRCache->pFile->uiUseCount == 1)
{
flmUnlinkFileFromNUList( pRCache->pFile);
}
bpFileInc = TRUE;
pRecord = pRCache->pRecord;
}
f_mutexUnlock( gv_FlmSysData.RCacheMgr.hMutex);
f_mutexUnlock( gv_FlmSysData.hShareMutex);
printTableStart( "DB Record", 1, 100);
printTableRowStart();
printColumnHeading( "", JUSTIFY_LEFT, FLM_IMON_COLOR_PUTTY_1, 1, 1, FALSE);
fnPrintf( m_pHRequest, "Refresh, ", szTemp);
fnPrintf( m_pHRequest, "%s\n", pszTemp);
printColumnHeadingClose();
printTableRowEnd();
printTableEnd();
write_links( pRCache);
write_data( pRecord, pRCache);
fnPrintf( m_pHRequest, "\n");
fnEmit();
Exit:
if (pRCache)
{
f_mutexLock( gv_FlmSysData.hShareMutex);
f_mutexLock( gv_FlmSysData.RCacheMgr.hMutex);
// Decrement the use count on the record
if (bpFileInc)
{
if (--pRCache->pFile->uiUseCount == 0)
{
flmLinkFileToNUList( pRCache->pFile);
}
}
RCA_DECR_USE_COUNT( pRCache->uiFlags);
f_mutexUnlock( gv_FlmSysData.RCacheMgr.hMutex);
f_mutexUnlock( gv_FlmSysData.hShareMutex);
}
if (pszTemp)
{
f_free( &pszTemp);
}
return( rc);
}
/****************************************************************************
Desc: This is a procedure for generating HTML content to display links to
next and previous records from the Record page, rather than having to
backup to the RCache page first.
****************************************************************************/
void F_RecordPage::write_links(
RCACHE * pRCache)
{
FLMUINT uiContainer;
FLMUINT uiDrn;
FLMUINT uiVersion;
void * pFile;
RCACHE * pTmpRCache;
char szAddress[20];
// Do nothing if there is no RCache to report on.
if (!pRCache)
{
return;
}
// Begin the table
printTableStart( "DB Record - Links", 8, 100);
printTableRowStart();
// pNextInBucket
if (pRCache->pNextInBucket)
{
pTmpRCache = pRCache->pNextInBucket;
// Extract the container etc.
uiContainer = pTmpRCache->uiContainer;
uiDrn = pTmpRCache->uiDrn;
pFile = (void *)pTmpRCache->pFile;
uiVersion = pTmpRCache->uiLowTransId;
printAddress( pFile, szAddress);
fnPrintf( m_pHRequest,
""
""
"pNextInBucket | \n",
m_pszURLString,
(unsigned long)uiContainer,
(unsigned long)uiDrn,
szAddress,
(unsigned long)uiVersion);
}
else
{
fnPrintf( m_pHRequest, "pNextInBucket | \n");
}
// pPrevInBucket
if (pRCache->pPrevInBucket)
{
pTmpRCache = pRCache->pPrevInBucket;
uiContainer = pTmpRCache->uiContainer;
uiDrn = pTmpRCache->uiDrn;
pFile = (void *)pTmpRCache->pFile;
uiVersion = pTmpRCache->uiLowTransId;
printAddress( pFile, szAddress);
fnPrintf( m_pHRequest,
""
""
"pPrevInBucket | \n",
m_pszURLString,
(unsigned long)uiContainer,
(unsigned long)uiDrn,
szAddress,
(unsigned long)uiVersion);
}
else
{
fnPrintf( m_pHRequest, "pPrevInBucket | \n");
}
// pNextInFile
if (pRCache->pNextInFile)
{
pTmpRCache = pRCache->pNextInFile;
uiContainer = pTmpRCache->uiContainer;
uiDrn = pTmpRCache->uiDrn;
pFile = (void *)pTmpRCache->pFile;
uiVersion = pTmpRCache->uiLowTransId;
printAddress( pFile, szAddress);
fnPrintf( m_pHRequest,
""
""
"pNextInFile | \n",
m_pszURLString,
(unsigned long)uiContainer,
(unsigned long)uiDrn,
szAddress,
(unsigned long)uiVersion);
}
else
{
fnPrintf( m_pHRequest, "pNextInFile | \n");
}
// pPrevInFile
if (pRCache->pPrevInFile)
{
pTmpRCache = pRCache->pPrevInFile;
uiContainer = pTmpRCache->uiContainer;
uiDrn = pTmpRCache->uiDrn;
pFile = (void *)pTmpRCache->pFile;
uiVersion = pTmpRCache->uiLowTransId;
printAddress( pFile, szAddress);
fnPrintf( m_pHRequest,
""
""
"pPrevInFile | \n",
m_pszURLString,
(unsigned long)uiContainer,
(unsigned long)uiDrn,
szAddress,
(unsigned long)uiVersion);
}
else
{
fnPrintf( m_pHRequest, "pPrevInFile | \n");
}
// pNextInGlobal
if (pRCache->pNextInGlobal)
{
pTmpRCache = pRCache->pNextInGlobal;
uiContainer = pTmpRCache->uiContainer;
uiDrn = pTmpRCache->uiDrn;
pFile = (void *)pTmpRCache->pFile;
uiVersion = pTmpRCache->uiLowTransId;
printAddress( pFile, szAddress);
fnPrintf( m_pHRequest,
""
""
"pNextInGlobal | \n",
m_pszURLString,
(unsigned long)uiContainer,
(unsigned long)uiDrn,
szAddress,
(unsigned long)uiVersion);
}
else
{
fnPrintf( m_pHRequest, "pNextInGlobal | \n");
}
// pPrevInGlobal
if (pRCache->pPrevInGlobal)
{
pTmpRCache = pRCache->pPrevInGlobal;
uiContainer = pTmpRCache->uiContainer;
uiDrn = pTmpRCache->uiDrn;
pFile = (void *)pTmpRCache->pFile;
uiVersion = pTmpRCache->uiLowTransId;
printAddress( pFile, szAddress);
fnPrintf( m_pHRequest,
""
""
"pPrevInGlobal | \n",
m_pszURLString,
(unsigned long)uiContainer,
(unsigned long)uiDrn,
szAddress,
(unsigned long)uiVersion);
}
else
{
fnPrintf( m_pHRequest, "pPrevInGlobal | \n");
}
// pOlderVersion
if (pRCache->pOlderVersion)
{
pTmpRCache = pRCache->pOlderVersion;
uiContainer = pTmpRCache->uiContainer;
uiDrn = pTmpRCache->uiDrn;
pFile = (void *)pTmpRCache->pFile;
uiVersion = pTmpRCache->uiLowTransId;
printAddress( pFile, szAddress);
fnPrintf( m_pHRequest,
""
""
"pOlderVersion | \n",
m_pszURLString,
(unsigned long)uiContainer,
(unsigned long)uiDrn,
szAddress,
(unsigned long)uiVersion);
}
else
{
fnPrintf( m_pHRequest, "pOlderVersion | \n");
}
// pNewerVersion
if (pRCache->pNewerVersion)
{
pTmpRCache = pRCache->pNewerVersion;
uiContainer = pTmpRCache->uiContainer;
uiDrn = pTmpRCache->uiDrn;
pFile = (void *)pTmpRCache->pFile;
uiVersion = pTmpRCache->uiLowTransId;
printAddress( pFile, szAddress);
fnPrintf( m_pHRequest,
""
""
"pNewerVersion | \n",
m_pszURLString,
(unsigned long)uiContainer,
(unsigned long)uiDrn,
szAddress,
(unsigned long)uiVersion);
}
else
{
fnPrintf( m_pHRequest, "pNewerVersion | \n");
}
printTableRowEnd();
printTableEnd();
}
/****************************************************************************
Desc: This is a procedure for generating HTML content to display the results
of querying the various methods in a FlmRecord
****************************************************************************/
void F_RecordPage::write_data(
FlmRecord * pRecord,
RCACHE * pRCache)
{
FLMBOOL bHighlight = FALSE;
// Do we have a valid reference to an record?
if (!pRecord)
{
// Return an error page
fnPrintf( m_pHRequest,
" Unable to find the Record that you requested."
" This is probably because the state of the cache changed "
"between the time that you displayed the previous page and the time "
"that you clicked on the link that brought you here.\n"
"
Click on your browser's \"Back\" button, then click \"Reload\" "
"and then try the link again.\n");
}
else
{
// Begin the table
printTableStart( "DB Record - Methods", 2, 100);
// Write out the table headings
printTableRowStart();
printColumnHeading( "Method Name");
printColumnHeading( "Value");
printTableRowEnd();
// getID()
printTableRowStart( bHighlight = ~bHighlight);
fnPrintf( m_pHRequest, TD_s, "getID");
fnPrintf( m_pHRequest, TD_ui, pRecord->getID());
printTableRowEnd();
// getContainerID()
printTableRowStart( bHighlight = ~bHighlight);
fnPrintf( m_pHRequest, TD_s, "getContainerID");
fnPrintf( m_pHRequest, TD_ui, pRecord->getContainerID());
printTableRowEnd();
// isReadOnly()
printTableRowStart( bHighlight = ~bHighlight);
fnPrintf( m_pHRequest, TD_s, "isReadOnly");
fnPrintf( m_pHRequest, TD_s, pRecord->isReadOnly() ? "Yes" : "No");
printTableRowEnd();
// getTotalMemory()
printTableRowStart( bHighlight = ~bHighlight);
fnPrintf( m_pHRequest, TD_s, "getTotalMemory");
fnPrintf( m_pHRequest, TD_ui, pRecord->getTotalMemory());
printTableRowEnd();
// getFreeMemory()
printTableRowStart( bHighlight = ~bHighlight);
fnPrintf( m_pHRequest, TD_s, "getFreeMemory");
fnPrintf( m_pHRequest, TD_ui, pRecord->getFreeMemory());
printTableRowEnd();
// getRefCount()
printTableRowStart( bHighlight = ~bHighlight);
fnPrintf( m_pHRequest, TD_s, "getRefCount");
fnPrintf( m_pHRequest, TD_ui, pRecord->getRefCount());
printTableRowEnd();
// End the table
printTableEnd();
// Begin a new table to display the fields
printTableStart( "DB Record - Fields", 4);
// Write out the new table headings
printTableRowStart();
printColumnHeading( "Byte Offset (hex)");
printColumnHeading( "Field Name");
printColumnHeading( "Field Type");
printColumnHeading( "Value");
printTableRowEnd();
// End the table
printTableEnd();
// At this point, we will extract the various fields and display each
// one according to the structure of the record.
printRecordFields( pRecord, pRCache);
}
}
/****************************************************************************
Desc: This is a procedure for generating HTML content to display
the fields of a FlmRecord.
****************************************************************************/
void F_RecordPage::printRecordFields(
FlmRecord * pRecord,
RCACHE * pRCache)
{
RCODE rc = FERR_OK;
F_NameTable * pNameTable = NULL;
FLMUINT uiContext = 0;
// Return if we have nothing to display.
if( !pRecord)
{
goto Exit;
}
if (!m_pFlmSession)
{
fnPrintf( m_pHRequest,
"
Cannot display record data. No session object available. "
"Return Code = 0x%04X (%s)\n", m_uiSessionRC, FlmErrorString( m_uiSessionRC));
goto Exit;
}
if (RC_BAD( rc = m_pFlmSession->getNameTable( pRCache->pFile, &pNameTable)))
{
fnPrintf( m_pHRequest,
"Cannot display record data. Could not get a Name Table."
"Return Code = 0x%04X (%s)\n", m_uiSessionRC, FlmErrorString( m_uiSessionRC));
goto Exit;
}
// We will call this when the code is ready...
printRecord( NULL, pRecord, pNameTable, &uiContext, TRUE);
Exit:
return;
}
/****************************************************************************
Desc: Prints the web page for the RCHashBucket
****************************************************************************/
RCODE F_RCHashBucketPage::display(
FLMUINT uiNumParams,
const char ** ppszParams)
{
RCODE rc = FERR_OK;
FLMBOOL bRefresh;
FLMBOOL bHighlight = TRUE;
FLMUINT uiLoop;
FLMUINT uiHashTableSize;
FLMUINT uiUsedEntries = 0;
char szStart[10];
char szRefresh[] = "&Refresh";
FLMUINT uiStart;
FLMUINT uiNewStart;
FLMBYTE * pszTemp;
FLMBOOL bNextUsed;
FLMUINT uiNextStart;
// We display 20 hash table entries at a time, some of which might need
// to be hyperlinked.
#define NUM_ENTRIES 20
FLMBYTE * pszHTLinks[NUM_ENTRIES];
// Check for the refresh parameter
bRefresh = DetectParameter( uiNumParams, ppszParams, "Refresh");
if (!bRefresh)
{
szRefresh[0]='\0'; // Effectively turns szRefresh into a null string
}
// Get the starting entry number...
if (RC_BAD( rc = ExtractParameter( uiNumParams, ppszParams,
"Start", sizeof( szStart),
szStart)))
{
flmAssert( 0);
goto Exit;
}
uiStart = f_atoud( szStart);
// Allocate space for the hyperlink text
for (uiLoop = 0; uiLoop < NUM_ENTRIES; uiLoop++)
{
if( RC_BAD( rc = f_alloc( 250, &pszHTLinks[ uiLoop])))
{
printErrorPage( rc, TRUE, (char *)"Failed to allocate temporary buffer");
goto Exit;
}
pszHTLinks[uiLoop][0] = '\0';
}
if( RC_BAD( rc = f_alloc( 250, &pszTemp)))
{
printErrorPage( rc, TRUE, (char *)"Failed to allocate temporary buffer");
goto Exit;
}
// Find out if we want to go to the next or previous used entry.
bNextUsed = DetectParameter( uiNumParams, ppszParams, "NextUsed");
// Lock the database
f_mutexLock( gv_FlmSysData.hShareMutex);
f_mutexLock( gv_FlmSysData.RCacheMgr.hMutex);
// Get the number of entries in the hash table
uiHashTableSize = gv_FlmSysData.RCacheMgr.uiNumBuckets;
// May need to modify starting number if it's out of range...
if ((uiStart + NUM_ENTRIES) >= uiHashTableSize)
{
uiStart = uiHashTableSize - NUM_ENTRIES;
}
if (bNextUsed)
{
uiNextStart = uiStart + NUM_ENTRIES;
if ((uiNextStart + NUM_ENTRIES) >= uiHashTableSize)
{
uiNextStart = uiHashTableSize - NUM_ENTRIES;
}
}
// We need to find out if there are any used entries after our uiNextStart
// index into the hash table. To do this, we will need to scan the table
// first, just to find out if there are any used entries...
if (bNextUsed)
{
for (uiLoop = 0; uiLoop < uiHashTableSize; uiLoop++)
{
if (gv_FlmSysData.RCacheMgr.ppHashBuckets[ uiLoop])
{
if ( uiLoop >= uiNextStart)
{
uiStart = uiLoop - (uiLoop % NUM_ENTRIES);
break; // No need to go further
}
}
}
}
// Loop through the entire table counting the number of entries in use
// If the entry is one of the one's we're going to display, store the
// appropriate text in pszHTLinks
for (uiLoop = 0; uiLoop < uiHashTableSize; uiLoop++)
{
if (gv_FlmSysData.RCacheMgr.ppHashBuckets[ uiLoop])
{
uiUsedEntries++;
}
if ( (uiLoop >= uiStart) &&
(uiLoop < (uiStart + NUM_ENTRIES)) )
{
// This is one of the entries that we will display
if (gv_FlmSysData.RCacheMgr.ppHashBuckets[ uiLoop])
{
flmBuildRCacheLink( (char *)pszHTLinks[uiLoop - uiStart],
gv_FlmSysData.RCacheMgr.ppHashBuckets[ uiLoop], m_pszURLString);
}
}
}
// Unlock the database
f_mutexUnlock( gv_FlmSysData.RCacheMgr.hMutex);
f_mutexUnlock( gv_FlmSysData.hShareMutex);
// Begin rendering the page...
stdHdr();
printStyle();
fnPrintf( m_pHRequest, HTML_DOCTYPE "\n");
// Determine if we are being requested to refresh this page or not.
if (bRefresh)
{
fnPrintf( m_pHRequest,
""
""
"Database iMonitor - RCache Hash Bucket\n", m_pszURLString, uiStart, szRefresh);
}
else
{
fnPrintf( m_pHRequest, "\n");
}
// If we are not to refresh this page, then don't include the
// refresh meta command
if (!bRefresh)
{
f_sprintf( (char *)pszTemp,
"Start Auto-refresh (5 sec.)",
m_pszURLString, uiStart);
}
else
{
f_sprintf( (char *)pszTemp,
"Stop Auto-refresh",
m_pszURLString, uiStart);
}
// Print out a formal header and the refresh option.
printTableStart("RCache Hash Bucket", 4);
printTableRowStart();
printColumnHeading( "", JUSTIFY_LEFT, FLM_IMON_COLOR_PUTTY_1, 4, 1, FALSE);
fnPrintf( m_pHRequest,
"Refresh, %s\n",
m_pszURLString, uiStart, szRefresh, pszTemp);
printColumnHeadingClose();
printTableRowEnd();
printTableRowStart( (bHighlight = !bHighlight));
fnPrintf( m_pHRequest, "Table Size: %lu | \n", uiHashTableSize);
printTableRowEnd();
printTableRowStart( (bHighlight = !bHighlight));
fnPrintf( m_pHRequest, "Entries Used: %lu (%lu%%) | \n", uiUsedEntries,
((uiUsedEntries * 100) / uiHashTableSize) );
printTableRowEnd();
// The rest of the table is going to be a single row with two columns:
// one for the list of hash buckets and the other for everything else
printTableRowStart( FALSE);
fnPrintf( m_pHRequest, " \n");
// Print out the hash buckets
for (uiLoop = 0; uiLoop < NUM_ENTRIES; uiLoop++)
{
if (pszHTLinks[uiLoop][0] != '\0')
{
fnPrintf( m_pHRequest, "%lu \n",
pszHTLinks[uiLoop], szRefresh, uiStart+uiLoop);
}
else
{
fnPrintf( m_pHRequest, "%lu \n", uiStart+uiLoop);
}
}
fnPrintf( m_pHRequest, "\n | \n\n");
// Print out the other stuff...
uiNewStart = (uiStart > 1000)?(uiStart - 1000):0;
fnPrintf( m_pHRequest, "Previous 1000 \n",
m_pszURLString, uiNewStart, szRefresh);
uiNewStart = (uiStart > 100)?(uiStart - 100):0;
fnPrintf( m_pHRequest, "Previous 100 \n",
m_pszURLString, uiNewStart, szRefresh);
uiNewStart = (uiStart > 10)?(uiStart - 10):0;
fnPrintf( m_pHRequest, "Previous 10 \n",
m_pszURLString, uiNewStart, szRefresh);
fnPrintf( m_pHRequest, " \n");
uiNewStart = (uiStart + 10);
if (uiNewStart >= (uiHashTableSize - NUM_ENTRIES))
{
uiNewStart = (uiHashTableSize - NUM_ENTRIES);
}
fnPrintf( m_pHRequest, "Next 10 \n",
m_pszURLString, uiNewStart, szRefresh);
uiNewStart = (uiStart + 100);
if (uiNewStart >= (uiHashTableSize - NUM_ENTRIES))
{
uiNewStart = (uiHashTableSize - NUM_ENTRIES);
}
fnPrintf( m_pHRequest, "Next 100 \n",
m_pszURLString, uiNewStart, szRefresh);
uiNewStart = (uiStart + 1000);
if (uiNewStart >= (uiHashTableSize - NUM_ENTRIES))
{
uiNewStart = (uiHashTableSize - NUM_ENTRIES);
}
fnPrintf( m_pHRequest, "Next 1000 \n"
"Next Used Bucket \n"
"\n | \n");
printTableRowEnd();
printTableEnd();
printDocEnd();
fnEmit();
Exit:
// Free the space for the hyperlink text
for (uiLoop = 0; uiLoop < NUM_ENTRIES; uiLoop++)
{
f_free( &pszHTLinks[uiLoop]);
}
f_free( &pszTemp);
return( rc);
}
/****************************************************************************
Desc: Determines the values of the parameters needed to reference
a specific RCache structure. Must be called from within a mutex
****************************************************************************/
FSTATIC void flmBuildRCacheLink(
char * pszString,
RCACHE * pRCache,
char * pszURLString)
{
char szAddress[20];
if (pRCache == NULL)
{
pszString[0] = 0;
}
else
{
printAddress( pRCache->pFile, szAddress);
f_sprintf((char *)pszString,
"%s/RCache?Container=%lu&DRN=%lu&File=%s&Version=%lu",
pszURLString,
(unsigned long)pRCache->uiContainer,
(unsigned long)pRCache->uiDrn,
szAddress,
(unsigned long)pRCache->uiLowTransId);
}
return;
}