Mostly changes to GArray code. See ChangeLog.

This commit is contained in:
Manish Singh
1998-09-02 07:44:02 +00:00
parent b420fa8418
commit 7401460a60
18 changed files with 874 additions and 600 deletions

View File

@@ -1,3 +1,33 @@
Tue Sep 1 23:46:31 1998 Josh MacDonald <jmacd@axis.hip.berkeley.edu>
* testglib.c (main): Update the array tests. Reduce the number of
iterations for the prepend test from 10000 to 100 since it is
O(n^2) and was taking longer than I would like to wait.
* garray.c: I've worked on the GArray interface, mostly. It was
seriously broken before and I hate to do it, but this is going to
break some code. It is important to do this now, because more and
more people are starting to use glib and the interface was both
broken and inconsistent. First, rename the _truncate functions of
both the GArray and GPtrArray classes to _set_size, since this
function can also be used to extend the arrays. GArray now
accepts two more initialization arguments: clear and element_size.
Instead of providing the type to each access function, the array
now stores the element size. Clear, if set, causes the library to
zero element's memory as the array expands. The major broken-ness
here was that array->len was in bytes, not elements. Now, since
the array knows its element size, array->len is correct and I have
removed the g_array_length macro. The only macro which now
accepts the type as an argument is g_array_index, which casts the
element to the right type--this interface does not change. The
append and prepend functions simply need the types removed.
g_ptr_array_remove_index now returns the removed element.
* gprimes.c (g_spaced_primes_closest): Move this function out of
ghash.c and rename it from g_hash_closest_prime. Fix the primes
so that they are actually prime (they weren't all -- isn't that
nice?).
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:

View File

@@ -1,3 +1,33 @@
Tue Sep 1 23:46:31 1998 Josh MacDonald <jmacd@axis.hip.berkeley.edu>
* testglib.c (main): Update the array tests. Reduce the number of
iterations for the prepend test from 10000 to 100 since it is
O(n^2) and was taking longer than I would like to wait.
* garray.c: I've worked on the GArray interface, mostly. It was
seriously broken before and I hate to do it, but this is going to
break some code. It is important to do this now, because more and
more people are starting to use glib and the interface was both
broken and inconsistent. First, rename the _truncate functions of
both the GArray and GPtrArray classes to _set_size, since this
function can also be used to extend the arrays. GArray now
accepts two more initialization arguments: clear and element_size.
Instead of providing the type to each access function, the array
now stores the element size. Clear, if set, causes the library to
zero element's memory as the array expands. The major broken-ness
here was that array->len was in bytes, not elements. Now, since
the array knows its element size, array->len is correct and I have
removed the g_array_length macro. The only macro which now
accepts the type as an argument is g_array_index, which casts the
element to the right type--this interface does not change. The
append and prepend functions simply need the types removed.
g_ptr_array_remove_index now returns the removed element.
* gprimes.c (g_spaced_primes_closest): Move this function out of
ghash.c and rename it from g_hash_closest_prime. Fix the primes
so that they are actually prime (they weren't all -- isn't that
nice?).
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:

View File

@@ -1,3 +1,33 @@
Tue Sep 1 23:46:31 1998 Josh MacDonald <jmacd@axis.hip.berkeley.edu>
* testglib.c (main): Update the array tests. Reduce the number of
iterations for the prepend test from 10000 to 100 since it is
O(n^2) and was taking longer than I would like to wait.
* garray.c: I've worked on the GArray interface, mostly. It was
seriously broken before and I hate to do it, but this is going to
break some code. It is important to do this now, because more and
more people are starting to use glib and the interface was both
broken and inconsistent. First, rename the _truncate functions of
both the GArray and GPtrArray classes to _set_size, since this
function can also be used to extend the arrays. GArray now
accepts two more initialization arguments: clear and element_size.
Instead of providing the type to each access function, the array
now stores the element size. Clear, if set, causes the library to
zero element's memory as the array expands. The major broken-ness
here was that array->len was in bytes, not elements. Now, since
the array knows its element size, array->len is correct and I have
removed the g_array_length macro. The only macro which now
accepts the type as an argument is g_array_index, which casts the
element to the right type--this interface does not change. The
append and prepend functions simply need the types removed.
g_ptr_array_remove_index now returns the removed element.
* gprimes.c (g_spaced_primes_closest): Move this function out of
ghash.c and rename it from g_hash_closest_prime. Fix the primes
so that they are actually prime (they weren't all -- isn't that
nice?).
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:

View File

@@ -1,3 +1,33 @@
Tue Sep 1 23:46:31 1998 Josh MacDonald <jmacd@axis.hip.berkeley.edu>
* testglib.c (main): Update the array tests. Reduce the number of
iterations for the prepend test from 10000 to 100 since it is
O(n^2) and was taking longer than I would like to wait.
* garray.c: I've worked on the GArray interface, mostly. It was
seriously broken before and I hate to do it, but this is going to
break some code. It is important to do this now, because more and
more people are starting to use glib and the interface was both
broken and inconsistent. First, rename the _truncate functions of
both the GArray and GPtrArray classes to _set_size, since this
function can also be used to extend the arrays. GArray now
accepts two more initialization arguments: clear and element_size.
Instead of providing the type to each access function, the array
now stores the element size. Clear, if set, causes the library to
zero element's memory as the array expands. The major broken-ness
here was that array->len was in bytes, not elements. Now, since
the array knows its element size, array->len is correct and I have
removed the g_array_length macro. The only macro which now
accepts the type as an argument is g_array_index, which casts the
element to the right type--this interface does not change. The
append and prepend functions simply need the types removed.
g_ptr_array_remove_index now returns the removed element.
* gprimes.c (g_spaced_primes_closest): Move this function out of
ghash.c and rename it from g_hash_closest_prime. Fix the primes
so that they are actually prime (they weren't all -- isn't that
nice?).
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:

View File

@@ -1,3 +1,33 @@
Tue Sep 1 23:46:31 1998 Josh MacDonald <jmacd@axis.hip.berkeley.edu>
* testglib.c (main): Update the array tests. Reduce the number of
iterations for the prepend test from 10000 to 100 since it is
O(n^2) and was taking longer than I would like to wait.
* garray.c: I've worked on the GArray interface, mostly. It was
seriously broken before and I hate to do it, but this is going to
break some code. It is important to do this now, because more and
more people are starting to use glib and the interface was both
broken and inconsistent. First, rename the _truncate functions of
both the GArray and GPtrArray classes to _set_size, since this
function can also be used to extend the arrays. GArray now
accepts two more initialization arguments: clear and element_size.
Instead of providing the type to each access function, the array
now stores the element size. Clear, if set, causes the library to
zero element's memory as the array expands. The major broken-ness
here was that array->len was in bytes, not elements. Now, since
the array knows its element size, array->len is correct and I have
removed the g_array_length macro. The only macro which now
accepts the type as an argument is g_array_index, which casts the
element to the right type--this interface does not change. The
append and prepend functions simply need the types removed.
g_ptr_array_remove_index now returns the removed element.
* gprimes.c (g_spaced_primes_closest): Move this function out of
ghash.c and rename it from g_hash_closest_prime. Fix the primes
so that they are actually prime (they weren't all -- isn't that
nice?).
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:

View File

@@ -1,3 +1,33 @@
Tue Sep 1 23:46:31 1998 Josh MacDonald <jmacd@axis.hip.berkeley.edu>
* testglib.c (main): Update the array tests. Reduce the number of
iterations for the prepend test from 10000 to 100 since it is
O(n^2) and was taking longer than I would like to wait.
* garray.c: I've worked on the GArray interface, mostly. It was
seriously broken before and I hate to do it, but this is going to
break some code. It is important to do this now, because more and
more people are starting to use glib and the interface was both
broken and inconsistent. First, rename the _truncate functions of
both the GArray and GPtrArray classes to _set_size, since this
function can also be used to extend the arrays. GArray now
accepts two more initialization arguments: clear and element_size.
Instead of providing the type to each access function, the array
now stores the element size. Clear, if set, causes the library to
zero element's memory as the array expands. The major broken-ness
here was that array->len was in bytes, not elements. Now, since
the array knows its element size, array->len is correct and I have
removed the g_array_length macro. The only macro which now
accepts the type as an argument is g_array_index, which casts the
element to the right type--this interface does not change. The
append and prepend functions simply need the types removed.
g_ptr_array_remove_index now returns the removed element.
* gprimes.c (g_spaced_primes_closest): Move this function out of
ghash.c and rename it from g_hash_closest_prime. Fix the primes
so that they are actually prime (they weren't all -- isn't that
nice?).
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:

View File

@@ -1,3 +1,33 @@
Tue Sep 1 23:46:31 1998 Josh MacDonald <jmacd@axis.hip.berkeley.edu>
* testglib.c (main): Update the array tests. Reduce the number of
iterations for the prepend test from 10000 to 100 since it is
O(n^2) and was taking longer than I would like to wait.
* garray.c: I've worked on the GArray interface, mostly. It was
seriously broken before and I hate to do it, but this is going to
break some code. It is important to do this now, because more and
more people are starting to use glib and the interface was both
broken and inconsistent. First, rename the _truncate functions of
both the GArray and GPtrArray classes to _set_size, since this
function can also be used to extend the arrays. GArray now
accepts two more initialization arguments: clear and element_size.
Instead of providing the type to each access function, the array
now stores the element size. Clear, if set, causes the library to
zero element's memory as the array expands. The major broken-ness
here was that array->len was in bytes, not elements. Now, since
the array knows its element size, array->len is correct and I have
removed the g_array_length macro. The only macro which now
accepts the type as an argument is g_array_index, which casts the
element to the right type--this interface does not change. The
append and prepend functions simply need the types removed.
g_ptr_array_remove_index now returns the removed element.
* gprimes.c (g_spaced_primes_closest): Move this function out of
ghash.c and rename it from g_hash_closest_prime. Fix the primes
so that they are actually prime (they weren't all -- isn't that
nice?).
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:

View File

@@ -1,3 +1,33 @@
Tue Sep 1 23:46:31 1998 Josh MacDonald <jmacd@axis.hip.berkeley.edu>
* testglib.c (main): Update the array tests. Reduce the number of
iterations for the prepend test from 10000 to 100 since it is
O(n^2) and was taking longer than I would like to wait.
* garray.c: I've worked on the GArray interface, mostly. It was
seriously broken before and I hate to do it, but this is going to
break some code. It is important to do this now, because more and
more people are starting to use glib and the interface was both
broken and inconsistent. First, rename the _truncate functions of
both the GArray and GPtrArray classes to _set_size, since this
function can also be used to extend the arrays. GArray now
accepts two more initialization arguments: clear and element_size.
Instead of providing the type to each access function, the array
now stores the element size. Clear, if set, causes the library to
zero element's memory as the array expands. The major broken-ness
here was that array->len was in bytes, not elements. Now, since
the array knows its element size, array->len is correct and I have
removed the g_array_length macro. The only macro which now
accepts the type as an argument is g_array_index, which casts the
element to the right type--this interface does not change. The
append and prepend functions simply need the types removed.
g_ptr_array_remove_index now returns the removed element.
* gprimes.c (g_spaced_primes_closest): Move this function out of
ghash.c and rename it from g_hash_closest_prime. Fix the primes
so that they are actually prime (they weren't all -- isn't that
nice?).
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:

106
garray.c
View File

@@ -30,7 +30,9 @@ struct _GRealArray
guint8 *data;
guint len;
guint alloc;
guint zero_terminated;
guint elt_size;
guint zero_terminated : 1;
guint clear : 1;
};
@@ -43,7 +45,9 @@ static GMemChunk *array_mem_chunk = NULL;
GArray*
g_array_new (gboolean zero_terminated)
g_array_new (gboolean zero_terminated,
gboolean clear,
guint elt_size)
{
GRealArray *array;
@@ -54,10 +58,12 @@ g_array_new (gboolean zero_terminated)
array = g_chunk_new (GRealArray, array_mem_chunk);
array->data = NULL;
array->len = 0;
array->alloc = 0;
array->data = NULL;
array->len = 0;
array->alloc = 0;
array->zero_terminated = (zero_terminated ? 1 : 0);
array->clear = (clear ? 1 : 0);
array->elt_size = elt_size;
return (GArray*) array;
}
@@ -73,45 +79,52 @@ g_array_free (GArray *array,
}
GArray*
g_rarray_append (GArray *array,
gpointer data,
gint size)
g_array_append_vals (GArray *farray,
gpointer data,
guint len)
{
g_array_maybe_expand ((GRealArray*) array, size);
GRealArray *array = (GRealArray*) farray;
memcpy (array->data + array->len, data, size);
g_array_maybe_expand (array, len);
array->len += size;
memcpy (array->data + array->elt_size * array->len, data, array->elt_size * len);
return array;
array->len += len;
return farray;
}
GArray*
g_rarray_prepend (GArray *array,
gpointer data,
gint size)
g_array_prepend_vals (GArray *farray,
gpointer data,
guint len)
{
g_array_maybe_expand ((GRealArray*) array, size);
GRealArray *array = (GRealArray*) farray;
g_memmove (array->data + size, array->data, array->len);
memcpy (array->data, data, size);
g_array_maybe_expand (array, len);
array->len += size;
g_memmove (array->data + array->elt_size * len, array->data, array->elt_size * array->len);
return array;
memcpy (array->data, data, len * array->elt_size);
array->len += len;
return farray;
}
GArray*
g_rarray_truncate (GArray *array,
gint length,
gint size)
g_array_set_size (GArray *farray,
guint length)
{
if (array->data)
memset (array->data + length * size, 0, size);
array->len = length * size;
return array;
}
GRealArray *array = (GRealArray*) farray;
if (array->len < length)
g_array_maybe_expand (array, length - array->len);
array->len = length;
return farray;
}
static gint
g_nearest_pow (gint num)
@@ -128,17 +141,19 @@ static void
g_array_maybe_expand (GRealArray *array,
gint len)
{
guint old_alloc;
guint want_alloc = (array->len + len + array->zero_terminated) * array->elt_size;
if ((array->len + len) > array->alloc)
if (want_alloc > array->alloc)
{
old_alloc = array->alloc;
guint old_alloc = array->alloc;
array->alloc = g_nearest_pow (array->len + array->zero_terminated + len);
array->alloc = g_nearest_pow (want_alloc);
array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
array->data = g_realloc (array->data, array->alloc);
memset (array->data + old_alloc, 0, array->alloc - old_alloc);
if (array->clear || array->zero_terminated)
memset (array->data + old_alloc, 0, array->alloc - old_alloc);
}
}
@@ -228,21 +243,26 @@ g_ptr_array_set_size (GPtrArray *farray,
array->len = length;
}
void
gpointer
g_ptr_array_remove_index (GPtrArray* farray,
gint index)
{
GRealPtrArray* array = (GRealPtrArray*) farray;
gpointer result;
g_return_if_fail (array);
g_return_val_if_fail (array, NULL);
g_return_if_fail (index < array->len);
g_return_val_if_fail (index >= 0 && index < array->len, NULL);
result = array->pdata[index];
array->pdata[index] = array->pdata[array->len - 1];
array->pdata[array->len - 1] = NULL;
array->len -= 1;
return result;
}
gboolean
@@ -284,11 +304,11 @@ g_ptr_array_add (GPtrArray* farray,
GByteArray* g_byte_array_new (void)
{
return (GByteArray*) g_array_new (FALSE);
return (GByteArray*) g_array_new (FALSE, FALSE, 1);
}
void g_byte_array_free (GByteArray *array,
gint free_segment)
gboolean free_segment)
{
g_array_free ((GArray*) array, free_segment);
}
@@ -297,7 +317,7 @@ GByteArray* g_byte_array_append (GByteArray *array,
const guint8 *data,
guint len)
{
g_rarray_append ((GArray*) array, (guint8*)data, len);
g_array_append_vals ((GArray*) array, (guint8*)data, len);
return array;
}
@@ -306,15 +326,15 @@ GByteArray* g_byte_array_prepend (GByteArray *array,
const guint8 *data,
guint len)
{
g_rarray_prepend ((GArray*) array, (guint8*)data, len);
g_array_prepend_vals ((GArray*) array, (guint8*)data, len);
return array;
}
GByteArray* g_byte_array_truncate (GByteArray *array,
gint length)
GByteArray* g_byte_array_set_size (GByteArray *array,
guint length)
{
g_rarray_truncate ((GArray*) array, length, 1);
g_array_set_size ((GArray*) array, length);
return array;
}

17
ghash.c
View File

@@ -46,7 +46,6 @@ struct _GHashTable
static void g_hash_table_resize (GHashTable *hash_table);
static GHashNode** g_hash_table_lookup_node(GHashTable *hash_table,
gconstpointer key);
static gint g_hash_closest_prime (gint num);
static GHashNode* g_hash_node_new (gpointer key,
gpointer value);
static void g_hash_node_destroy (GHashNode *hash_node);
@@ -237,7 +236,7 @@ g_hash_table_resize (GHashTable *hash_table)
(nodes_per_list < 3.0 || hash_table->size >= HASH_TABLE_MAX_SIZE))
return;
new_size = CLAMP(g_hash_closest_prime (hash_table->nnodes),
new_size = CLAMP(g_spaced_primes_closest (hash_table->nnodes),
HASH_TABLE_MIN_SIZE,
HASH_TABLE_MAX_SIZE);
new_nodes = g_new (GHashNode*, new_size);
@@ -285,20 +284,6 @@ g_hash_table_lookup_node (GHashTable *hash_table,
return node;
}
static gint
g_hash_closest_prime (gint num)
{
extern gint g_primes[];
extern gint g_nprimes;
gint i;
for (i = 0; i < g_nprimes; i++)
if ((g_primes[i] - num) > 0)
return g_primes[i];
return g_primes[g_nprimes - 1];
}
static GHashNode*
g_hash_node_new (gpointer key,
gpointer value)

95
glib.h
View File

@@ -439,8 +439,8 @@ typedef float gfloat;
typedef double gdouble;
/* HAVE_LONG_DOUBLE doesn't work correctly on all platforms.
* Since gldouble isn't used anywhere, just disable it for now
*/
* Since gldouble isn't used anywhere, just disable it for now */
#if 0
#ifdef HAVE_LONG_DOUBLE
typedef long double gldouble;
@@ -1285,34 +1285,24 @@ void g_string_sprintfa (GString *string,
/* Resizable arrays
*/
#define g_array_length(array,type) \
(((array)->len)/sizeof(type))
#define g_array_append_val(array,type,val) \
g_rarray_append (array, (gpointer) &val, sizeof (type))
#define g_array_append_vals(array,type,vals,nvals) \
g_rarray_append (array, (gpointer) vals, sizeof (type) * nvals)
#define g_array_prepend_val(array,type,val) \
g_rarray_prepend (array, (gpointer) &val, sizeof (type))
#define g_array_prepend_vals(array,type,vals,nvals) \
g_rarray_prepend (array, (gpointer) vals, sizeof (type) * nvals)
#define g_array_truncate(array,type,length) \
g_rarray_truncate (array, length, sizeof (type))
#define g_array_index(array,type,index) \
((type*) array->data)[index]
GArray* g_array_new (gboolean zero_terminated);
void g_array_free (GArray *array,
gboolean free_segment);
GArray* g_rarray_append (GArray *array,
gpointer data,
gint size);
GArray* g_rarray_prepend (GArray *array,
gpointer data,
gint size);
GArray* g_rarray_truncate (GArray *array,
gint length,
gint size);
#define g_array_append_val(a,v) g_array_append_vals(a,&v,1)
#define g_array_prepend_val(a,v) g_array_prepend_vals(a,&v,1)
#define g_array_index(a,t,i) (((t*)a->data)[i])
GArray* g_array_new (gboolean zero_terminated,
gboolean clear,
guint element_size);
void g_array_free (GArray *array,
gboolean free_segment);
GArray* g_array_append_vals (GArray *array,
gpointer data,
guint len);
GArray* g_array_prepend_vals (GArray *array,
gpointer data,
guint len);
GArray* g_array_set_size (GArray *array,
guint length);
/* Resizable pointer array. This interface is much less complicated
* than the above. Add appends appends a pointer. Remove fills any
@@ -1324,30 +1314,28 @@ void g_ptr_array_free (GPtrArray *array,
gboolean free_seg);
void g_ptr_array_set_size (GPtrArray *array,
gint length);
void g_ptr_array_remove_index (GPtrArray *array,
gint index);
gboolean g_ptr_array_remove (GPtrArray *array,
gpointer data);
void g_ptr_array_add (GPtrArray *array,
gpointer data);
gpointer g_ptr_array_remove_index (GPtrArray *array,
gint index);
gboolean g_ptr_array_remove (GPtrArray *array,
gpointer data);
void g_ptr_array_add (GPtrArray *array,
gpointer data);
/* Byte arrays, an array of guint8. Implemented as a GArray,
* but type-safe.
*/
GByteArray* g_byte_array_new (void);
void g_byte_array_free (GByteArray *array,
gint free_segment);
GByteArray* g_byte_array_append (GByteArray *array,
const guint8 *data,
guint len);
GByteArray* g_byte_array_prepend (GByteArray *array,
GByteArray* g_byte_array_new (void);
void g_byte_array_free (GByteArray *array,
gboolean free_segment);
GByteArray* g_byte_array_append (GByteArray *array,
const guint8 *data,
guint len);
GByteArray* g_byte_array_truncate (GByteArray *array,
gint length);
guint len);
GByteArray* g_byte_array_prepend (GByteArray *array,
const guint8 *data,
guint len);
GByteArray* g_byte_array_set_size (GByteArray *array,
guint length);
/* Hash Functions
@@ -1694,8 +1682,23 @@ gpointer g_tuples_index (GTuples *tuples,
gint field);
/* Prime numbers.
*/
/* This function returns prime numbers spaced by approximately 1.5-2.0
* and is for use in resizing data structures which prefer
* prime-valued sizes. The closest spaced prime function returns the
* next largest prime, or the highest it knows about which is about
* MAXINT/4.
*/
guint g_spaced_primes_closest (guint num);
/* Glib version.
*/
extern const guint glib_major_version;
extern const guint glib_minor_version;
extern const guint glib_micro_version;
#ifdef __cplusplus
}

View File

@@ -30,7 +30,9 @@ struct _GRealArray
guint8 *data;
guint len;
guint alloc;
guint zero_terminated;
guint elt_size;
guint zero_terminated : 1;
guint clear : 1;
};
@@ -43,7 +45,9 @@ static GMemChunk *array_mem_chunk = NULL;
GArray*
g_array_new (gboolean zero_terminated)
g_array_new (gboolean zero_terminated,
gboolean clear,
guint elt_size)
{
GRealArray *array;
@@ -54,10 +58,12 @@ g_array_new (gboolean zero_terminated)
array = g_chunk_new (GRealArray, array_mem_chunk);
array->data = NULL;
array->len = 0;
array->alloc = 0;
array->data = NULL;
array->len = 0;
array->alloc = 0;
array->zero_terminated = (zero_terminated ? 1 : 0);
array->clear = (clear ? 1 : 0);
array->elt_size = elt_size;
return (GArray*) array;
}
@@ -73,45 +79,52 @@ g_array_free (GArray *array,
}
GArray*
g_rarray_append (GArray *array,
gpointer data,
gint size)
g_array_append_vals (GArray *farray,
gpointer data,
guint len)
{
g_array_maybe_expand ((GRealArray*) array, size);
GRealArray *array = (GRealArray*) farray;
memcpy (array->data + array->len, data, size);
g_array_maybe_expand (array, len);
array->len += size;
memcpy (array->data + array->elt_size * array->len, data, array->elt_size * len);
return array;
array->len += len;
return farray;
}
GArray*
g_rarray_prepend (GArray *array,
gpointer data,
gint size)
g_array_prepend_vals (GArray *farray,
gpointer data,
guint len)
{
g_array_maybe_expand ((GRealArray*) array, size);
GRealArray *array = (GRealArray*) farray;
g_memmove (array->data + size, array->data, array->len);
memcpy (array->data, data, size);
g_array_maybe_expand (array, len);
array->len += size;
g_memmove (array->data + array->elt_size * len, array->data, array->elt_size * array->len);
return array;
memcpy (array->data, data, len * array->elt_size);
array->len += len;
return farray;
}
GArray*
g_rarray_truncate (GArray *array,
gint length,
gint size)
g_array_set_size (GArray *farray,
guint length)
{
if (array->data)
memset (array->data + length * size, 0, size);
array->len = length * size;
return array;
}
GRealArray *array = (GRealArray*) farray;
if (array->len < length)
g_array_maybe_expand (array, length - array->len);
array->len = length;
return farray;
}
static gint
g_nearest_pow (gint num)
@@ -128,17 +141,19 @@ static void
g_array_maybe_expand (GRealArray *array,
gint len)
{
guint old_alloc;
guint want_alloc = (array->len + len + array->zero_terminated) * array->elt_size;
if ((array->len + len) > array->alloc)
if (want_alloc > array->alloc)
{
old_alloc = array->alloc;
guint old_alloc = array->alloc;
array->alloc = g_nearest_pow (array->len + array->zero_terminated + len);
array->alloc = g_nearest_pow (want_alloc);
array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
array->data = g_realloc (array->data, array->alloc);
memset (array->data + old_alloc, 0, array->alloc - old_alloc);
if (array->clear || array->zero_terminated)
memset (array->data + old_alloc, 0, array->alloc - old_alloc);
}
}
@@ -228,21 +243,26 @@ g_ptr_array_set_size (GPtrArray *farray,
array->len = length;
}
void
gpointer
g_ptr_array_remove_index (GPtrArray* farray,
gint index)
{
GRealPtrArray* array = (GRealPtrArray*) farray;
gpointer result;
g_return_if_fail (array);
g_return_val_if_fail (array, NULL);
g_return_if_fail (index < array->len);
g_return_val_if_fail (index >= 0 && index < array->len, NULL);
result = array->pdata[index];
array->pdata[index] = array->pdata[array->len - 1];
array->pdata[array->len - 1] = NULL;
array->len -= 1;
return result;
}
gboolean
@@ -284,11 +304,11 @@ g_ptr_array_add (GPtrArray* farray,
GByteArray* g_byte_array_new (void)
{
return (GByteArray*) g_array_new (FALSE);
return (GByteArray*) g_array_new (FALSE, FALSE, 1);
}
void g_byte_array_free (GByteArray *array,
gint free_segment)
gboolean free_segment)
{
g_array_free ((GArray*) array, free_segment);
}
@@ -297,7 +317,7 @@ GByteArray* g_byte_array_append (GByteArray *array,
const guint8 *data,
guint len)
{
g_rarray_append ((GArray*) array, (guint8*)data, len);
g_array_append_vals ((GArray*) array, (guint8*)data, len);
return array;
}
@@ -306,15 +326,15 @@ GByteArray* g_byte_array_prepend (GByteArray *array,
const guint8 *data,
guint len)
{
g_rarray_prepend ((GArray*) array, (guint8*)data, len);
g_array_prepend_vals ((GArray*) array, (guint8*)data, len);
return array;
}
GByteArray* g_byte_array_truncate (GByteArray *array,
gint length)
GByteArray* g_byte_array_set_size (GByteArray *array,
guint length)
{
g_rarray_truncate ((GArray*) array, length, 1);
g_array_set_size ((GArray*) array, length);
return array;
}

View File

@@ -46,7 +46,6 @@ struct _GHashTable
static void g_hash_table_resize (GHashTable *hash_table);
static GHashNode** g_hash_table_lookup_node(GHashTable *hash_table,
gconstpointer key);
static gint g_hash_closest_prime (gint num);
static GHashNode* g_hash_node_new (gpointer key,
gpointer value);
static void g_hash_node_destroy (GHashNode *hash_node);
@@ -237,7 +236,7 @@ g_hash_table_resize (GHashTable *hash_table)
(nodes_per_list < 3.0 || hash_table->size >= HASH_TABLE_MAX_SIZE))
return;
new_size = CLAMP(g_hash_closest_prime (hash_table->nnodes),
new_size = CLAMP(g_spaced_primes_closest (hash_table->nnodes),
HASH_TABLE_MIN_SIZE,
HASH_TABLE_MAX_SIZE);
new_nodes = g_new (GHashNode*, new_size);
@@ -285,20 +284,6 @@ g_hash_table_lookup_node (GHashTable *hash_table,
return node;
}
static gint
g_hash_closest_prime (gint num)
{
extern gint g_primes[];
extern gint g_nprimes;
gint i;
for (i = 0; i < g_nprimes; i++)
if ((g_primes[i] - num) > 0)
return g_primes[i];
return g_primes[g_nprimes - 1];
}
static GHashNode*
g_hash_node_new (gpointer key,
gpointer value)

View File

@@ -439,8 +439,8 @@ typedef float gfloat;
typedef double gdouble;
/* HAVE_LONG_DOUBLE doesn't work correctly on all platforms.
* Since gldouble isn't used anywhere, just disable it for now
*/
* Since gldouble isn't used anywhere, just disable it for now */
#if 0
#ifdef HAVE_LONG_DOUBLE
typedef long double gldouble;
@@ -1285,34 +1285,24 @@ void g_string_sprintfa (GString *string,
/* Resizable arrays
*/
#define g_array_length(array,type) \
(((array)->len)/sizeof(type))
#define g_array_append_val(array,type,val) \
g_rarray_append (array, (gpointer) &val, sizeof (type))
#define g_array_append_vals(array,type,vals,nvals) \
g_rarray_append (array, (gpointer) vals, sizeof (type) * nvals)
#define g_array_prepend_val(array,type,val) \
g_rarray_prepend (array, (gpointer) &val, sizeof (type))
#define g_array_prepend_vals(array,type,vals,nvals) \
g_rarray_prepend (array, (gpointer) vals, sizeof (type) * nvals)
#define g_array_truncate(array,type,length) \
g_rarray_truncate (array, length, sizeof (type))
#define g_array_index(array,type,index) \
((type*) array->data)[index]
GArray* g_array_new (gboolean zero_terminated);
void g_array_free (GArray *array,
gboolean free_segment);
GArray* g_rarray_append (GArray *array,
gpointer data,
gint size);
GArray* g_rarray_prepend (GArray *array,
gpointer data,
gint size);
GArray* g_rarray_truncate (GArray *array,
gint length,
gint size);
#define g_array_append_val(a,v) g_array_append_vals(a,&v,1)
#define g_array_prepend_val(a,v) g_array_prepend_vals(a,&v,1)
#define g_array_index(a,t,i) (((t*)a->data)[i])
GArray* g_array_new (gboolean zero_terminated,
gboolean clear,
guint element_size);
void g_array_free (GArray *array,
gboolean free_segment);
GArray* g_array_append_vals (GArray *array,
gpointer data,
guint len);
GArray* g_array_prepend_vals (GArray *array,
gpointer data,
guint len);
GArray* g_array_set_size (GArray *array,
guint length);
/* Resizable pointer array. This interface is much less complicated
* than the above. Add appends appends a pointer. Remove fills any
@@ -1324,30 +1314,28 @@ void g_ptr_array_free (GPtrArray *array,
gboolean free_seg);
void g_ptr_array_set_size (GPtrArray *array,
gint length);
void g_ptr_array_remove_index (GPtrArray *array,
gint index);
gboolean g_ptr_array_remove (GPtrArray *array,
gpointer data);
void g_ptr_array_add (GPtrArray *array,
gpointer data);
gpointer g_ptr_array_remove_index (GPtrArray *array,
gint index);
gboolean g_ptr_array_remove (GPtrArray *array,
gpointer data);
void g_ptr_array_add (GPtrArray *array,
gpointer data);
/* Byte arrays, an array of guint8. Implemented as a GArray,
* but type-safe.
*/
GByteArray* g_byte_array_new (void);
void g_byte_array_free (GByteArray *array,
gint free_segment);
GByteArray* g_byte_array_append (GByteArray *array,
const guint8 *data,
guint len);
GByteArray* g_byte_array_prepend (GByteArray *array,
GByteArray* g_byte_array_new (void);
void g_byte_array_free (GByteArray *array,
gboolean free_segment);
GByteArray* g_byte_array_append (GByteArray *array,
const guint8 *data,
guint len);
GByteArray* g_byte_array_truncate (GByteArray *array,
gint length);
guint len);
GByteArray* g_byte_array_prepend (GByteArray *array,
const guint8 *data,
guint len);
GByteArray* g_byte_array_set_size (GByteArray *array,
guint length);
/* Hash Functions
@@ -1694,8 +1682,23 @@ gpointer g_tuples_index (GTuples *tuples,
gint field);
/* Prime numbers.
*/
/* This function returns prime numbers spaced by approximately 1.5-2.0
* and is for use in resizing data structures which prefer
* prime-valued sizes. The closest spaced prime function returns the
* next largest prime, or the highest it knows about which is about
* MAXINT/4.
*/
guint g_spaced_primes_closest (guint num);
/* Glib version.
*/
extern const guint glib_major_version;
extern const guint glib_minor_version;
extern const guint glib_micro_version;
#ifdef __cplusplus
}

View File

@@ -18,14 +18,11 @@
*/
#include "glib.h"
gint g_primes[] =
static const guint g_primes[] =
{
11,
15,
23,
35,
49,
19,
37,
73,
109,
163,
@@ -59,4 +56,16 @@ gint g_primes[] =
13845163,
};
gint g_nprimes = sizeof (g_primes) / sizeof (g_primes[0]);
static const guint g_nprimes = sizeof (g_primes) / sizeof (g_primes[0]);
guint
g_spaced_primes_closest (guint num)
{
gint i;
for (i = 0; i < g_nprimes; i++)
if (g_primes[i] > num)
return g_primes[i];
return g_primes[g_nprimes - 1];
}

View File

@@ -18,14 +18,11 @@
*/
#include "glib.h"
gint g_primes[] =
static const guint g_primes[] =
{
11,
15,
23,
35,
49,
19,
37,
73,
109,
163,
@@ -59,4 +56,16 @@ gint g_primes[] =
13845163,
};
gint g_nprimes = sizeof (g_primes) / sizeof (g_primes[0]);
static const guint g_nprimes = sizeof (g_primes) / sizeof (g_primes[0]);
guint
g_spaced_primes_closest (guint num)
{
gint i;
for (i = 0; i < g_nprimes; i++)
if (g_primes[i] > num)
return g_primes[i];
return g_primes[g_nprimes - 1];
}

View File

@@ -555,9 +555,9 @@ main (int argc,
g_print ("checking arrays...");
garray = g_array_new (FALSE);
garray = g_array_new (FALSE, FALSE, sizeof (gint));
for (i = 0; i < 10000; i++)
g_array_append_val (garray, gint, i);
g_array_append_val (garray, i);
for (i = 0; i < 10000; i++)
if (g_array_index (garray, gint, i) != i)
@@ -565,13 +565,13 @@ main (int argc,
g_array_free (garray, TRUE);
garray = g_array_new (FALSE);
for (i = 0; i < 10000; i++)
g_array_prepend_val (garray, gint, i);
garray = g_array_new (FALSE, FALSE, sizeof (gint));
for (i = 0; i < 100; i++)
g_array_prepend_val (garray, i);
for (i = 0; i < 10000; i++)
if (g_array_index (garray, gint, i) != (10000 - i - 1))
g_print ("uh oh: %d ( %d )\n", g_array_index (garray, gint, i), 10000 - i - 1);
for (i = 0; i < 100; i++)
if (g_array_index (garray, gint, i) != (100 - i - 1))
g_print ("uh oh: %d ( %d )\n", g_array_index (garray, gint, i), 100 - i - 1);
g_array_free (garray, TRUE);

View File

@@ -555,9 +555,9 @@ main (int argc,
g_print ("checking arrays...");
garray = g_array_new (FALSE);
garray = g_array_new (FALSE, FALSE, sizeof (gint));
for (i = 0; i < 10000; i++)
g_array_append_val (garray, gint, i);
g_array_append_val (garray, i);
for (i = 0; i < 10000; i++)
if (g_array_index (garray, gint, i) != i)
@@ -565,13 +565,13 @@ main (int argc,
g_array_free (garray, TRUE);
garray = g_array_new (FALSE);
for (i = 0; i < 10000; i++)
g_array_prepend_val (garray, gint, i);
garray = g_array_new (FALSE, FALSE, sizeof (gint));
for (i = 0; i < 100; i++)
g_array_prepend_val (garray, i);
for (i = 0; i < 10000; i++)
if (g_array_index (garray, gint, i) != (10000 - i - 1))
g_print ("uh oh: %d ( %d )\n", g_array_index (garray, gint, i), 10000 - i - 1);
for (i = 0; i < 100; i++)
if (g_array_index (garray, gint, i) != (100 - i - 1))
g_print ("uh oh: %d ( %d )\n", g_array_index (garray, gint, i), 100 - i - 1);
g_array_free (garray, TRUE);