From 1fb6dd39621c73ec0753422790cd6247ca46effb Mon Sep 17 00:00:00 2001 From: Mindaugas Kavaliauskas Date: Thu, 13 Mar 2014 18:43:00 +0200 Subject: [PATCH] 2014-03-13 18:40 UTC+0200 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt) * contrib/rddads/adsx.c * implemented intermediate index creation in case ADS can process index FOR or WHILE condition. Ex., if requested index has WHILE condition supported by server, but index key expression is not supported (or codeblock is used), server side index is created using WHILE condition. This intermediate index later is used to create final index. This logic increases speed dramatically if WHILE condition was used to filter a few records from a large database using subindex. --- ChangeLog.txt | 11 ++++ contrib/rddads/adsx.c | 115 +++++++++++++++++++++++++++++++++--------- 2 files changed, 103 insertions(+), 23 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index cc8db1a086..6c9ce8d4fa 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,17 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2014-03-13 18:40 UTC+0200 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt) + * contrib/rddads/adsx.c + * implemented intermediate index creation in case ADS can process index + FOR or WHILE condition. + Ex., if requested index has WHILE condition supported by server, + but index key expression is not supported (or codeblock is used), + server side index is created using WHILE condition. This intermediate + index later is used to create final index. + This logic increases speed dramatically if WHILE condition was used + to filter a few records from a large database using subindex. + 2014-03-12 00:18 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * src/rdd/hbdbsort.c * casting diff --git a/contrib/rddads/adsx.c b/contrib/rddads/adsx.c index 2ed9491048..550af3d99e 100644 --- a/contrib/rddads/adsx.c +++ b/contrib/rddads/adsx.c @@ -132,7 +132,7 @@ static RDDFUNCS adsxSuper; static HB_ERRCODE hb_mixErrorRT( ADSXAREAP pArea, HB_ERRCODE errGenCode, HB_ERRCODE errSubCode, - char * filename, HB_ERRCODE errOsCode, + const char * filename, HB_ERRCODE errOsCode, HB_USHORT uiFlags ) { PHB_ITEM pError; @@ -497,9 +497,7 @@ static PMIXTAG mixTagCreate( const char * szTagName, PHB_ITEM pKeyExpr, PHB_ITEM } if( pWhileItem && ! mixEvalCond( pWhileItem, NULL ) ) - { break; - } if( pForItem == NULL || mixEvalCond( pForItem, NULL ) ) { @@ -1093,46 +1091,96 @@ static HB_ERRCODE adsxOrderCreate( ADSXAREAP pArea, LPDBORDERCREATEINFO pOrderIn HB_USHORT uiLen; HB_BYTE bType; UNSIGNED16 bValidExpr; - HB_BOOL bUseADS; + HB_BOOL bKeyADS, bForADS, bWhileADS; + ADSHANDLE hIndex = NULL; + + bForADS = bWhileADS = HB_TRUE; /* Test key expression */ bValidExpr = 0; AdsIsExprValid( pArea->adsarea.hTable, ( UNSIGNED8 * ) hb_itemGetCPtr( pOrderInfo->abExpr ), &bValidExpr ); - bUseADS = bValidExpr; + bKeyADS = bValidExpr; - if( bUseADS && pArea->adsarea.area.lpdbOrdCondInfo ) + if( pArea->adsarea.area.lpdbOrdCondInfo ) { /* Test FOR expression */ if( pArea->adsarea.area.lpdbOrdCondInfo->abFor ) { bValidExpr = 0; AdsIsExprValid( pArea->adsarea.hTable, ( UNSIGNED8 * ) pArea->adsarea.area.lpdbOrdCondInfo->abFor, &bValidExpr ); - bUseADS = bValidExpr; + bForADS = bValidExpr; } else if( pArea->adsarea.area.lpdbOrdCondInfo->itmCobFor ) - { - bUseADS = HB_FALSE; - } + bForADS = HB_FALSE; /* Test WHILE expression */ - if( bUseADS ) + if( pArea->adsarea.area.lpdbOrdCondInfo->abWhile ) { - if( pArea->adsarea.area.lpdbOrdCondInfo->abWhile ) - { - bValidExpr = 0; - AdsIsExprValid( pArea->adsarea.hTable, ( UNSIGNED8 * ) pArea->adsarea.area.lpdbOrdCondInfo->abWhile, &bValidExpr ); - bUseADS = ( bValidExpr != 0 ); - } - else if( pArea->adsarea.area.lpdbOrdCondInfo->itmCobWhile ) - bUseADS = HB_FALSE; + bValidExpr = 0; + AdsIsExprValid( pArea->adsarea.hTable, ( UNSIGNED8 * ) pArea->adsarea.area.lpdbOrdCondInfo->abWhile, &bValidExpr ); + bWhileADS = bValidExpr; } + else if( pArea->adsarea.area.lpdbOrdCondInfo->itmCobWhile ) + bWhileADS = HB_FALSE; } - if( bUseADS ) + if( bKeyADS && bForADS && bWhileADS ) { return SUPER_ORDCREATE( ( AREAP ) pArea, pOrderInfo ); } + if( pArea->adsarea.area.lpdbOrdCondInfo && + ( bForADS && pArea->adsarea.area.lpdbOrdCondInfo->abFor || + bWhileADS && pArea->adsarea.area.lpdbOrdCondInfo->abWhile ) ) + { + /* We can use server side indexing to filter records. This improves speed */ + UNSIGNED32 u32RetVal; + UNSIGNED8 szKeyExpr[ 1024 ]; + UNSIGNED16 usLen = sizeof( szKeyExpr ); + + if( pArea->adsarea.area.lpdbOrdCondInfo->fUseCurrent && pArea->adsarea.hOrdCurrent ) + { + AdsGetIndexExpr( pArea->adsarea.hOrdCurrent, szKeyExpr, &usLen ); + } + else + szKeyExpr[ 0 ] = '\0'; + + u32RetVal = AdsCreateIndex61( + pArea->adsarea.area.lpdbOrdCondInfo->fUseCurrent ? pArea->adsarea.hOrdCurrent : pArea->adsarea.hTable, + ( UNSIGNED8 * ) pOrderInfo->abBagName, + ( UNSIGNED8 * ) pOrderInfo->atomBagName, + szKeyExpr[ 0 ] ? ( UNSIGNED8 * ) szKeyExpr : ( UNSIGNED8 * ) "1", + ( UNSIGNED8 * ) ( ( bForADS && pArea->adsarea.area.lpdbOrdCondInfo->abFor ) ? pArea->adsarea.area.lpdbOrdCondInfo->abFor : NULL ), + ( UNSIGNED8 * ) ( ( bWhileADS && pArea->adsarea.area.lpdbOrdCondInfo->abWhile ) ? pArea->adsarea.area.lpdbOrdCondInfo->abWhile : NULL ), + ADS_COMPOUND, ADS_DEFAULT, &hIndex ); + + if( u32RetVal != AE_SUCCESS ) + { + hb_mixErrorRT( pArea, EG_CREATE, ( HB_ERRCODE ) u32RetVal, pOrderInfo->atomBagName, 0, 0 ); + return HB_FAILURE; + } + + pArea->adsarea.area.lpdbOrdCondInfo->fUseCurrent = HB_TRUE; + + /* If while condition is already used, remove it from OrdCondInfo */ + if( bWhileADS && pArea->adsarea.area.lpdbOrdCondInfo->abWhile ) + { + hb_xfree( pArea->adsarea.area.lpdbOrdCondInfo->abWhile ); + pArea->adsarea.area.lpdbOrdCondInfo->abWhile = NULL; + if( pArea->adsarea.area.lpdbOrdCondInfo->itmCobWhile ) + { + hb_itemRelease( pArea->adsarea.area.lpdbOrdCondInfo->itmCobWhile ); + pArea->adsarea.area.lpdbOrdCondInfo->itmCobWhile = NULL; + } + if( pArea->adsarea.area.lpdbOrdCondInfo->itmStartRecID ) + { + hb_itemRelease( pArea->adsarea.area.lpdbOrdCondInfo->itmStartRecID ); + pArea->adsarea.area.lpdbOrdCondInfo->itmStartRecID = NULL; + } + pArea->adsarea.area.lpdbOrdCondInfo->fRest = HB_FALSE; + } + } + /* Obtain key codeblock */ if( pOrderInfo->itmCobExpr ) { @@ -1141,7 +1189,11 @@ static HB_ERRCODE adsxOrderCreate( ADSXAREAP pArea, LPDBORDERCREATEINFO pOrderIn else { if( SELF_COMPILE( ( AREAP ) pArea, hb_itemGetCPtr( pOrderInfo->abExpr ) ) == HB_FAILURE ) + { + if( hIndex ) + AdsDeleteIndex( hIndex ); return HB_FAILURE; + } pKeyItem = pArea->adsarea.area.valResult; pArea->adsarea.area.valResult = NULL; } @@ -1151,6 +1203,8 @@ static HB_ERRCODE adsxOrderCreate( ADSXAREAP pArea, LPDBORDERCREATEINFO pOrderIn SELF_GOTO( ( AREAP ) pArea, 0 ); if( SELF_EVALBLOCK( ( AREAP ) pArea, pKeyItem ) == HB_FAILURE ) { + if( hIndex ) + AdsDeleteIndex( hIndex ); hb_vmDestroyBlockOrMacro( pKeyItem ); SELF_GOTO( ( AREAP ) pArea, ulRecNo ); return HB_FAILURE; @@ -1194,6 +1248,8 @@ static HB_ERRCODE adsxOrderCreate( ADSXAREAP pArea, LPDBORDERCREATEINFO pOrderIn if( bType == 'U' || uiLen == 0 ) { + if( hIndex ) + AdsDeleteIndex( hIndex ); hb_vmDestroyBlockOrMacro( pKeyItem ); SELF_GOTO( ( AREAP ) pArea, ulRecNo ); hb_mixErrorRT( pArea, bType == 'U' ? EG_DATATYPE : EG_DATAWIDTH, 1026, NULL, 0, 0 ); @@ -1211,6 +1267,8 @@ static HB_ERRCODE adsxOrderCreate( ADSXAREAP pArea, LPDBORDERCREATEINFO pOrderIn { if( SELF_COMPILE( ( AREAP ) pArea, pArea->adsarea.area.lpdbOrdCondInfo->abFor ) == HB_FAILURE ) { + if( hIndex ) + AdsDeleteIndex( hIndex ); hb_vmDestroyBlockOrMacro( pKeyItem ); SELF_GOTO( ( AREAP ) pArea, ulRecNo ); return HB_FAILURE; @@ -1228,6 +1286,8 @@ static HB_ERRCODE adsxOrderCreate( ADSXAREAP pArea, LPDBORDERCREATEINFO pOrderIn { if( SELF_COMPILE( ( AREAP ) pArea, pArea->adsarea.area.lpdbOrdCondInfo->abWhile ) == HB_FAILURE ) { + if( hIndex ) + AdsDeleteIndex( hIndex ); hb_vmDestroyBlockOrMacro( pKeyItem ); if( pForItem ) hb_vmDestroyBlockOrMacro( pForItem ); @@ -1244,6 +1304,8 @@ static HB_ERRCODE adsxOrderCreate( ADSXAREAP pArea, LPDBORDERCREATEINFO pOrderIn { if( SELF_EVALBLOCK( ( AREAP ) pArea, pForItem ) == HB_FAILURE ) { + if( hIndex ) + AdsDeleteIndex( hIndex ); hb_vmDestroyBlockOrMacro( pKeyItem ); hb_vmDestroyBlockOrMacro( pForItem ); if( pWhileItem ) @@ -1253,6 +1315,8 @@ static HB_ERRCODE adsxOrderCreate( ADSXAREAP pArea, LPDBORDERCREATEINFO pOrderIn } if( hb_itemType( pArea->adsarea.area.valResult ) != HB_IT_LOGICAL ) { + if( hIndex ) + AdsDeleteIndex( hIndex ); hb_itemRelease( pArea->adsarea.area.valResult ); pArea->adsarea.area.valResult = 0; hb_vmDestroyBlockOrMacro( pKeyItem ); @@ -1271,9 +1335,17 @@ static HB_ERRCODE adsxOrderCreate( ADSXAREAP pArea, LPDBORDERCREATEINFO pOrderIn SELF_GOTO( ( AREAP ) pArea, ulRecNo ); + /* Set auxiliary index as current for subindexing */ + if( hIndex ) + pArea->adsarea.hOrdCurrent = hIndex; + pTagNew = mixTagCreate( pOrderInfo->atomBagName, pOrderInfo->abExpr, pKeyItem, pForItem, pWhileItem, bType, uiLen, pArea ); + pArea->adsarea.hOrdCurrent = 0; + if( hIndex ) + AdsDeleteIndex( hIndex ); + if( pWhileItem ) hb_vmDestroyBlockOrMacro( pWhileItem ); @@ -1289,10 +1361,7 @@ static HB_ERRCODE adsxOrderCreate( ADSXAREAP pArea, LPDBORDERCREATEINFO pOrderIn { pArea->pTagList = pTagNew; } - pArea->pTagCurrent = pTagNew; - pArea->adsarea.hOrdCurrent = 0; - return HB_SUCCESS; }