diff --git a/ChangeLog.txt b/ChangeLog.txt index ab5f602c61..583129cae0 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,27 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2013-05-29 08:53 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * src/vm/hashes.c + % changed sorting algorithm for hash arrays which keeps item order. + % do not resort hash arrays when KEEPORDER flag is cleared but use + existing internal index to create new order. + * changed the behavior of hb_hSort() function. Now for hash arrays + which keep item order it changes internal item pair position sorting + them. The sort order depends on binary and case sensitivity hash + array flags. + + * src/vm/hvm.c + ! for literal hash array with repeated keys store the last item + with the given key instead of the first one. It restores + previous behavior. + + * contrib/rddads/rddads.hbx + + added AdsSetIndexDirection() + + * contrib/rddads/adsfunc.c + ! fixed formatting of AdsSetIndexDirection() + 2013-05-28 01:59 UTC+0200 Tamas TEVESZ (ice extreme.hu) * src/vm/dynlibhb.c * Report dlopen() errors at HB_TR_LEVEL_DEBUG diff --git a/contrib/rddads/adsfunc.c b/contrib/rddads/adsfunc.c index 156f70452d..a2be9d3c3a 100644 --- a/contrib/rddads/adsfunc.c +++ b/contrib/rddads/adsfunc.c @@ -2170,7 +2170,7 @@ HB_FUNC( ADSRESTRUCTURETABLE ) #endif } -/* lSuccess := AdsCopyTableContent( szAliasDest [, nAdsFilterOption ] ) */ +/* AdsCopyTableContent( szAliasDest [, nAdsFilterOption ] ) -> lSuccess */ HB_FUNC( ADSCOPYTABLECONTENTS ) { #if ADS_LIB_VERSION >= 600 @@ -2420,21 +2420,19 @@ HB_FUNC( ADSDDDROPLINK ) #endif } -HB_FUNC( ADSSETINDEXDIRECTION ) +HB_FUNC( ADSSETINDEXDIRECTION ) { #if ADS_LIB_VERSION >= 900 ADSAREAP pArea = hb_adsGetWorkAreaPointer(); ADSHANDLE hIndex; - UNSIGNED32 nRet = 0 ; - + UNSIGNED32 nRet = 0; + if( pArea && HB_ISNUM( 1 ) ) { - hIndex = pArea->hOrdCurrent; - - nRet = AdsSetIndexDirection( hIndex, ( UNSIGNED16 ) hb_parni( 1 ) ); + hIndex = pArea->hOrdCurrent; + nRet = AdsSetIndexDirection( hIndex, ( UNSIGNED16 ) hb_parni( 1 ) ); } - - hb_retnl( nRet ); + hb_retnl( nRet ); #else hb_retnl( 0 ); #endif diff --git a/contrib/rddads/rddads.hbx b/contrib/rddads/rddads.hbx index 7a6b855248..b32972f040 100644 --- a/contrib/rddads/rddads.hbx +++ b/contrib/rddads/rddads.hbx @@ -151,6 +151,7 @@ DYNAMIC AdsSetDeleted DYNAMIC AdsSetEpoch DYNAMIC AdsSetExact DYNAMIC AdsSetFileType +DYNAMIC AdsSetIndexDirection DYNAMIC AdsSetRelKeyPos DYNAMIC AdsSetSearchPath DYNAMIC AdsSetServerType diff --git a/src/vm/hashes.c b/src/vm/hashes.c index 1e27993283..59b6da3112 100644 --- a/src/vm/hashes.c +++ b/src/vm/hashes.c @@ -208,32 +208,60 @@ static int hb_hashItemCmp( PHB_ITEM pKey1, PHB_ITEM pKey2, int iFlags ) } static void hb_hashResort( PHB_BASEHASH pBaseHash ) +{ + HB_SIZE nPos; + + for( nPos = 0; nPos < pBaseHash->nLen; ++nPos ) + { + HB_SIZE nFrom = pBaseHash->pnPos[ nPos ]; + + if( nFrom != nPos ) + { + HB_HASHPAIR pair; + memcpy( &pair, pBaseHash->pPairs + nPos, sizeof( HB_HASHPAIR ) ); + memcpy( pBaseHash->pPairs + nPos, pBaseHash->pPairs + nFrom, sizeof( HB_HASHPAIR ) ); + memcpy( pBaseHash->pPairs + nFrom, &pair, sizeof( HB_HASHPAIR ) ); + } + } +} + +static void hb_hashSortDo( PHB_BASEHASH pBaseHash ) { HB_SIZE nPos, nFrom; int iFlags = pBaseHash->iFlags; - /* The hash array is probably quite well sorted so this trivial - * algorithm is the most efficient one [druzus] - */ - if( pBaseHash->pnPos ) { for( nFrom = 1; nFrom < pBaseHash->nLen; ++nFrom ) { - nPos = nFrom; - while( nPos > 0 && hb_hashItemCmp( &pBaseHash->pPairs[ pBaseHash->pnPos[ nPos - 1 ] ].key, - &pBaseHash->pPairs[ pBaseHash->pnPos[ nPos ] ].key, - iFlags ) > 0 ) + PHB_ITEM pKey = &pBaseHash->pPairs[ pBaseHash->pnPos[ nFrom ] ].key; + HB_SIZE nLeft = 0, nRight = nFrom; + + while( nLeft < nRight ) { - HB_SIZE nTemp = pBaseHash->pnPos[ nPos - 1 ]; - pBaseHash->pnPos[ nPos - 1 ] = pBaseHash->pnPos[ nPos ]; - pBaseHash->pnPos[ nPos ] = nTemp; - --nPos; + HB_SIZE nMiddle = ( nLeft + nRight ) >> 1; + int i = hb_hashItemCmp( &pBaseHash->pPairs[ pBaseHash->pnPos[ nMiddle ] ].key, + pKey, iFlags ); + if( i > 0 ) + nRight = nMiddle; + else + nLeft = nMiddle + 1; + } + if( nLeft < nFrom ) + { + nRight = pBaseHash->pnPos[ nLeft ]; + memmove( pBaseHash->pnPos + nLeft, pBaseHash->pnPos + nLeft + 1, + ( nFrom - nLeft ) * sizeof( HB_SIZE ) ); + pBaseHash->pnPos[ nFrom ] = nRight; } } } else { + /* The hash array is probably quite well sorted so this trivial + * algorithm is the most efficient one [druzus] + */ + for( nFrom = 1; nFrom < pBaseHash->nLen; ++nFrom ) { nPos = nFrom; @@ -260,7 +288,7 @@ static HB_BOOL hb_hashFind( PHB_BASEHASH pBaseHash, PHB_ITEM pKey, HB_SIZE * pnP int i; if( iFlags & HB_HASH_RESORT ) - hb_hashResort( pBaseHash ); + hb_hashSortDo( pBaseHash ); nLeft = 0; nRight = pBaseHash->nLen; @@ -575,8 +603,13 @@ void hb_hashSort( PHB_ITEM pHash ) if( HB_IS_HASH( pHash ) ) { - if( pHash->item.asHash.value->iFlags & HB_HASH_RESORT ) - hb_hashResort( pHash->item.asHash.value ); + PHB_BASEHASH pBaseHash = pHash->item.asHash.value; + + if( pBaseHash->iFlags & HB_HASH_RESORT ) + hb_hashSortDo( pBaseHash ); + + if( pBaseHash->pnPos ) + hb_hashResort( pBaseHash ); } } @@ -1152,10 +1185,7 @@ void hb_hashClearFlags( PHB_ITEM pHash, int iFlags ) if( pHash->item.asHash.value->pnPos != NULL && ( pHash->item.asHash.value->iFlags & HB_HASH_KEEPORDER ) == 0 ) { - hb_xfree( pHash->item.asHash.value->pnPos ); - pHash->item.asHash.value->pnPos = NULL; - if( pHash->item.asHash.value->nSize ) - pHash->item.asHash.value->iFlags |= HB_HASH_RESORT; + hb_hashResort( pHash->item.asHash.value ); } } } diff --git a/src/vm/hvm.c b/src/vm/hvm.c index faf8c1504d..ffd87423d3 100644 --- a/src/vm/hvm.c +++ b/src/vm/hvm.c @@ -5457,7 +5457,7 @@ static void hb_vmHashGen( HB_SIZE nElements ) /* generates an nElements Hash and pKey = hb_stackItemFromTop( iPos++ ); pVal = hb_stackItemFromTop( iPos++ ); if( HB_IS_HASHKEY( pKey ) ) - hb_hashAddNew( pHash, pKey, pVal ); + hb_hashAdd( pHash, pKey, pVal ); else { hb_errRT_BASE( EG_BOUND, 1133, NULL, hb_langDGetErrorDesc( EG_ARRASSIGN ), 3, pHash, pKey, pVal );