2000-12-09 14:09 UTC-0800 Brian Hays <bhays@abacuslaw.com>
This commit is contained in:
@@ -145,7 +145,7 @@ static ERRCODE hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level);
|
||||
static ERRCODE hb_ntxPageKeyInsert( LPPAGEINFO pPage, PHB_ITEM pKey, int pos );
|
||||
/* Insert page in position pos */
|
||||
static int hb_ntxItemCompare( PHB_ITEM pKey1, PHB_ITEM pKey2 );
|
||||
/* Comapare 2 Keys (They mus be keys !!! */
|
||||
/* Compare 2 Keys (They mus be keys !!! */
|
||||
static ERRCODE hb_ntxPageAddPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level, int pos );
|
||||
|
||||
/* Implementation of functions for debug this module */
|
||||
@@ -190,6 +190,13 @@ static void hb_ntxIndexDump( LPNTXINDEX pIndex )
|
||||
}
|
||||
#endif
|
||||
|
||||
static void backcpy( BYTE* dest, BYTE* src, long mlen )
|
||||
{
|
||||
long i;
|
||||
for( dest = dest + mlen - 1,src = src + mlen - 1, i = 0; i < mlen; i++, dest--,src-- )
|
||||
*dest = *src;
|
||||
}
|
||||
|
||||
/* Implementation of internal functions */
|
||||
|
||||
static int hb_ntxItemCompare( PHB_ITEM pKey1, PHB_ITEM pKey2 )
|
||||
@@ -233,42 +240,169 @@ static int hb_ntxItemCompare( PHB_ITEM pKey1, PHB_ITEM pKey2 )
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hb_ntxPageSave( LPPAGEINFO pPage )
|
||||
{
|
||||
char buffer[NTXBLOCKSIZE+1];
|
||||
int i;
|
||||
LPNTXBUFFER itemlist;
|
||||
LPNTXITEM item;
|
||||
LPKEYINFO pKey;
|
||||
|
||||
memset( buffer, 0, NTXBLOCKSIZE+1 );
|
||||
pKey = pPage->pKeys;
|
||||
itemlist = ( LPNTXBUFFER ) buffer;
|
||||
itemlist->item_count = pPage->uiKeys;
|
||||
for( i = 0; i < pPage->uiKeys; i++ )
|
||||
{
|
||||
itemlist->item_offset[i] = 2 + 2 * ( pPage->TagParent->MaxKeys + 1 ) +
|
||||
i * ( pPage->TagParent->KeyLength + 8 );
|
||||
item=(NTXITEM *)(buffer+itemlist->item_offset[i]);
|
||||
item->page = pKey[i].Tag;
|
||||
item->rec_no = pKey[i].Xtra;
|
||||
strcpy(item->key, pKey[i].pItem->item.asString.value);
|
||||
}
|
||||
itemlist->item_offset[i] = 2 + 2 * ( pPage->TagParent->MaxKeys + 1 ) +
|
||||
i * ( pPage->TagParent->KeyLength + 8 );
|
||||
item=(NTXITEM *)(buffer+itemlist->item_offset[i]);
|
||||
item->page = pKey[i].Tag;
|
||||
hb_fsSeek( pPage->TagParent->Owner->DiskFile, pPage->Page, FS_SET );
|
||||
hb_fsWrite( pPage->TagParent->Owner->DiskFile, (BYTE *) buffer, NTXBLOCKSIZE );
|
||||
pPage->Changed = FALSE;
|
||||
}
|
||||
|
||||
static LPPAGEINFO hb_ntxPageLoad( LPPAGEINFO pParentPage, ULONG ulOffset )
|
||||
{
|
||||
char buffer[NTXBLOCKSIZE];
|
||||
int i, uiCount;
|
||||
LPNTXBUFFER itemlist;
|
||||
LPNTXITEM item;
|
||||
LPPAGEINFO pPage;
|
||||
|
||||
/* printf( "\nntxPageLoad - 0" ); */
|
||||
hb_fsSeek( pParentPage->TagParent->Owner->DiskFile, ulOffset, FS_SET );
|
||||
uiCount = hb_fsRead( pParentPage->TagParent->Owner->DiskFile, ( BYTE * ) buffer, NTXBLOCKSIZE );
|
||||
if( uiCount != NTXBLOCKSIZE )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
pPage = ( LPPAGEINFO ) hb_xgrab( sizeof( HB_PAGEINFO ) );
|
||||
memset( pPage , 0 ,sizeof( HB_PAGEINFO ) );
|
||||
pPage->TagParent = pParentPage->TagParent;
|
||||
pPage->Owner = pParentPage;
|
||||
pPage->CurKey = -1;
|
||||
pPage->Page = ulOffset;
|
||||
pPage->pKeys = ( LPKEYINFO ) hb_xgrab( sizeof( KEYINFO ) * ( pPage->TagParent->MaxKeys + 1 ) );
|
||||
memset( pPage->pKeys, 0, sizeof( KEYINFO ) * ( pPage->TagParent->MaxKeys + 1 ) );
|
||||
|
||||
itemlist = ( LPNTXBUFFER ) buffer;
|
||||
pPage->uiKeys = itemlist->item_count ;
|
||||
for( i = 0; i < itemlist->item_count; i++ )
|
||||
{
|
||||
item=(NTXITEM *)(buffer+itemlist->item_offset[i]);
|
||||
pPage->pKeys[i].Xtra = item->rec_no;
|
||||
pPage->pKeys[i].Tag = item->page;
|
||||
pPage->pKeys[i].pItem = hb_itemNew( NULL );
|
||||
hb_itemPutCL( pPage->pKeys[i].pItem, item->key, pPage->TagParent->KeyLength );
|
||||
}
|
||||
item=(NTXITEM *)(buffer+itemlist->item_offset[i]);
|
||||
pPage->pKeys[i].Tag = item->page;
|
||||
return pPage;
|
||||
}
|
||||
|
||||
static void hb_ntxPageFree( LPPAGEINFO pPage )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( pPage->Child )
|
||||
hb_ntxPageFree( pPage->Child );
|
||||
if( pPage->Changed )
|
||||
hb_ntxPageSave( pPage );
|
||||
if( pPage->NewRoot )
|
||||
{
|
||||
pPage->TagParent->RootBlock = pPage->Page;
|
||||
hb_ntxHeaderSave( pPage->TagParent->Owner );
|
||||
}
|
||||
for( i = 0; i< pPage->uiKeys; i++)
|
||||
{
|
||||
hb_itemRelease( pPage->pKeys[i].pItem );
|
||||
}
|
||||
hb_xfree( pPage->pKeys );
|
||||
hb_xfree( pPage );
|
||||
}
|
||||
|
||||
|
||||
static LPPAGEINFO hb_ntxPageNew(LPTAGINFO pParentTag, LPPAGEINFO pParentPage)
|
||||
{
|
||||
LPPAGEINFO pPage;
|
||||
|
||||
pPage = ( LPPAGEINFO ) hb_xgrab( sizeof( HB_PAGEINFO ) );
|
||||
memset( pPage, 0, sizeof( HB_PAGEINFO ) );
|
||||
pPage->TagParent = pParentTag;
|
||||
pPage->Owner = pParentPage;
|
||||
pPage->CurKey = -1;
|
||||
pParentTag->TagBlock = pParentTag->TagBlock + 1024;
|
||||
pPage->Page = pParentTag->TagBlock;
|
||||
pPage->pKeys = ( LPKEYINFO ) hb_xgrab( sizeof( KEYINFO ) * ( pParentTag->MaxKeys + 1 ) );
|
||||
memset( pPage->pKeys, 0, sizeof( KEYINFO ) * ( pParentTag->MaxKeys + 1 ) );
|
||||
return pPage;
|
||||
}
|
||||
|
||||
static ERRCODE hb_ntxPageAddPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level, int pos )
|
||||
{
|
||||
int nBegin, nEnd;
|
||||
int nNewPos;
|
||||
int MaxKeys = pPage->TagParent->MaxKeys - 1 ;
|
||||
int MaxKeys = pPage->TagParent->MaxKeys;
|
||||
int nCount, nMaxCount = MaxKeys / 5;
|
||||
LPPAGEINFO pNewPage;
|
||||
|
||||
/*
|
||||
int i;
|
||||
for( i = 0; i < pPage->uiKeys; i++ )
|
||||
printf( "\n --- ( %d %5lx %s )", i,pPage->pKeys[i].Tag,hb_itemGetCPtr( pPage->pKeys[i].pItem ) );
|
||||
*/
|
||||
pNewPage = hb_ntxPageNew( pPage->TagParent, pPage );
|
||||
if( pNewPage == NULL )
|
||||
return FAILURE;
|
||||
nBegin = pos;
|
||||
nCount = 0;
|
||||
while( ( nCount < nMaxCount ) && ( nBegin > 0 ) && ( pPage->pKeys[ nBegin - 1 ].Tag == 0 ) )
|
||||
if( pos > pPage->TagParent->MaxKeys )
|
||||
{
|
||||
nBegin--;
|
||||
nCount++;
|
||||
memmove( pNewPage->pKeys , pPage->pKeys,
|
||||
( pPage->uiKeys ) * sizeof( KEYINFO ) + sizeof( pPage->pKeys->Tag ) );
|
||||
pNewPage->uiKeys = pPage->uiKeys;
|
||||
pPage->uiKeys = 1;
|
||||
pPage->pKeys[0].Tag = pNewPage->Page;
|
||||
pPage->pKeys[0].Xtra = pPage->TagParent->Owner->Owner->ulRecNo;
|
||||
pPage->pKeys[0].pItem = hb_itemNew( pKey );
|
||||
/* printf( "\nntxPageAddPageKeyAdd - 2( %s %d %d )", hb_itemGetCPtr( pKey ),level,pos ); */
|
||||
}
|
||||
nEnd = pos;
|
||||
while( ( nCount < nMaxCount ) && ( nEnd < MaxKeys ) && ( pPage->pKeys[ nEnd + 1 ].Tag == 0 ) )
|
||||
else
|
||||
{
|
||||
nEnd++;
|
||||
nCount++;
|
||||
nBegin = pos;
|
||||
nCount = 0;
|
||||
while( ( nCount < nMaxCount ) && ( nBegin > 0 ) && ( pPage->pKeys[ nBegin - 1 ].Tag == 0 ) )
|
||||
{
|
||||
nBegin--;
|
||||
nCount++;
|
||||
|
||||
}
|
||||
nEnd = pos;
|
||||
while( ( nCount < nMaxCount ) && ( nEnd < pPage->uiKeys - 1 ) && ( pPage->pKeys[ nEnd + 1 ].Tag == 0 ) )
|
||||
{
|
||||
nEnd++;
|
||||
nCount++;
|
||||
}
|
||||
nNewPos = pos - nBegin ;
|
||||
if( nNewPos > 0 )
|
||||
memmove( pNewPage->pKeys, pPage->pKeys + nBegin, nNewPos * sizeof( KEYINFO ));
|
||||
pNewPage->pKeys[nNewPos].Xtra = pPage->TagParent->Owner->Owner->ulRecNo;
|
||||
pNewPage->pKeys[nNewPos].pItem = hb_itemNew( pKey );
|
||||
/* printf( "\nntxPageAddPageKeyAdd - 1( %s %d %d ) %d %d %d %d", hb_itemGetCPtr( pKey ),level,pos,nBegin,nNewPos,nEnd,pPage->uiKeys ); */
|
||||
if( nEnd > pos )
|
||||
memmove( pNewPage->pKeys + nNewPos + 1, pPage->pKeys + pos, ( nEnd - pos ) * sizeof( KEYINFO ));
|
||||
pPage->pKeys[nEnd].Tag = pNewPage->Page;
|
||||
memmove( pPage->pKeys + nBegin , pPage->pKeys + nEnd,
|
||||
( pPage->uiKeys - nEnd + 1) * sizeof( KEYINFO ) );
|
||||
pPage->uiKeys -= nCount;
|
||||
pNewPage->uiKeys = nCount + 1;
|
||||
}
|
||||
nNewPos = pos - nBegin ;
|
||||
if( nNewPos > 0 )
|
||||
memmove( pNewPage->pKeys, pPage->pKeys + nBegin, nNewPos * sizeof( KEYINFO ));
|
||||
pNewPage->pKeys[nNewPos].Xtra = pPage->TagParent->Owner->Owner->ulRecNo;
|
||||
pNewPage->pKeys[nNewPos].pItem = hb_itemNew( pKey );
|
||||
if( nEnd > pos )
|
||||
memmove( pNewPage->pKeys + nNewPos + 1, pPage->pKeys + pos, ( nEnd - pos ) * sizeof( KEYINFO ));
|
||||
pPage->pKeys[nEnd].Tag = pNewPage->Page;
|
||||
memmove( pPage->pKeys + nBegin , pPage->pKeys + nEnd,
|
||||
( pPage->uiKeys - nEnd ) * sizeof( KEYINFO ) + sizeof( pPage->pKeys->Tag ) );
|
||||
pPage->uiKeys -= nCount;
|
||||
pNewPage->uiKeys = nCount + 1;
|
||||
pPage->Changed = TRUE;
|
||||
pNewPage->Changed = TRUE;
|
||||
hb_ntxPageFree( pNewPage );
|
||||
@@ -279,8 +413,10 @@ static ERRCODE hb_ntxPageAddPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int lev
|
||||
|
||||
static ERRCODE hb_ntxPageKeyInsert( LPPAGEINFO pPage, PHB_ITEM pKey, int pos )
|
||||
{
|
||||
memcpy( pPage->pKeys + pos + 1 , pPage->pKeys + pos ,
|
||||
( pPage->uiKeys - pos ) * sizeof( KEYINFO ) + sizeof( pPage->pKeys->Tag ) );
|
||||
int i;
|
||||
/* printf( "\nntxPageKeyInsert ( %d %s )", pos,hb_itemGetCPtr( pKey ) ); */
|
||||
backcpy( pPage->pKeys + pos + 1 , pPage->pKeys + pos ,
|
||||
( pPage->uiKeys - pos + 1 ) * sizeof( KEYINFO ) );
|
||||
pPage->uiKeys++;
|
||||
pPage->Changed = TRUE;
|
||||
pPage->pKeys[pos].Xtra = pPage->TagParent->Owner->Owner->ulRecNo;
|
||||
@@ -294,6 +430,7 @@ static ERRCODE hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level)
|
||||
int i,cmp;
|
||||
LPPAGEINFO pLoadedPage;
|
||||
|
||||
/* printf( "\nntxPageKeyAdd - 0" ); */
|
||||
i=0;
|
||||
if( pPage->uiKeys == 0 )
|
||||
{
|
||||
@@ -308,7 +445,7 @@ static ERRCODE hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level)
|
||||
cmp = hb_ntxItemCompare( pPage->pKeys[ i ].pItem , pKey );
|
||||
if( cmp > 0 )
|
||||
{
|
||||
if( pPage->uiKeys == pPage->TagParent->MaxKeys )
|
||||
if( pPage->uiKeys == pPage->TagParent->MaxKeys && pPage->pKeys[i].Tag == 0 )
|
||||
{
|
||||
hb_ntxPageAddPageKeyAdd(pPage, pKey, level, i );
|
||||
}
|
||||
@@ -331,8 +468,10 @@ static ERRCODE hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
/* printf( "\nntxPageKeyAdd - 1" ); */
|
||||
if( pPage->uiKeys == pPage->TagParent->MaxKeys )
|
||||
{
|
||||
hb_ntxPageAddPageKeyAdd( pPage, pKey, level, pPage->uiKeys+1 );
|
||||
}
|
||||
else if( pPage->pKeys[i].Tag != 0 )
|
||||
{
|
||||
@@ -340,6 +479,7 @@ static ERRCODE hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level)
|
||||
if( pLoadedPage == NULL )
|
||||
{
|
||||
/* TODO : Error recovery ??? */
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
hb_ntxPageKeyAdd( pLoadedPage, pKey, level+1 );
|
||||
@@ -372,92 +512,11 @@ static ERRCODE hb_ntxTagKeyAdd( LPTAGINFO pTag, PHB_ITEM pKey)
|
||||
pPage->pKeys[0].Xtra = pTag->Owner->Owner->ulRecNo;
|
||||
pPage->pKeys[0].pItem = hb_itemNew( pKey );
|
||||
pTag->RootPage = pPage;
|
||||
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static LPNTXINDEX hb_ntxIndexNew( NTXAREAP pArea )
|
||||
{
|
||||
LPNTXINDEX pIndex, pIndexes;
|
||||
int found;
|
||||
|
||||
pIndex = ( LPNTXINDEX ) hb_xgrab( sizeof( NTXINDEX ) );
|
||||
memset( pIndex, 0, sizeof( NTXINDEX ) );
|
||||
pIndex->DiskFile = FS_ERROR;
|
||||
|
||||
pIndex->Owner = pArea;
|
||||
pIndex->NextAvail = -1;
|
||||
pIndex->TagRoot = 1;
|
||||
if( pArea->lpNtxIndex )
|
||||
{
|
||||
do
|
||||
{
|
||||
found = 0;
|
||||
pIndex->TagRoot++;
|
||||
pIndexes = pArea->lpNtxIndex;
|
||||
while( pIndexes->pNext != pArea->lpNtxIndex )
|
||||
{
|
||||
if( pIndex->TagRoot == pIndexes->TagRoot )
|
||||
found = 1;
|
||||
pIndexes = pIndexes->pNext;
|
||||
}
|
||||
}
|
||||
while( found );
|
||||
}
|
||||
return pIndex;
|
||||
}
|
||||
|
||||
static void hb_ntxIndexFree( LPNTXINDEX pIndex )
|
||||
{
|
||||
LPTAGINFO pTag;
|
||||
|
||||
pTag = pIndex->CompoundTag;
|
||||
if( pTag->RootPage > 0 )
|
||||
hb_ntxPageFree( pTag->RootPage );
|
||||
hb_fsClose( pIndex->DiskFile );
|
||||
hb_xfree( pTag->TagName );
|
||||
if( pTag->KeyExpr != NULL )
|
||||
hb_xfree( pTag->KeyExpr );
|
||||
if( pTag->ForExpr != NULL )
|
||||
hb_xfree( pTag->ForExpr );
|
||||
if( pTag->pKeyItem != NULL )
|
||||
hb_itemRelease( pTag->pKeyItem );
|
||||
if( pTag->pForItem != NULL )
|
||||
hb_itemRelease( pTag->pForItem );
|
||||
hb_xfree( pTag );
|
||||
hb_xfree( pIndex->IndexName );
|
||||
hb_xfree( pIndex );
|
||||
}
|
||||
|
||||
static LPTAGINFO hb_ntxTagNew( LPNTXINDEX PIF, char * ITN, char *szKeyExpr, PHB_ITEM pKeyExpr, BYTE bKeyType, USHORT uiKeyLen, char *szForExp, PHB_ITEM pForExp, BOOL fAscendKey, BOOL fUnique )
|
||||
{
|
||||
LPTAGINFO pTag;
|
||||
|
||||
pTag = ( LPTAGINFO ) hb_xgrab( sizeof( TAGINFO ) );
|
||||
memset( pTag, 0, sizeof( TAGINFO ) );
|
||||
pTag->TagName = (char *) hb_xgrab( strlen( ITN ) + 1 );
|
||||
hb_strncpyUpper( pTag->TagName, ITN, strlen( ITN ) + 1 );
|
||||
if( szKeyExpr )
|
||||
{
|
||||
pTag->KeyExpr = (char *) hb_xgrab( NTX_MAX_KEY );
|
||||
strcpy( pTag->KeyExpr, szKeyExpr );
|
||||
}
|
||||
if( szForExp )
|
||||
{
|
||||
pTag->ForExpr = (char *) hb_xgrab( NTX_MAX_KEY );
|
||||
strcpy( pTag->ForExpr, szForExp );
|
||||
}
|
||||
pTag->pKeyItem = pKeyExpr;
|
||||
pTag->pForItem = pForExp;
|
||||
pTag->AscendKey = fAscendKey;
|
||||
pTag->UniqueKey = fUnique;
|
||||
pTag->KeyType = bKeyType;
|
||||
pTag->KeyLength = uiKeyLen;
|
||||
pTag->Owner = PIF;
|
||||
pTag->MaxKeys = (NTXBLOCKSIZE-6)/(uiKeyLen+10);
|
||||
return pTag;
|
||||
}
|
||||
|
||||
static ERRCODE hb_ntxIndexCreate( LPNTXINDEX pIndex )
|
||||
{
|
||||
ULONG ulRecNo, ulRecCount;
|
||||
@@ -480,9 +539,9 @@ static ERRCODE hb_ntxIndexCreate( LPNTXINDEX pIndex )
|
||||
pItem = hb_itemNew( NULL );
|
||||
for( ulRecNo = 1; ulRecNo <= ulRecCount; ulRecNo++)
|
||||
{
|
||||
/* printf( "\nntxIndexCreate - 0" ); */
|
||||
hb_fsSeek( pArea->hDataFile,
|
||||
pArea->uiHeaderLen +
|
||||
( ulRecNo - 1 ) * pArea->uiRecordLen,
|
||||
pArea->uiHeaderLen + ( ulRecNo - 1 ) * pArea->uiRecordLen,
|
||||
FS_SET );
|
||||
hb_fsRead( pArea->hDataFile,
|
||||
pArea->pRecord,
|
||||
@@ -546,163 +605,24 @@ static ERRCODE hb_ntxIndexCreate( LPNTXINDEX pIndex )
|
||||
}
|
||||
}
|
||||
}
|
||||
/* printf( "\nntxIndexCreate - 1" ); */
|
||||
hb_itemRelease( pItem );
|
||||
hb_ntxPageFree( pTag->RootPage );
|
||||
pTag->RootPage = NULL;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static void hb_ntxPageFree( LPPAGEINFO pPage )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( pPage->Child )
|
||||
hb_ntxPageFree( pPage->Child );
|
||||
if( pPage->Changed )
|
||||
hb_ntxPageSave( pPage );
|
||||
if( pPage->NewRoot )
|
||||
{
|
||||
pPage->TagParent->RootBlock = pPage->Page;
|
||||
hb_ntxHeaderSave( pPage->TagParent->Owner );
|
||||
}
|
||||
for( i = 0; i< pPage->uiKeys; i++)
|
||||
{
|
||||
hb_itemRelease( pPage->pKeys[i].pItem );
|
||||
}
|
||||
hb_xfree( pPage->pKeys );
|
||||
hb_xfree( pPage );
|
||||
}
|
||||
|
||||
static LPPAGEINFO hb_ntxPageNew(LPTAGINFO pParentTag, LPPAGEINFO pParentPage)
|
||||
{
|
||||
LPPAGEINFO pPage;
|
||||
|
||||
pPage = ( LPPAGEINFO ) hb_xgrab( sizeof( HB_PAGEINFO ) );
|
||||
memset( pPage, 0, sizeof( HB_PAGEINFO ) );
|
||||
pPage->TagParent = pParentTag;
|
||||
pPage->Owner = pParentPage;
|
||||
pPage->CurKey = -1;
|
||||
pParentTag->TagBlock = pParentTag->TagBlock + 1024;
|
||||
pPage->Page = pParentTag->TagBlock;
|
||||
pPage->pKeys = ( LPKEYINFO ) hb_xgrab( sizeof( KEYINFO ) * ( pParentTag->MaxKeys + 1 ) );
|
||||
memset( pPage->pKeys, 0, sizeof( KEYINFO ) * ( pParentTag->MaxKeys + 1 ) );
|
||||
return pPage;
|
||||
}
|
||||
|
||||
static void hb_ntxPageSave( LPPAGEINFO pPage )
|
||||
{
|
||||
char buffer[NTXBLOCKSIZE+1];
|
||||
int i;
|
||||
LPNTXBUFFER itemlist;
|
||||
LPNTXITEM item;
|
||||
LPKEYINFO pKey;
|
||||
|
||||
pKey = pPage->pKeys;
|
||||
itemlist = ( LPNTXBUFFER ) buffer;
|
||||
itemlist->item_count = pPage->uiKeys;
|
||||
for( i = 0; i < pPage->uiKeys; i++ )
|
||||
{
|
||||
itemlist->item_offset[i] = 2 + 2 * ( pPage->TagParent->MaxKeys + 1 ) +
|
||||
i * ( pPage->TagParent->KeyLength + 8 );
|
||||
item=(NTXITEM *)(buffer+itemlist->item_offset[i]);
|
||||
item->page = pKey[i].Tag;
|
||||
item->rec_no = pKey[i].Xtra;
|
||||
strcpy(item->key, pKey[i].pItem->item.asString.value);
|
||||
}
|
||||
itemlist->item_offset[i] = 2 + 2 * ( pPage->TagParent->MaxKeys + 1 ) +
|
||||
i * ( pPage->TagParent->KeyLength + 8 );
|
||||
item=(NTXITEM *)(buffer+itemlist->item_offset[i]);
|
||||
item->page = pKey[i].Tag;
|
||||
hb_fsSeek( pPage->TagParent->Owner->DiskFile, pPage->Page, FS_SET );
|
||||
hb_fsWrite( pPage->TagParent->Owner->DiskFile, (BYTE *) buffer, NTXBLOCKSIZE );
|
||||
pPage->Changed = FALSE;
|
||||
}
|
||||
|
||||
static LPPAGEINFO hb_ntxIndexRootPageLoad( LPNTXINDEX pIndex )
|
||||
{
|
||||
char buffer[NTXBLOCKSIZE];
|
||||
int uiCount;
|
||||
int i;
|
||||
LPNTXBUFFER itemlist;
|
||||
LPNTXITEM item;
|
||||
LPPAGEINFO pPage;
|
||||
|
||||
hb_fsSeek( pIndex->DiskFile, pIndex->CompoundTag->RootBlock, FS_SET );
|
||||
uiCount = hb_fsRead( pIndex->DiskFile, ( BYTE * ) buffer, NTXBLOCKSIZE );
|
||||
if( uiCount != NTXBLOCKSIZE )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
pPage = ( LPPAGEINFO ) hb_xgrab( sizeof( HB_PAGEINFO ) );
|
||||
memset( pPage , 0 ,sizeof( HB_PAGEINFO ) );
|
||||
pPage->TagParent = pIndex->CompoundTag;
|
||||
pPage->Owner = NULL;
|
||||
pPage->CurKey = -1;
|
||||
pPage->Page = pIndex->CompoundTag->RootBlock;
|
||||
pPage->pKeys = ( LPKEYINFO ) hb_xgrab( sizeof( KEYINFO ) * ( pPage->TagParent->MaxKeys + 1 ) );
|
||||
memset( pPage->pKeys, 0, sizeof( KEYINFO ) * ( pPage->TagParent->MaxKeys + 1 ) );
|
||||
itemlist = ( LPNTXBUFFER ) buffer;
|
||||
pPage->uiKeys = itemlist->item_count;
|
||||
for( i = 0; i < itemlist->item_count; i++ )
|
||||
{
|
||||
item=(NTXITEM *)(buffer+itemlist->item_offset[i]);
|
||||
pPage->pKeys[i].Xtra = item->rec_no;
|
||||
pPage->pKeys[i].Tag = item->page;
|
||||
pPage->pKeys[i].pItem = hb_itemNew( NULL );
|
||||
hb_itemPutCL( pPage->pKeys[i].pItem, item->key, pPage->TagParent->KeyLength );
|
||||
}
|
||||
item=(NTXITEM *)(buffer+itemlist->item_offset[i]);
|
||||
pPage->pKeys[i].Tag = item->page;
|
||||
return pPage;
|
||||
}
|
||||
|
||||
static LPPAGEINFO hb_ntxPageLoad( LPPAGEINFO pParentPage, ULONG ulOffset )
|
||||
{
|
||||
char buffer[NTXBLOCKSIZE];
|
||||
int i, uiCount;
|
||||
LPNTXBUFFER itemlist;
|
||||
LPNTXITEM item;
|
||||
LPPAGEINFO pPage;
|
||||
|
||||
hb_fsSeek( pParentPage->TagParent->Owner->DiskFile, ulOffset, FS_SET );
|
||||
uiCount = hb_fsRead( pParentPage->TagParent->Owner->DiskFile, ( BYTE * ) buffer, NTXBLOCKSIZE );
|
||||
if( uiCount != NTXBLOCKSIZE )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
pPage = ( LPPAGEINFO ) hb_xgrab( sizeof( HB_PAGEINFO ) );
|
||||
memset( pPage , 0 ,sizeof( HB_PAGEINFO ) );
|
||||
pPage->TagParent = pParentPage->TagParent;
|
||||
pPage->Owner = pParentPage;
|
||||
pPage->CurKey = -1;
|
||||
pPage->Page = ulOffset;
|
||||
pPage->pKeys = ( LPKEYINFO ) hb_xgrab( sizeof( KEYINFO ) * ( pPage->TagParent->MaxKeys + 1 ) );
|
||||
memset( pPage->pKeys, 0, sizeof( KEYINFO ) * ( pPage->TagParent->MaxKeys + 1 ) );
|
||||
|
||||
itemlist = ( LPNTXBUFFER ) buffer;
|
||||
pPage->uiKeys = itemlist->item_count ;
|
||||
for( i = 0; i < itemlist->item_count; i++ )
|
||||
{
|
||||
item=(NTXITEM *)(buffer+itemlist->item_offset[i]);
|
||||
pPage->pKeys[i].Xtra = item->rec_no;
|
||||
pPage->pKeys[i].Tag = item->page;
|
||||
pPage->pKeys[i].pItem = hb_itemNew( NULL );
|
||||
hb_itemPutCL( pPage->pKeys[i].pItem, item->key, pPage->TagParent->KeyLength );
|
||||
}
|
||||
item=(NTXITEM *)(buffer+itemlist->item_offset[i]);
|
||||
pPage->pKeys[i].Tag = item->page;
|
||||
return pPage;
|
||||
}
|
||||
|
||||
static void hb_ntxHeaderSave( LPNTXINDEX pIndex )
|
||||
{
|
||||
NTXHEADER Header;
|
||||
|
||||
memset( (void*) &Header, 0, sizeof( NTXHEADER ) );
|
||||
Header.type = 15;
|
||||
Header.version = 1;
|
||||
Header.root = pIndex->CompoundTag->RootBlock;
|
||||
Header.next_page = pIndex->NextAvail;
|
||||
Header.item_size = pIndex->CompoundTag->KeyLength+4;
|
||||
Header.item_size = pIndex->CompoundTag->KeyLength+8;
|
||||
|
||||
Header.key_size = pIndex->CompoundTag->KeyLength;
|
||||
Header.key_dec = 0;
|
||||
Header.max_item = pIndex->CompoundTag->MaxKeys;
|
||||
@@ -715,6 +635,90 @@ static void hb_ntxHeaderSave( LPNTXINDEX pIndex )
|
||||
pIndex->CompoundTag->RootPage->NewRoot = FALSE;
|
||||
}
|
||||
|
||||
static LPTAGINFO hb_ntxTagNew( LPNTXINDEX PIF, char * ITN, char *szKeyExpr, PHB_ITEM pKeyExpr, BYTE bKeyType, USHORT uiKeyLen, char *szForExp, PHB_ITEM pForExp, BOOL fAscendKey, BOOL fUnique )
|
||||
{
|
||||
LPTAGINFO pTag;
|
||||
|
||||
pTag = ( LPTAGINFO ) hb_xgrab( sizeof( TAGINFO ) );
|
||||
memset( pTag, 0, sizeof( TAGINFO ) );
|
||||
// pTag->TagName = (char *) hb_xgrab( strlen( ITN ) + 1 );
|
||||
|
||||
// hb_strncpyUpper( pTag->TagName, ITN, strlen( ITN ) + 1 );
|
||||
pTag->TagName = ITN;
|
||||
if( szKeyExpr )
|
||||
{
|
||||
pTag->KeyExpr = (char *) hb_xgrab( NTX_MAX_KEY );
|
||||
strcpy( pTag->KeyExpr, szKeyExpr );
|
||||
}
|
||||
if( szForExp )
|
||||
{
|
||||
pTag->ForExpr = (char *) hb_xgrab( NTX_MAX_KEY );
|
||||
strcpy( pTag->ForExpr, szForExp );
|
||||
}
|
||||
pTag->pKeyItem = pKeyExpr;
|
||||
pTag->pForItem = pForExp;
|
||||
pTag->AscendKey = fAscendKey;
|
||||
pTag->UniqueKey = fUnique;
|
||||
pTag->KeyType = bKeyType;
|
||||
pTag->KeyLength = uiKeyLen;
|
||||
pTag->Owner = PIF;
|
||||
pTag->MaxKeys = (NTXBLOCKSIZE-6)/(uiKeyLen+10) - 1;
|
||||
return pTag;
|
||||
}
|
||||
|
||||
static LPNTXINDEX hb_ntxIndexNew( NTXAREAP pArea )
|
||||
{
|
||||
LPNTXINDEX pIndex, pIndexes;
|
||||
int found;
|
||||
|
||||
pIndex = ( LPNTXINDEX ) hb_xgrab( sizeof( NTXINDEX ) );
|
||||
memset( pIndex, 0, sizeof( NTXINDEX ) );
|
||||
pIndex->DiskFile = FS_ERROR;
|
||||
|
||||
pIndex->Owner = pArea;
|
||||
pIndex->NextAvail = -1;
|
||||
pIndex->TagRoot = 1;
|
||||
if( pArea->lpNtxIndex )
|
||||
{
|
||||
do
|
||||
{
|
||||
found = 0;
|
||||
pIndex->TagRoot++;
|
||||
pIndexes = pArea->lpNtxIndex;
|
||||
while( pIndexes->pNext != pArea->lpNtxIndex )
|
||||
{
|
||||
if( pIndex->TagRoot == pIndexes->TagRoot )
|
||||
found = 1;
|
||||
pIndexes = pIndexes->pNext;
|
||||
}
|
||||
}
|
||||
while( found );
|
||||
}
|
||||
return pIndex;
|
||||
}
|
||||
|
||||
static void hb_ntxIndexFree( LPNTXINDEX pIndex )
|
||||
{
|
||||
LPTAGINFO pTag;
|
||||
|
||||
pTag = pIndex->CompoundTag;
|
||||
if( pTag->RootPage > 0 )
|
||||
hb_ntxPageFree( pTag->RootPage );
|
||||
hb_fsClose( pIndex->DiskFile );
|
||||
hb_xfree( pTag->TagName );
|
||||
if( pTag->KeyExpr != NULL )
|
||||
hb_xfree( pTag->KeyExpr );
|
||||
if( pTag->ForExpr != NULL )
|
||||
hb_xfree( pTag->ForExpr );
|
||||
if( pTag->pKeyItem != NULL )
|
||||
hb_itemRelease( pTag->pKeyItem );
|
||||
if( pTag->pForItem != NULL )
|
||||
hb_itemRelease( pTag->pForItem );
|
||||
hb_xfree( pTag );
|
||||
hb_xfree( pIndex->IndexName );
|
||||
hb_xfree( pIndex );
|
||||
}
|
||||
|
||||
static ERRCODE hb_ntxHeaderLoad( LPNTXINDEX pIndex , char *ITN)
|
||||
{
|
||||
NTXHEADER Header;
|
||||
@@ -747,6 +751,47 @@ static ERRCODE hb_ntxHeaderLoad( LPNTXINDEX pIndex , char *ITN)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static LPPAGEINFO hb_ntxIndexRootPageLoad( LPNTXINDEX pIndex )
|
||||
{
|
||||
char buffer[NTXBLOCKSIZE];
|
||||
int uiCount;
|
||||
int i;
|
||||
LPNTXBUFFER itemlist;
|
||||
|
||||
LPNTXITEM item;
|
||||
LPPAGEINFO pPage;
|
||||
|
||||
|
||||
hb_fsSeek( pIndex->DiskFile, pIndex->CompoundTag->RootBlock, FS_SET );
|
||||
uiCount = hb_fsRead( pIndex->DiskFile, ( BYTE * ) buffer, NTXBLOCKSIZE );
|
||||
if( uiCount != NTXBLOCKSIZE )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
pPage = ( LPPAGEINFO ) hb_xgrab( sizeof( HB_PAGEINFO ) );
|
||||
memset( pPage , 0 ,sizeof( HB_PAGEINFO ) );
|
||||
pPage->TagParent = pIndex->CompoundTag;
|
||||
pPage->Owner = NULL;
|
||||
pPage->CurKey = -1;
|
||||
pPage->Page = pIndex->CompoundTag->RootBlock;
|
||||
pPage->pKeys = ( LPKEYINFO ) hb_xgrab( sizeof( KEYINFO ) * ( pPage->TagParent->MaxKeys + 1 ) );
|
||||
memset( pPage->pKeys, 0, sizeof( KEYINFO ) * ( pPage->TagParent->MaxKeys + 1 ) );
|
||||
itemlist = ( LPNTXBUFFER ) buffer;
|
||||
pPage->uiKeys = itemlist->item_count;
|
||||
|
||||
for( i = 0; i < itemlist->item_count; i++ )
|
||||
{
|
||||
item=(NTXITEM *)(buffer+itemlist->item_offset[i]);
|
||||
pPage->pKeys[i].Xtra = item->rec_no;
|
||||
pPage->pKeys[i].Tag = item->page;
|
||||
pPage->pKeys[i].pItem = hb_itemNew( NULL );
|
||||
hb_itemPutCL( pPage->pKeys[i].pItem, item->key, pPage->TagParent->KeyLength );
|
||||
}
|
||||
item=(NTXITEM *)(buffer+itemlist->item_offset[i]);
|
||||
pPage->pKeys[i].Tag = item->page;
|
||||
return pPage;
|
||||
}
|
||||
|
||||
static LPNTXINDEX ntxFindIndex( NTXAREAP pArea , PHB_ITEM lpOrder )
|
||||
{
|
||||
LPNTXINDEX start, current;
|
||||
@@ -979,6 +1024,7 @@ static ERRCODE ntxOrderCreate( NTXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo )
|
||||
pIndex->IndexName = szFileName;
|
||||
pArea->lpNtxIndex = pIndex;
|
||||
pTag = hb_ntxTagNew( pIndex, szTagName, pOrderInfo->abExpr->item.asString.value,
|
||||
|
||||
pKeyExp, bType, uiLen, (char *) ( pArea->lpdbOrdCondInfo ? pArea->lpdbOrdCondInfo->abFor : NULL ),
|
||||
pForExp, pArea->lpdbOrdCondInfo ? !pArea->lpdbOrdCondInfo->fDescending : TRUE,
|
||||
pOrderInfo->fUnique );
|
||||
@@ -1182,7 +1228,7 @@ static RDDFUNCS ntxTable = { ntxBof,
|
||||
ntxNewArea,
|
||||
ntxOpen,
|
||||
ntxRelease,
|
||||
ntxStructSize,
|
||||
( DBENTRYP_SP ) ntxStructSize,
|
||||
ntxSysName,
|
||||
ntxEval,
|
||||
ntxPack,
|
||||
@@ -1252,4 +1298,4 @@ HB_FUNC( DBFNTX_GETFUNCTABLE )
|
||||
hb_retni( hb_rddInherit( pTable, &ntxTable, &ntxSuper, ( BYTE * ) "DBF" ) );
|
||||
else
|
||||
hb_retni( FAILURE );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user