2000-12-09 14:09 UTC-0800 Brian Hays <bhays@abacuslaw.com>

This commit is contained in:
Brian Hays
2000-12-09 22:04:40 +00:00
parent e7a8e2bda9
commit 5275c2a020

View File

@@ -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 );
}
}