summaryrefslogtreecommitdiff
path: root/qmake/tools/qgarray.cpp
Side-by-side diff
Diffstat (limited to 'qmake/tools/qgarray.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qgarray.cpp97
1 files changed, 80 insertions, 17 deletions
diff --git a/qmake/tools/qgarray.cpp b/qmake/tools/qgarray.cpp
index 45c45ce..0a522e4 100644
--- a/qmake/tools/qgarray.cpp
+++ b/qmake/tools/qgarray.cpp
@@ -32,27 +32,37 @@
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
-#include "qglobal.h" // needed to define Q_WS_WIN
-#ifdef Q_WS_WIN
-#include "qt_windows.h" // needed for bsearch on some platforms
+#include "qglobal.h"
+#if defined(Q_CC_BOR)
+ // needed for qsort() because of a std namespace problem on Borland
+# include "qplatformdefs.h"
+#elif defined(Q_WS_WIN)
+ // needed for bsearch on some platforms
+# include "qt_windows.h"
#endif
#define QGARRAY_CPP
#include "qgarray.h"
#include <stdlib.h>
#include <string.h>
#ifdef QT_THREAD_SUPPORT
# include <private/qmutexpool_p.h>
#endif // QT_THREAD_SUPPORT
-#define USE_MALLOC // comment to use new/delete
+/*
+ If USE_MALLOC isn't defined, we use new[] and delete[] to allocate
+ memory. The documentation for QMemArray<T>::assign() explicitly
+ mentions that the array is freed using free(), so don't mess around
+ with USE_MALLOC unless you know what you're doing.
+*/
+#define USE_MALLOC
#undef NEW
#undef DELETE
#if defined(USE_MALLOC)
#define NEW(type,size) ((type*)malloc(size*sizeof(type)))
@@ -132,13 +142,17 @@ QGArray::QGArray( int size )
shd = newData();
Q_CHECK_PTR( shd );
if ( size == 0 ) // zero length
return;
shd->data = NEW(char,size);
Q_CHECK_PTR( shd->data );
- shd->len = size;
+ shd->len =
+#ifdef QT_QGARRAY_SPEED_OPTIM
+ shd->maxl =
+#endif
+ size;
}
/*!
Constructs a shallow copy of \a a.
*/
@@ -209,41 +223,76 @@ bool QGArray::isEqual( const QGArray &a ) const
return TRUE;
return (size() ? memcmp( data(), a.data(), size() ) : 0) == 0;
}
/*!
- Resizes the array to \a newsize bytes.
+ Resizes the array to \a newsize bytes. \a optim is either
+ MemOptim (the default) or SpeedOptim.
*/
-
-bool QGArray::resize( uint newsize )
+bool QGArray::resize( uint newsize, Optimization optim )
{
- if ( newsize == shd->len ) // nothing to do
+#ifndef QT_QGARRAY_SPEED_OPTIM
+ Q_UNUSED(optim);
+#endif
+
+ if ( newsize == shd->len
+#ifdef QT_QGARRAY_SPEED_OPTIM
+ && newsize == shd->maxl
+#endif
+ ) // nothing to do
return TRUE;
if ( newsize == 0 ) { // remove array
duplicate( 0, 0 );
return TRUE;
}
+
+ uint newmaxl = newsize;
+#ifdef QT_QGARRAY_SPEED_OPTIM
+ if ( optim == SpeedOptim ) {
+ if ( newsize <= shd->maxl &&
+ ( newsize * 4 > shd->maxl || shd->maxl <= 4 ) ) {
+ shd->len = newsize;
+ return TRUE;
+ }
+ newmaxl = 4;
+ while ( newmaxl < newsize )
+ newmaxl *= 2;
+ // try to spare some memory
+ if ( newmaxl >= 1024 * 1024 && newsize <= newmaxl - (newmaxl >> 2) )
+ newmaxl -= newmaxl >> 2;
+ }
+ shd->maxl = newmaxl;
+#endif
+
if ( shd->data ) { // existing data
#if defined(DONT_USE_REALLOC)
char *newdata = NEW(char,newsize); // manual realloc
- memcpy( newdata, shd->data, QMIN(shd->len,newsize) );
+ memcpy( newdata, shd->data, QMIN(shd->len,newmaxl) );
DELETE(shd->data);
shd->data = newdata;
#else
- shd->data = (char *)realloc( shd->data, newsize );
+ shd->data = (char *)realloc( shd->data, newmaxl );
#endif
} else {
- shd->data = NEW(char,newsize);
+ shd->data = NEW(char,newmaxl);
}
if ( !shd->data ) // no memory
return FALSE;
shd->len = newsize;
return TRUE;
}
+/*!\overload
+*/
+bool QGArray::resize( uint newsize )
+{
+ return resize( newsize, MemOptim );
+}
+
+
/*!
Fills the array with the repeated occurrences of \a d, which is
\a sz bytes long.
If \a len is specified as different from -1, then the array will be
resized to \a len*sz before it is filled.
@@ -316,13 +365,17 @@ QGArray &QGArray::assign( const char *d, uint len )
Q_CHECK_PTR( shd );
} else {
if ( shd->data )
DELETE(shd->data);
}
shd->data = (char *)d;
- shd->len = len;
+ shd->len =
+#ifdef QT_QGARRAY_SPEED_OPTIM
+ shd->maxl =
+#endif
+ len;
return *this;
}
/*!
Deep copy. Dereference the current array and obtains a copy of the data
contained in \a a instead. Returns a reference to this array.
@@ -361,13 +414,17 @@ QGArray &QGArray::duplicate( const QGArray &a )
Q_CHECK_PTR( shd->data );
if ( shd->data )
memcpy( shd->data, a.shd->data, a.shd->len );
} else {
shd->data = 0;
}
- shd->len = a.shd->len;
+ shd->len =
+#ifdef QT_QGARRAY_SPEED_OPTIM
+ shd->maxl =
+#endif
+ a.shd->len;
if ( oldptr )
DELETE(oldptr);
return *this;
}
/*!
@@ -399,13 +456,17 @@ QGArray &QGArray::duplicate( const char *d, uint len )
Q_CHECK_PTR( shd );
} else { // just a single reference
if ( shd->data )
DELETE(shd->data);
}
shd->data = data;
- shd->len = len;
+ shd->len =
+#ifdef QT_QGARRAY_SPEED_OPTIM
+ shd->maxl =
+#endif
+ len;
return *this;
}
/*!
Resizes this array to \a len bytes and copies the \a len bytes at
address \a d into it.
@@ -656,13 +717,14 @@ void QGArray::sort( uint sz )
{
int numItems = size() / sz;
if ( numItems < 2 )
return;
#ifdef QT_THREAD_SUPPORT
- QMutexLocker locker( qt_global_mutexpool->get( &cmp_item_size ) );
+ QMutexLocker locker( qt_global_mutexpool ?
+ qt_global_mutexpool->get( &cmp_item_size ) : 0 );
#endif // QT_THREAD_SUPPORT
cmp_item_size = sz;
qsort( shd->data, numItems, sz, cmp_arr );
}
@@ -674,13 +736,14 @@ int QGArray::bsearch( const char *d, uint sz ) const
{
int numItems = size() / sz;
if ( !numItems )
return -1;
#ifdef QT_THREAD_SUPPORT
- QMutexLocker locker( qt_global_mutexpool->get( &cmp_item_size ) );
+ QMutexLocker locker( qt_global_mutexpool ?
+ qt_global_mutexpool->get( &cmp_item_size ) : 0 );
#endif // QT_THREAD_SUPPORT
cmp_item_size = sz;
char* r = (char*)::bsearch( d, shd->data, numItems, sz, cmp_arr );
if ( !r )
return -1;