2003-11-10 15:54 UTC+0100 Maurilio Longo <maurilio.longo@libero.it>
borrowed from xHarbour trying to hunt down a memory leak on an utility of mine 2003-11-10 12:19 UTC+0100 Przemyslaw Czerpak <druzus@polbox.com> * xharbour/include/hbrddcdx.h * xharbour/source/rdd/dbfcdx/dbfcdx1.c ! possible memory leak fixed * small improvment in balancing
This commit is contained in:
@@ -9,6 +9,15 @@
|
||||
*/
|
||||
|
||||
|
||||
2003-11-10 15:54 UTC+0100 Maurilio Longo <maurilio.longo@libero.it>
|
||||
borrowed from xHarbour trying to hunt down a memory leak on an utility of mine
|
||||
|
||||
2003-11-10 12:19 UTC+0100 Przemyslaw Czerpak <druzus@polbox.com>
|
||||
* xharbour/include/hbrddcdx.h
|
||||
* xharbour/source/rdd/dbfcdx/dbfcdx1.c
|
||||
! possible memory leak fixed
|
||||
* small improvment in balancing
|
||||
|
||||
|
||||
2003-11-10 13:20 UTC+0100 Maurilio Longo <maurilio.longo@libero.it>
|
||||
* harbour/contrib/btree/hb_btree.c
|
||||
|
||||
@@ -113,13 +113,13 @@ extern "C" {
|
||||
#define CURKEY_ISSET(pTag) (((pTag)->curKeyState & (CDX_CURKEY_NOTEXIST | CDX_CURKEY_UNDEF)) == 0)
|
||||
#define CURKEY_REC(pTag) ((((pTag)->curKeyState & CDX_CURKEY_REC) != 0) ? (pTag)->curKey->rec : 0)
|
||||
#define CURKEY_VAL(pTag) ((((pTag)->curKeyState & CDX_CURKEY_VAL) != 0) ? (pTag)->curKey->val : NULL)
|
||||
#define CURKEY_REFRESH(pTag)
|
||||
#define CURKEY_REFRESH(pTag)
|
||||
*/
|
||||
|
||||
#define HB_CDXMAXKEY( x ) ((USHORT) ((x) > CDX_MAXKEY ? CDX_MAXKEY : (x)))
|
||||
#define HB_CDXBITMASK( x ) ((LONG) ((1L<<(x))-1))
|
||||
|
||||
//#define FAST_GOCOLD( A ) (((CDXAREAP) (A))->fRecordChanged || ((CDXAREAP) (A))->fCdxAppend ? (SELF_GOCOLD((A))) : SUCCESS)
|
||||
/* #define FAST_GOCOLD( A ) (((CDXAREAP) (A))->fRecordChanged || ((CDXAREAP) (A))->fCdxAppend ? (SELF_GOCOLD((A))) : SUCCESS) */
|
||||
#define FAST_GOCOLD( A ) SELF_GOCOLD(A)
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ typedef struct _CDXTAGHEADER
|
||||
BYTE forExpPos[ 2 ]; /* offset of filter expression */
|
||||
BYTE forExpLen[ 2 ]; /* length of filter expression */
|
||||
BYTE keyExpPos[ 2 ]; /* offset of key expression */
|
||||
BYTE keyExpLen[ 2 ]; /* length of key expression */
|
||||
BYTE keyExpLen[ 2 ]; /* length of key expression */
|
||||
BYTE keyExpPool[ CDX_PAGELEN ];
|
||||
} CDXTAGHEADER;
|
||||
typedef CDXTAGHEADER * LPCDXTAGHEADER;
|
||||
@@ -412,6 +412,7 @@ typedef struct _CDXAREA
|
||||
BOOL fCdxAppend; /* Appended record changed */
|
||||
LPCDXINDEX lpIndexes; /* Pointer to indexes array */
|
||||
USHORT uiTag; /* current tag focus */
|
||||
BYTE * bCdxSortTab; /* Table with storted characters */
|
||||
|
||||
} CDXAREA;
|
||||
|
||||
|
||||
@@ -389,6 +389,45 @@ static ERRCODE hb_cdxErrorRT( CDXAREAP pArea, USHORT uiGenCode, USHORT uiSubCode
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/*
|
||||
* create index sort table
|
||||
*/
|
||||
static void hb_cdxMakeSortTab( CDXAREAP pArea )
|
||||
{
|
||||
#ifndef HB_CDP_SUPPORT_OFF
|
||||
if ( pArea->cdPage && pArea->cdPage->lSort && !pArea->bCdxSortTab )
|
||||
{
|
||||
int i, j, l;
|
||||
BYTE * pbSort, b;
|
||||
|
||||
pArea->bCdxSortTab = ( BYTE * ) hb_xgrab( 256 );
|
||||
pbSort = ( BYTE * ) hb_xgrab( 256 );
|
||||
/* this table should be allready quite good sorted so this simple
|
||||
algorithms will be one of the most efficient one. */
|
||||
for ( i = 0; i <= 255; i++ )
|
||||
pbSort[i] = ( BYTE ) i;
|
||||
l = 255;
|
||||
do
|
||||
{
|
||||
j = l;
|
||||
for( i = 0; i < j; i++ )
|
||||
{
|
||||
if ( hb_cdpchrcmp( pbSort[i], pbSort[i+1], pArea->cdPage ) > 0 )
|
||||
{
|
||||
b = pbSort[i+1];
|
||||
pbSort[i+1] = pbSort[i];
|
||||
pbSort[i] = b;
|
||||
l = i;
|
||||
}
|
||||
}
|
||||
} while ( j != l );
|
||||
for ( i = 0; i <= 255; i++ )
|
||||
pArea->bCdxSortTab[pbSort[i]] = i;
|
||||
hb_xfree( pbSort );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* create new index key
|
||||
*/
|
||||
@@ -516,19 +555,21 @@ static int hb_cdxValCompare( LPCDXTAG pTag, BYTE * val1, BYTE len1,
|
||||
if ( pTag->uiType == 'C' )
|
||||
{
|
||||
#ifndef HB_CDP_SUPPORT_OFF
|
||||
PHB_CODEPAGE cdpage = pTag->pIndex->pArea->cdPage;
|
||||
int iPos = 0;
|
||||
|
||||
while ( iResult == 0 && iPos < iLimit )
|
||||
if ( pTag->pIndex->pArea->bCdxSortTab )
|
||||
{
|
||||
/* for nation sorting support */
|
||||
iResult = hb_cdpcharcmp( val1[ iPos ], val2[ iPos ], cdpage );
|
||||
iPos++; /* EndPos += 1; */
|
||||
BYTE * pSort = pTag->pIndex->pArea->bCdxSortTab;
|
||||
int iPos = 0;
|
||||
while ( iResult == 0 && iPos < iLimit )
|
||||
{
|
||||
iResult = pSort[ val1[ iPos ] ] - pSort[ val2[ iPos ] ];
|
||||
iPos++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
else
|
||||
#endif
|
||||
if ( iLimit > 0 )
|
||||
iResult = memcmp( val1, val2, iLimit );
|
||||
#endif
|
||||
|
||||
if ( iResult == 0 )
|
||||
{
|
||||
if ( len1 > len2 )
|
||||
@@ -2206,7 +2247,10 @@ static int hb_cdxPageKeyLeafBalance( LPCDXPAGE pPage, SHORT iChildRet )
|
||||
if ( pPage->iCurKey > 0 )
|
||||
iFirstKey = pPage->iCurKey - 1;
|
||||
else
|
||||
{
|
||||
iFirstKey = 0;
|
||||
--iBlncKeys;
|
||||
}
|
||||
if ( iBlncKeys > pPage->iKeys - iFirstKey )
|
||||
{
|
||||
iBlncKeys = pPage->iKeys - iFirstKey;
|
||||
@@ -2251,11 +2295,13 @@ static int hb_cdxPageKeyLeafBalance( LPCDXPAGE pPage, SHORT iChildRet )
|
||||
{
|
||||
if ( i == iSkip )
|
||||
++iSkip;
|
||||
#if 0
|
||||
else if ( i + 1 == iBlncKeys )
|
||||
{
|
||||
iBlncKeys--;
|
||||
hb_cdxPageFree( childs[i], FALSE );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if ( i >= iSkip && i < iBlncKeys )
|
||||
iKeys += childs[i]->iKeys;
|
||||
@@ -2266,7 +2312,15 @@ static int hb_cdxPageKeyLeafBalance( LPCDXPAGE pPage, SHORT iChildRet )
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( ( iChildRet & NODE_SPLIT ) == 0 )
|
||||
{
|
||||
for ( i = iBlncKeys - 1; i > iSkip && childs[i]->iFree >= 0 && childs[i]->iFree < childs[i]->ReqByte; i-- )
|
||||
{
|
||||
iKeys -= childs[i]->iKeys;
|
||||
hb_cdxPageFree( childs[i], FALSE );
|
||||
iBlncKeys--;
|
||||
}
|
||||
}
|
||||
if ( ( iChildRet & ( NODE_SPLIT | NODE_JOIN ) ) == 0 &&
|
||||
( iBlncKeys < 2 || iFree < CDX_EXT_FREESPACE ) )
|
||||
{
|
||||
@@ -2274,7 +2328,6 @@ static int hb_cdxPageKeyLeafBalance( LPCDXPAGE pPage, SHORT iChildRet )
|
||||
hb_cdxPageFree( childs[i], FALSE );
|
||||
return iRet;
|
||||
}
|
||||
|
||||
#ifdef HB_CDX_DSPDBG_INFO
|
||||
printf("\r\nleaf balance: Page=%lx iKeys=%d", pPage->Page, iKeys);
|
||||
fflush(stdout);
|
||||
@@ -2339,11 +2392,43 @@ static int hb_cdxPageKeyLeafBalance( LPCDXPAGE pPage, SHORT iChildRet )
|
||||
|
||||
if ( !fIns && lpTmpPage != NULL )
|
||||
{
|
||||
#if 1
|
||||
SHORT j, iSize = 0;
|
||||
ULONG ulMaxRec = 0, ul;
|
||||
BYTE * pbKey, bMax;
|
||||
|
||||
for ( j = 0; j < iKeys; j++ )
|
||||
{
|
||||
if ( ulMaxRec < ( ul = HB_GET_LE_ULONG( &pPtr[ ( j + 1 ) * iLen - 6 ] ) ) )
|
||||
ulMaxRec = ul;
|
||||
iSize += iLen - 6 - ( j == 0 ? 0 : pPtr[ ( j + 1 ) * iLen - 2 ] ) - pPtr[ ( j + 1 ) * iLen - 1 ];
|
||||
}
|
||||
pbKey = hb_cdxPageGetKeyVal( lpTmpPage, 0 );
|
||||
bMax = ( lpTmpPage->node.extNode.keyPool[ lpTmpPage->ReqByte - 2 ]
|
||||
>> ( 16 - lpTmpPage->TCBits ) ) & lpTmpPage->TCMask;
|
||||
bMax = iLen - 6 - HB_MAX( pPtr[ iKeys * iLen - 1 ], bMax );
|
||||
for ( j = 0; j < bMax &&
|
||||
pPtr[ ( iKeys - 1 ) * iLen + j ] == pbKey[ j ]; j++ );
|
||||
iSize -= j;
|
||||
iMaxReq = lpTmpPage->ReqByte;
|
||||
ul = lpTmpPage->RNMask;
|
||||
while ( ulMaxRec > ul )
|
||||
{
|
||||
++iMaxReq;
|
||||
ul = ( ul << 8 ) | 0xFF;
|
||||
}
|
||||
iSize += iKeys * iMaxReq;
|
||||
iSize = lpTmpPage->iFree - iSize -
|
||||
( iMaxReq - lpTmpPage->ReqByte ) * lpTmpPage->iKeys;
|
||||
if ( iSize < 0 )
|
||||
fIns = TRUE;
|
||||
#else
|
||||
if ( lpTmpPage->ReqByte > iMaxReq )
|
||||
iMaxReq = lpTmpPage->ReqByte;
|
||||
if ( lpTmpPage->iFree < iKeys * ( iLen - 6 + iMaxReq ) +
|
||||
( iMaxReq - lpTmpPage->ReqByte ) * lpTmpPage->iKeys )
|
||||
fIns = TRUE;
|
||||
#endif
|
||||
else
|
||||
{
|
||||
BYTE * pTmp = (BYTE *) hb_xgrab( ( iKeys + lpTmpPage->iKeys ) * iLen );
|
||||
@@ -2373,6 +2458,26 @@ static int hb_cdxPageKeyLeafBalance( LPCDXPAGE pPage, SHORT iChildRet )
|
||||
childs[i] = lpTmpPage;
|
||||
if ( iFirstKey + i >= pPage->iKeys )
|
||||
iRet |= NODE_NEWLASTKEY;
|
||||
#if 1
|
||||
#ifndef HB_CDX_DBGCODE_OFF
|
||||
childs[i]->iKeys = 0;
|
||||
if ( childs[i]->pKeyBuf )
|
||||
{
|
||||
hb_xfree( childs[i]->pKeyBuf );
|
||||
childs[i]->pKeyBuf = NULL;
|
||||
childs[i]->fBufChanged = FALSE;
|
||||
}
|
||||
hb_cdxPageCalcLeafSpace( childs[i], pPtr, iKeys );
|
||||
hb_cdxPageLeafEncode( childs[i], pPtr, childs[i]->iKeys );
|
||||
if ( iSize != childs[i]->iFree )
|
||||
{
|
||||
printf("\r\nninserting, iSize=%d, childs[i]->iFree=%d", iSize, childs[i]->iFree); fflush(stdout);
|
||||
printf("\r\niKeys=%d, iMaxReq=%d", iKeys, iMaxReq); fflush(stdout);
|
||||
hb_cdxErrInternal( "hb_cdxPageGetChild: index corrupted." );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2504,11 +2609,15 @@ static int hb_cdxPageKeyIntBalance( LPCDXPAGE pPage, SHORT iChildRet )
|
||||
LPCDXPAGE childs[ CDX_BALANCE_INTPAGES + 2 ], lpTmpPage;
|
||||
SHORT iFirstKey, iBlncKeys = CDX_BALANCE_INTPAGES;
|
||||
SHORT iLen = pPage->TagParent->uiLen + 8, iKeys = 0, iNeedKeys, iNodeKeys,
|
||||
iMin = pPage->TagParent->MaxKeys, iMax = 0;
|
||||
iMin = pPage->TagParent->MaxKeys, iMax = 0, iDiv;
|
||||
ULONG ulPage;
|
||||
BYTE * pKeyPool = NULL, *pPtr;
|
||||
BOOL fForce = ( iChildRet & ( NODE_SPLIT | NODE_JOIN ) ) != 0;
|
||||
int iRet = 0, i;
|
||||
|
||||
if ( !fForce && ( iChildRet & NODE_BALANCE ) == 0 )
|
||||
return iRet;
|
||||
|
||||
if ( pPage->Child && pPage->Child->Child )
|
||||
hb_cdxPageFree( pPage->Child->Child, FALSE );
|
||||
|
||||
@@ -2518,10 +2627,10 @@ static int hb_cdxPageKeyIntBalance( LPCDXPAGE pPage, SHORT iChildRet )
|
||||
|
||||
if ( pPage->iKeys <= iBlncKeys || pPage->iCurKey <= iBlncKeys / 2 )
|
||||
iFirstKey = 0;
|
||||
else if ( pPage->iCurKey + iBlncKeys / 2 >= pPage->iKeys )
|
||||
else if ( pPage->iCurKey + ( iBlncKeys >> 1 ) >= pPage->iKeys )
|
||||
iFirstKey = pPage->iKeys - iBlncKeys;
|
||||
else
|
||||
iFirstKey = pPage->iCurKey - iBlncKeys / 2;
|
||||
iFirstKey = pPage->iCurKey - ( iBlncKeys >> 1 );
|
||||
if ( iBlncKeys > pPage->iKeys - iFirstKey )
|
||||
{
|
||||
iBlncKeys = pPage->iKeys - iFirstKey;
|
||||
@@ -2533,8 +2642,7 @@ static int hb_cdxPageKeyIntBalance( LPCDXPAGE pPage, SHORT iChildRet )
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
if ( ( iChildRet & ( NODE_SPLIT | NODE_JOIN ) ) == 0 &&
|
||||
( iBlncKeys < 2 || ( iChildRet & NODE_BALANCE ) == 0 ) )
|
||||
if ( !fForce && iBlncKeys < 2 )
|
||||
return iRet;
|
||||
|
||||
for ( i = 0; i < iBlncKeys; i++ )
|
||||
@@ -2571,15 +2679,45 @@ static int hb_cdxPageKeyIntBalance( LPCDXPAGE pPage, SHORT iChildRet )
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( ( iChildRet & ( NODE_SPLIT | NODE_JOIN ) ) == 0 &&
|
||||
( iBlncKeys < 2 || iMax - iMin < 2 ) )
|
||||
iDiv = iMax - iMin;
|
||||
if ( iDiv >= 2 || fForce )
|
||||
{
|
||||
iNeedKeys = ( iKeys + pPage->TagParent->MaxKeys - 1 )
|
||||
/ pPage->TagParent->MaxKeys;
|
||||
iMin = iKeys / iNeedKeys;
|
||||
iMax = ( iKeys + iNeedKeys - 1 ) / iNeedKeys;
|
||||
if ( iMin < 1 )
|
||||
iMin = 1;
|
||||
if ( iMax > pPage->TagParent->MaxKeys )
|
||||
iMax = pPage->TagParent->MaxKeys;
|
||||
for ( i = iBlncKeys - 1; i >= 0 &&
|
||||
childs[i]->iKeys >= iMin && childs[i]->iKeys <= iMax; i-- )
|
||||
{
|
||||
iKeys -= childs[i]->iKeys;
|
||||
hb_cdxPageFree( childs[i], FALSE );
|
||||
iBlncKeys--;
|
||||
}
|
||||
while ( iBlncKeys > 0 && childs[0]->iKeys >= iMin && childs[0]->iKeys <= iMax )
|
||||
{
|
||||
iKeys -= childs[0]->iKeys;
|
||||
hb_cdxPageFree( childs[0], FALSE );
|
||||
iBlncKeys--;
|
||||
iFirstKey++;
|
||||
for ( i = 0; i < iBlncKeys; i++ )
|
||||
{
|
||||
childs[i] = childs[i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !fForce && ( iBlncKeys < 2 || iDiv < 2 ) )
|
||||
{
|
||||
for ( i = 0; i < iBlncKeys; i++ )
|
||||
hb_cdxPageFree( childs[i], FALSE );
|
||||
return iRet;
|
||||
}
|
||||
|
||||
iNeedKeys = ( iKeys + pPage->TagParent->MaxKeys - 1 )
|
||||
/ pPage->TagParent->MaxKeys;
|
||||
if ( iKeys > 0 )
|
||||
{
|
||||
pPtr = pKeyPool = (BYTE*) hb_xgrab( iKeys * iLen );
|
||||
@@ -2593,9 +2731,6 @@ static int hb_cdxPageKeyIntBalance( LPCDXPAGE pPage, SHORT iChildRet )
|
||||
}
|
||||
}
|
||||
|
||||
iNeedKeys = ( iKeys + pPage->TagParent->MaxKeys - 1 )
|
||||
/ pPage->TagParent->MaxKeys;
|
||||
|
||||
if ( iNeedKeys > iBlncKeys )
|
||||
{
|
||||
childs[iBlncKeys] = hb_cdxPageNew( pPage->TagParent, pPage, 0 );
|
||||
@@ -3637,6 +3772,8 @@ static void hb_cdxTagIndexTagNew( LPCDXTAG pTag,
|
||||
char * ForExp, PHB_ITEM pForItem,
|
||||
BOOL fAscnd, BOOL fUniq, BOOL fCustom )
|
||||
{
|
||||
if ( bType == 'C' )
|
||||
hb_cdxMakeSortTab( pTag->pIndex->pArea );
|
||||
if ( KeyExp != NULL )
|
||||
{
|
||||
pTag->KeyExpr = ( char * ) hb_xgrab( CDX_MAXKEY + 1 );
|
||||
@@ -3785,6 +3922,9 @@ static void hb_cdxIndexFree( LPCDXINDEX pIndex )
|
||||
{
|
||||
LPCDXTAG pTag;
|
||||
|
||||
/* Free List of Free Pages */
|
||||
hb_cdxIndexDropAvailPage( pIndex );
|
||||
|
||||
/* Free Compound tag */
|
||||
if ( pIndex->pCompound != NULL )
|
||||
{
|
||||
@@ -4758,7 +4898,6 @@ static ERRCODE hb_cdxGoCold( CDXAREAP pArea )
|
||||
if ( !pTag->Custom )
|
||||
{
|
||||
pKey = hb_cdxKeyEval( pKey, pTag, TRUE );
|
||||
/* test for expresion, working but not tested */
|
||||
if ( pTag->pForItem != NULL )
|
||||
fAdd = hb_cdxEvalCond ( pArea, pTag->pForItem, TRUE );
|
||||
else
|
||||
@@ -4805,13 +4944,13 @@ static ERRCODE hb_cdxGoCold( CDXAREAP pArea )
|
||||
hb_cdxTagClose( pTag );
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
#if 0
|
||||
if ( pTag->HotKey )
|
||||
{
|
||||
hb_cdxKeyFree( pTag->HotKey );
|
||||
pTag->HotKey = NULL;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
if ( pTag->pNext )
|
||||
pTag = pTag->pNext;
|
||||
@@ -4899,7 +5038,11 @@ static ERRCODE hb_cdxClose( CDXAREAP pArea )
|
||||
return FAILURE;
|
||||
|
||||
hb_cdxOrdListClear( pArea, TRUE, NULL );
|
||||
|
||||
if ( pArea->bCdxSortTab )
|
||||
{
|
||||
hb_xfree( pArea->bCdxSortTab );
|
||||
pArea->bCdxSortTab = NULL;
|
||||
}
|
||||
#ifdef HB_CDX_DBGTIME
|
||||
printf( "\r\ncdxTimeIntBld=%f, cdxTimeExtBld=%f, cdxTimeBld=%f\r\n"
|
||||
"cdxTimeGetKey=%f, cdxTimeFreeKey=%f\r\n"
|
||||
@@ -7182,7 +7325,11 @@ static void hb_cdxSortAddExternal( LPSORTINFO pSort, USHORT Lvl, LONG Tag, LONG
|
||||
cd = hb_cdxSortKeyFindDup( Value, pSort->LastKey );
|
||||
|
||||
#ifndef HB_CDX_DBGCODE_OFF
|
||||
#ifndef HB_CDP_SUPPORT_OFF
|
||||
if( hb_cdxSortKeyCompare( Value, pSort->LastKey, pSort->CurTag->pIndex->pArea->cdPage ) < 0 )
|
||||
#else
|
||||
if( hb_cdxSortKeyCompare( Value, pSort->LastKey ) < 0 )
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
printf("\r\nValue->length=%2d, Value->Value=%s", Value->length, Value->Value);
|
||||
@@ -7427,7 +7574,7 @@ static void hb_cdxTagDoIndex( LPCDXTAG pTag )
|
||||
break;
|
||||
|
||||
default:
|
||||
printf( "hb_cdxTagDoIndex( LPCDXTAG pTag ): hb_itemType( pItem ) = %i", hb_itemType( pItem ) );
|
||||
printf( "hb_cdxTagDoIndex: hb_itemType( pItem ) = %i", hb_itemType( pItem ) );
|
||||
}
|
||||
}
|
||||
if ( pEvalItem )
|
||||
|
||||
Reference in New Issue
Block a user