2010-03-01 13:42 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/src/rdd/dbfntx/dbfntx1.c
  * harbour/src/rdd/dbfnsx/dbfnsx1.c
  * harbour/src/rdd/dbfcdx/dbfcdx1.c
    ! make linear scan in template tags to detect position of current
      record in tag after GOTO() operation - SIX3 compatible behavior
This commit is contained in:
Przemyslaw Czerpak
2010-03-01 12:42:34 +00:00
parent 7c8e18e208
commit 820d1d28d8
4 changed files with 161 additions and 112 deletions

View File

@@ -17,6 +17,13 @@
past entries belonging to author(s): Viktor Szakats.
*/
2010-03-01 13:42 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/src/rdd/dbfntx/dbfntx1.c
* harbour/src/rdd/dbfnsx/dbfnsx1.c
* harbour/src/rdd/dbfcdx/dbfcdx1.c
! make linear scan in template tags to detect position of current
record in tag after GOTO() operation - SIX3 compatible behavior
2010-03-01 08:00 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/src/vm/hvm.c
! added missing HB_STACK_TLS_PRELOAD

View File

@@ -5201,6 +5201,16 @@ static HB_BOOL hb_cdxCurKeyRefresh( CDXAREAP pArea, LPCDXTAG pTag )
if( memcmp( buf, pKey->val, pKey->len ) != 0 )
hb_cdxTagKeyFind( pTag, pKey );
}
if( pTag->CurKey->rec != pArea->dbfarea.ulRecNo && pTag->Template )
{
hb_cdxTagGoTop( pTag );
while( !pTag->TagBOF && !pTag->TagEOF && hb_cdxBottomScope( pTag ) )
{
if( pTag->CurKey->rec == pArea->dbfarea.ulRecNo )
break;
hb_cdxTagSkipNext( pTag );
}
}
}
hb_cdxKeyFree( pKey );
return ( pTag->CurKey->rec != 0 && pTag->CurKey->rec == pArea->dbfarea.ulRecNo );

View File

@@ -1650,6 +1650,17 @@ static HB_ULONG hb_nsxPageGetFree( LPTAGINFO pTag )
return ulPage;
}
/*
* SIX3 compatible template index expression detection
*/
static HB_BOOL hb_nsxIsTemplateFunc( const char * szKeyExpr )
{
return hb_strnicmp( szKeyExpr, "sxChar(", 7 ) == 0 ||
hb_strnicmp( szKeyExpr, "sxDate(", 7 ) == 0 ||
hb_strnicmp( szKeyExpr, "sxNum(", 6 ) == 0 ||
hb_strnicmp( szKeyExpr, "sxLog(", 6 ) == 0;
}
/*
* create the new tag structure
*/
@@ -3417,61 +3428,6 @@ static HB_BOOL hb_nsxTagKeyDel( LPTAGINFO pTag, LPKEYINFO pKey )
/* ************************************************************************* */
/*
* refresh CurKey value and set proper path from RootPage to LeafPage
*/
static HB_BOOL hb_nsxCurKeyRefresh( LPTAGINFO pTag )
{
NSXAREAP pArea = pTag->pIndex->pArea;
if( pArea->dbfarea.lpdbPendingRel )
SELF_FORCEREL( ( AREAP ) pArea );
if( !pArea->dbfarea.fPositioned )
{
pTag->stackLevel = 0;
pTag->TagBOF = pTag->TagEOF = HB_TRUE;
pTag->CurKeyInfo->rec = 0;
return HB_FALSE;
}
else if( pTag->stackLevel == 0 || pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo )
{
HB_BOOL fValidBuf = pArea->dbfarea.fValidBuffer;
HB_BYTE buf[ NSX_MAXKEYLEN ];
HB_BOOL fBuf = HB_FALSE;
LPKEYINFO pKey = NULL;
/* Try to find previous if it's key for the same record */
if( pTag->CurKeyInfo->rec == pArea->dbfarea.ulRecNo )
{
fBuf = HB_TRUE;
memcpy( buf, pTag->CurKeyInfo->val, pTag->KeyLength );
pKey = hb_nsxKeyCopy( pKey, pTag->CurKeyInfo, pTag->KeyLength );
hb_nsxTagKeyFind( pTag, pKey, pTag->KeyLength );
}
if( pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo )
{
/* not found, create new key from DBF and if differs seek again */
pKey = hb_nsxEvalKey( pKey, pTag );
if( !fBuf || memcmp( buf, pKey->val, pTag->KeyLength ) != 0 )
hb_nsxTagKeyFind( pTag, pKey, pTag->KeyLength );
/* not found, if key was generated from DBF buffer then force to
* update it, create the new key and if differs seek again */
if( pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo && fValidBuf )
{
SELF_GOTO( ( AREAP ) pArea, pArea->dbfarea.ulRecNo );
memcpy( buf, pKey->val, pTag->KeyLength );
pKey = hb_nsxEvalKey( pKey, pTag );
if( memcmp( buf, pKey->val, pTag->KeyLength ) != 0 )
hb_nsxTagKeyFind( pTag, pKey, pTag->KeyLength );
}
}
hb_nsxKeyFree( pKey );
return pTag->CurKeyInfo->rec != 0 && pTag->CurKeyInfo->rec == pArea->dbfarea.ulRecNo;
}
pTag->TagBOF = pTag->TagEOF = HB_FALSE;
return HB_TRUE;
}
/*
* Skip in tag respecting record filter only
*/
@@ -3709,6 +3665,71 @@ static void hb_nsxTagGoToRelKeyPos( LPTAGINFO pTag, double dPos )
hb_nsxTagPrevKey( pTag );
}
/*
* refresh CurKey value and set proper path from RootPage to LeafPage
*/
static HB_BOOL hb_nsxCurKeyRefresh( LPTAGINFO pTag )
{
NSXAREAP pArea = pTag->pIndex->pArea;
if( pArea->dbfarea.lpdbPendingRel )
SELF_FORCEREL( ( AREAP ) pArea );
if( !pArea->dbfarea.fPositioned )
{
pTag->stackLevel = 0;
pTag->TagBOF = pTag->TagEOF = HB_TRUE;
pTag->CurKeyInfo->rec = 0;
return HB_FALSE;
}
else if( pTag->stackLevel == 0 || pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo )
{
HB_BOOL fValidBuf = pArea->dbfarea.fValidBuffer;
HB_BYTE buf[ NSX_MAXKEYLEN ];
HB_BOOL fBuf = HB_FALSE;
LPKEYINFO pKey = NULL;
/* Try to find previous if it's key for the same record */
if( pTag->CurKeyInfo->rec == pArea->dbfarea.ulRecNo )
{
fBuf = HB_TRUE;
memcpy( buf, pTag->CurKeyInfo->val, pTag->KeyLength );
pKey = hb_nsxKeyCopy( pKey, pTag->CurKeyInfo, pTag->KeyLength );
hb_nsxTagKeyFind( pTag, pKey, pTag->KeyLength );
}
if( pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo )
{
/* not found, create new key from DBF and if differs seek again */
pKey = hb_nsxEvalKey( pKey, pTag );
if( !fBuf || memcmp( buf, pKey->val, pTag->KeyLength ) != 0 )
hb_nsxTagKeyFind( pTag, pKey, pTag->KeyLength );
/* not found, if key was generated from DBF buffer then force to
* update it, create the new key and if differs seek again */
if( pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo && fValidBuf )
{
SELF_GOTO( ( AREAP ) pArea, pArea->dbfarea.ulRecNo );
memcpy( buf, pKey->val, pTag->KeyLength );
pKey = hb_nsxEvalKey( pKey, pTag );
if( memcmp( buf, pKey->val, pTag->KeyLength ) != 0 )
hb_nsxTagKeyFind( pTag, pKey, pTag->KeyLength );
}
if( pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo && pTag->Template )
{
hb_nsxTagGoTop( pTag );
while( !pTag->TagEOF )
{
if( pTag->CurKeyInfo->rec == pArea->dbfarea.ulRecNo )
break;
hb_nsxTagSkipNext( pTag );
}
}
}
hb_nsxKeyFree( pKey );
return pTag->CurKeyInfo->rec != 0 && pTag->CurKeyInfo->rec == pArea->dbfarea.ulRecNo;
}
pTag->TagBOF = pTag->TagEOF = HB_FALSE;
return HB_TRUE;
}
/*
* free pages allocated by tag
*/
@@ -6900,6 +6921,7 @@ static HB_ERRCODE hb_nsxOrderCreate( NSXAREAP pArea, LPDBORDERCREATEINFO pOrderI
szKey, pKeyExp, bType, ( HB_USHORT ) iLen, bTrail,
szFor, pForExp,
fAscend, pOrderInfo->fUnique, fCustom );
pTag->Template = hb_nsxIsTemplateFunc( pTag->KeyExpr );
pTag->Partial = ( pArea->dbfarea.area.lpdbOrdCondInfo && !pArea->dbfarea.area.lpdbOrdCondInfo->fAll );
if( fNewFile )

View File

@@ -3194,63 +3194,6 @@ static HB_BOOL hb_ntxTagKeyDel( LPTAGINFO pTag, LPKEYINFO pKey )
return HB_TRUE;
}
/*
* refresh CurKey value and set proper path from RootPage to LeafPage
*/
static HB_BOOL hb_ntxCurKeyRefresh( LPTAGINFO pTag )
{
NTXAREAP pArea = pTag->Owner->Owner;
if( pArea->dbfarea.lpdbPendingRel )
SELF_FORCEREL( ( AREAP ) pArea );
if( !pArea->dbfarea.fPositioned )
{
pTag->stackLevel = 0;
pTag->TagBOF = pTag->TagEOF = HB_TRUE;
pTag->CurKeyInfo->Xtra = 0;
return HB_FALSE;
}
else if( pTag->stackLevel == 0 || pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo )
{
HB_BYTE buf[ NTX_MAX_KEY ];
HB_BOOL fBuf = HB_FALSE;
LPKEYINFO pKey = NULL;
/* Try to find previous if it's key for the same record */
if( pTag->CurKeyInfo->Xtra == pArea->dbfarea.ulRecNo )
{
fBuf = HB_TRUE;
memcpy( buf, pTag->CurKeyInfo->key, pTag->KeyLength );
pKey = hb_ntxKeyCopy( pKey, pTag->CurKeyInfo, pTag->KeyLength );
hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength );
}
if( pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo )
{
HB_BOOL fValidBuf = pArea->dbfarea.fValidBuffer;
/* not found, create new key from DBF and if differs seek again */
pKey = hb_ntxEvalKey( pKey, pTag );
if( !fBuf || memcmp( buf, pKey->key, pTag->KeyLength ) != 0 )
{
hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength );
}
/* not found, if key was generated from DBF buffer then force to
* update it, create the new key and if differs seek again */
if( pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo && fValidBuf )
{
SELF_GOTO( ( AREAP ) pArea, pArea->dbfarea.ulRecNo );
memcpy( buf, pKey->key, pTag->KeyLength );
pKey = hb_ntxEvalKey( pKey, pTag );
if( memcmp( buf, pKey->key, pTag->KeyLength ) != 0 )
hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength );
}
}
hb_ntxKeyFree( pKey );
return pTag->CurKeyInfo->Xtra != 0 && pTag->CurKeyInfo->Xtra == pArea->dbfarea.ulRecNo;
}
pTag->TagBOF = pTag->TagEOF = HB_FALSE;
return HB_TRUE;
}
/*
* Skip in tag respecting record filter only
*/
@@ -3474,6 +3417,73 @@ static void hb_ntxTagGoToRelKeyPos( LPTAGINFO pTag, double dPos )
hb_ntxTagPrevKey( pTag );
}
/*
* refresh CurKey value and set proper path from RootPage to LeafPage
*/
static HB_BOOL hb_ntxCurKeyRefresh( LPTAGINFO pTag )
{
NTXAREAP pArea = pTag->Owner->Owner;
if( pArea->dbfarea.lpdbPendingRel )
SELF_FORCEREL( ( AREAP ) pArea );
if( !pArea->dbfarea.fPositioned )
{
pTag->stackLevel = 0;
pTag->TagBOF = pTag->TagEOF = HB_TRUE;
pTag->CurKeyInfo->Xtra = 0;
return HB_FALSE;
}
else if( pTag->stackLevel == 0 || pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo )
{
HB_BYTE buf[ NTX_MAX_KEY ];
HB_BOOL fBuf = HB_FALSE;
LPKEYINFO pKey = NULL;
/* Try to find previous if it's key for the same record */
if( pTag->CurKeyInfo->Xtra == pArea->dbfarea.ulRecNo )
{
fBuf = HB_TRUE;
memcpy( buf, pTag->CurKeyInfo->key, pTag->KeyLength );
pKey = hb_ntxKeyCopy( pKey, pTag->CurKeyInfo, pTag->KeyLength );
hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength );
}
if( pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo )
{
HB_BOOL fValidBuf = pArea->dbfarea.fValidBuffer;
/* not found, create new key from DBF and if differs seek again */
pKey = hb_ntxEvalKey( pKey, pTag );
if( !fBuf || memcmp( buf, pKey->key, pTag->KeyLength ) != 0 )
{
hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength );
}
/* not found, if key was generated from DBF buffer then force to
* update it, create the new key and if differs seek again */
if( pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo && fValidBuf )
{
SELF_GOTO( ( AREAP ) pArea, pArea->dbfarea.ulRecNo );
memcpy( buf, pKey->key, pTag->KeyLength );
pKey = hb_ntxEvalKey( pKey, pTag );
if( memcmp( buf, pKey->key, pTag->KeyLength ) != 0 )
hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength );
}
if( pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo && pTag->Template )
{
hb_ntxTagGoTop( pTag );
while( !pTag->TagEOF )
{
if( pTag->CurKeyInfo->Xtra == pArea->dbfarea.ulRecNo )
break;
hb_ntxTagSkipNext( pTag );
}
}
}
hb_ntxKeyFree( pKey );
return pTag->CurKeyInfo->Xtra != 0 && pTag->CurKeyInfo->Xtra == pArea->dbfarea.ulRecNo;
}
pTag->TagBOF = pTag->TagEOF = HB_FALSE;
return HB_TRUE;
}
/*
* free pages allocated by tag
*/