diff --git a/harbour/ChangeLog b/harbour/ChangeLog index a1ec31dea9..e97ee59c6a 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,25 @@ The license applies to all entries newer than 2009-04-28. */ +2012-01-27 18:25 UTC+0200 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt) + * src/vm/hashes.c + * src/vm/hashfunc.c + + implemented posibility to use hashes a sorted arays with binary search. + + Implemented HB_BOOL hb_hashScanSoft( pHash, pKey, &nPos ). Function + if similar to, but returns nPos even if pKey is not found in pHash. + + Extended HB_HHASKEY( aHash, xKey [, @nPos ] ) --> lFound + Function optionaly returns position of the item with a largest key + smaller or equal to xKey. If xKey is less than all keys in hash, + zero position is returned. I.e., + aHash := {10=>, 20=>} + ? HB_HHASKEY( aHash, 5, @nPos ), nPos // .F. 0 + ? HB_HHASKEY( aHash, 10, @nPos ), nPos // .T. 1 + ? HB_HHASKEY( aHash, 15, @nPos ), nPos // .F. 1 + ? HB_HHASKEY( aHash, 20, @nPos ), nPos // .T. 2 + ? HB_HHASKEY( aHash, 25, @nPos ), nPos // .F. 2 + 2012-01-27 13:34 UTC+0100 Viktor Szakats (harbour syenar.net) * INSTALL * deleted announcement mailing list. pls recreate with new owner diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index f860adcd79..c2e5d1611e 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -871,6 +871,7 @@ extern HB_EXPORT PHB_ITEM hb_hashClone( PHB_ITEM pHash ); extern HB_EXPORT PHB_ITEM hb_hashCloneTo( PHB_ITEM pDest, PHB_ITEM pHash ); extern HB_EXPORT void hb_hashJoin( PHB_ITEM pDest, PHB_ITEM pSource, int iType ); extern HB_EXPORT HB_BOOL hb_hashScan( PHB_ITEM pHash, PHB_ITEM pKey, HB_SIZE * pnPos ); +extern HB_EXPORT HB_BOOL hb_hashScanSoft( PHB_ITEM pHash, PHB_ITEM pKey, HB_SIZE * pnPos ); extern HB_EXPORT void hb_hashPreallocate( PHB_ITEM pHash, HB_SIZE nNewSize ); extern HB_EXPORT PHB_ITEM hb_hashGetKeys( PHB_ITEM pHash ); extern HB_EXPORT PHB_ITEM hb_hashGetValues( PHB_ITEM pHash ); diff --git a/harbour/src/vm/hashes.c b/harbour/src/vm/hashes.c index 5059628958..e3426f39fc 100644 --- a/harbour/src/vm/hashes.c +++ b/harbour/src/vm/hashes.c @@ -719,6 +719,35 @@ HB_BOOL hb_hashScan( PHB_ITEM pHash, PHB_ITEM pKey, HB_SIZE * pnPos ) return HB_FALSE; } +HB_BOOL hb_hashScanSoft( PHB_ITEM pHash, PHB_ITEM pKey, HB_SIZE * pnPos ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_hashScanSoft(%p,%p,%p)", pHash, pKey, pnPos)); + + if( HB_IS_HASH( pHash ) && HB_IS_HASHKEY( pKey ) ) + { + HB_SIZE nPos; + if( hb_hashFind( pHash->item.asHash.value, pKey, &nPos ) ) + { + if( pnPos ) + *pnPos = nPos + 1; + return HB_TRUE; + } + else + { + if( pnPos ) + { + if( nPos != 0 && pHash->item.asHash.value->pnPos ) + nPos = pHash->item.asHash.value->pnPos[ nPos - 1 ] + 1; + *pnPos = nPos; + } + return HB_FALSE; + } + } + if( pnPos ) + *pnPos = 0; + return HB_FALSE; +} + HB_BOOL hb_hashClear( PHB_ITEM pHash ) { HB_TRACE(HB_TR_DEBUG, ("hb_hashClear(%p)", pHash)); diff --git a/harbour/src/vm/hashfunc.c b/harbour/src/vm/hashfunc.c index 55c9250455..f28911e743 100644 --- a/harbour/src/vm/hashfunc.c +++ b/harbour/src/vm/hashfunc.c @@ -89,7 +89,11 @@ HB_FUNC( HB_HHASKEY ) PHB_ITEM pKey = hb_param( 2, HB_IT_HASHKEY ); if( pHash && pKey ) - hb_retl( hb_hashScan( pHash, pKey, NULL ) ); + { + HB_SIZE nPos; + hb_retl( hb_hashScanSoft( pHash, pKey, &nPos ) ); + hb_storns( nPos, 3 ); + } else hb_errRT_BASE( EG_ARG, 1123, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); }