diff --git a/harbour/source/rdd/dbfntx/dbfntx1.c b/harbour/source/rdd/dbfntx/dbfntx1.c index 74283476b4..d27fb68924 100644 --- a/harbour/source/rdd/dbfntx/dbfntx1.c +++ b/harbour/source/rdd/dbfntx/dbfntx1.c @@ -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 ); -} +} \ No newline at end of file