From c19ebf700ead993d62714e4c1e579c3c7a17cedb Mon Sep 17 00:00:00 2001 From: Mindaugas Kavaliauskas Date: Tue, 30 Dec 2008 16:14:01 +0000 Subject: [PATCH] 2008-12-30 18:10 UTC+0200 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt) * harbour/include/hbapi.h * harbour/source/vm/arrays.c + added array preallocation * harbour/contrib/rddsql/sqlbase.c * harbour/contrib/rddsql/sqlmix.c * fixed a few compile time warnings --- harbour/ChangeLog | 9 +++++++++ harbour/contrib/rddsql/sqlbase.c | 2 +- harbour/contrib/rddsql/sqlmix.c | 3 ++- harbour/include/hbapi.h | 1 + harbour/source/vm/arrays.c | 26 +++++++++++++++++++++++--- 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 6668092a02..d763491a9f 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,15 @@ 2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) */ +2008-12-30 18:10 UTC+0200 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt) + * harbour/include/hbapi.h + * harbour/source/vm/arrays.c + + added array preallocation + + * harbour/contrib/rddsql/sqlbase.c + * harbour/contrib/rddsql/sqlmix.c + * fixed a few compile time warnings + 2008-12-30 12:02 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbcomp.h * harbour/include/hbcompdf.h diff --git a/harbour/contrib/rddsql/sqlbase.c b/harbour/contrib/rddsql/sqlbase.c index efa2c9e1f0..c0b6391c4d 100644 --- a/harbour/contrib/rddsql/sqlbase.c +++ b/harbour/contrib/rddsql/sqlbase.c @@ -506,7 +506,7 @@ static ERRCODE sqlbaseCreate( SQLBASEAREAP pArea, LPDBOPENINFO pOpenInfo ) pArea->ulConnection = pOpenInfo->ulConnection ? pOpenInfo->ulConnection : s_ulConnectionCurrent; - if ( pArea->ulConnection < 0 || pArea->ulConnection > s_ulConnectionCount || + if ( pArea->ulConnection > s_ulConnectionCount || ( pArea->ulConnection && ! s_pConnection[ pArea->ulConnection - 1 ].hConnection ) ) { hb_errRT_SQLBASE( EG_OPEN, ESQLDD_NOTCONNECTED, "Not connected", NULL ); diff --git a/harbour/contrib/rddsql/sqlmix.c b/harbour/contrib/rddsql/sqlmix.c index 9ad3d6e7e3..48253fbc2c 100644 --- a/harbour/contrib/rddsql/sqlmix.c +++ b/harbour/contrib/rddsql/sqlmix.c @@ -367,6 +367,7 @@ static int hb_mixKeyCompare( PMIXTAG pTag, PMIXKEY pKey1, PMIXKEY pKey2, UINT ui /* -------------------------- Tag management ---------------------------- */ /* hb_mixTag*() */ +/* This function is used for debugging purposes. Uncomment it, if you need it. static void hb_mixTagPrintNode( PMIXTAG pTag, PMIXNODE pNode, int iLevel ) { UINT i; @@ -400,7 +401,7 @@ static void hb_mixTagPrintNode( PMIXTAG pTag, PMIXNODE pNode, int iLevel ) hb_mixTagPrintNode( pTag, pNode->Child[ pNode->KeyCount ], iLevel + 1 ); } } - +*/ static PMIXNODE hb_mixTagCreateNode( PMIXTAG pTag, BOOL fLeaf ) { diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index cb262fe61f..dd6e940308 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -390,6 +390,7 @@ typedef struct _HB_BASEARRAY { PHB_ITEM pItems; /* pointer to the array items */ ULONG ulLen; /* number of items in the array */ + ULONG ulAllocated; /* number of allocated items */ USHORT uiClass; /* offset to the classes base if it is an object */ USHORT uiPrevCls; /* for fixing after access super */ } HB_BASEARRAY, * PHB_BASEARRAY, * HB_BASEARRAY_PTR; diff --git a/harbour/source/vm/arrays.c b/harbour/source/vm/arrays.c index ff5616d7ea..22cdce48b3 100644 --- a/harbour/source/vm/arrays.c +++ b/harbour/source/vm/arrays.c @@ -183,7 +183,7 @@ BOOL hb_arrayNew( PHB_ITEM pItem, ULONG ulLen ) /* creates a new array */ pBaseArray->ulLen = ulLen; pBaseArray->uiClass = 0; pBaseArray->uiPrevCls = 0; - + pBaseArray->ulAllocated= ulLen; pItem->type = HB_IT_ARRAY; pItem->item.asArray.value = pBaseArray; @@ -205,6 +205,7 @@ BOOL hb_arraySize( PHB_ITEM pArray, ULONG ulLen ) if( pBaseArray->ulLen == 0 ) { pBaseArray->pItems = ( PHB_ITEM ) hb_xgrab( ulLen * sizeof( HB_ITEM ) ); + pBaseArray->ulAllocated = ulLen; for( ulPos = 0; ulPos < ulLen; ulPos++ ) ( pBaseArray->pItems + ulPos )->type = HB_IT_NIL; @@ -213,7 +214,23 @@ BOOL hb_arraySize( PHB_ITEM pArray, ULONG ulLen ) { if( pBaseArray->ulLen < ulLen ) { - pBaseArray->pItems = ( PHB_ITEM ) hb_xrealloc( pBaseArray->pItems, sizeof( HB_ITEM ) * ulLen ); + + if( pBaseArray->ulAllocated < ulLen ) + { + /* + A common practice is to double allocation buffer size. Thus, making + reallocation count logarithmic to total number of added numbers. + I've used here a little different formula. ulAllocated is divided by + factor 2 ( >> 1 ) and 1 is added to requested size. This algorithm + has properties: + - reallocation count remains asymptoticaly logarithmic; + - saves memory for large arrays, because reallocation buffer + size is not doubled, but multiplied by 1.5; + - adding of 1, allows reduce reallocation count for small arrays. + */ + pBaseArray->ulAllocated = ( pBaseArray->ulAllocated >> 1 ) + 1 + ulLen; + pBaseArray->pItems = ( PHB_ITEM ) hb_xrealloc( pBaseArray->pItems, sizeof( HB_ITEM ) * pBaseArray->ulAllocated ); + } /* set value for new items */ for( ulPos = pBaseArray->ulLen; ulPos < ulLen; ulPos++ ) @@ -233,8 +250,11 @@ BOOL hb_arraySize( PHB_ITEM pArray, ULONG ulLen ) hb_xfree( pBaseArray->pItems ); pBaseArray->pItems = NULL; } - else + else if( ulLen < ( pBaseArray->ulAllocated >> 1 ) ) + { + pBaseArray->ulAllocated = ulLen; pBaseArray->pItems = ( PHB_ITEM ) hb_xrealloc( pBaseArray->pItems, sizeof( HB_ITEM ) * ulLen ); + } } }