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()
This commit is contained in:
Przemysław Czerpak
2013-05-29 08:53:45 +02:00
parent b6ad77f6e3
commit c27bb280a0
5 changed files with 79 additions and 29 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -151,6 +151,7 @@ DYNAMIC AdsSetDeleted
DYNAMIC AdsSetEpoch
DYNAMIC AdsSetExact
DYNAMIC AdsSetFileType
DYNAMIC AdsSetIndexDirection
DYNAMIC AdsSetRelKeyPos
DYNAMIC AdsSetSearchPath
DYNAMIC AdsSetServerType

View File

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

View File

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