mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
[Changes from josh to sync with his glib stuff -Yosh]
Fri Jun 12 00:39:28 1998 Josh MacDonald <jmacd@icw.EECS.Berkeley.EDU> * glib.h: add new hash and equal functions g_int_*. complement g_direct_hash with g_direct_equal. * grel.c: new file, GRelations implement tuples of N-N mappings. A comment in glib.h briefly describes the interface. * ghash.c: new function, g_hash_table_size * glib.h: new typedefs, gsize, gssize, gtime. * garray.c: new functions implementing a simplified GArray. This GPtrArray is an array of gpointers and has functions to add and remove elements, much like java.lang.Vector. * garray.c: new functions for the single-byte special case of GArray. The functions g_byte_array* operate on arrays of bytes. Internally, a GArray is used. * testglib.c: tests for g_ptr_array, g_byte_array, and g_relation...
This commit is contained in:
parent
f62aace5b0
commit
df9a49ec3c
22
ChangeLog
22
ChangeLog
@ -1,3 +1,25 @@
|
||||
Fri Jun 12 00:39:28 1998 Josh MacDonald <jmacd@icw.EECS.Berkeley.EDU>
|
||||
|
||||
* glib.h: add new hash and equal functions g_int_*. complement
|
||||
g_direct_hash with g_direct_equal.
|
||||
|
||||
* grel.c: new file, GRelations implement tuples of N-N mappings.
|
||||
A comment in glib.h briefly describes the interface.
|
||||
|
||||
* ghash.c: new function, g_hash_table_size
|
||||
|
||||
* glib.h: new typedefs, gsize, gssize, gtime.
|
||||
|
||||
* garray.c: new functions implementing a simplified GArray. This
|
||||
GPtrArray is an array of gpointers and has functions to add and
|
||||
remove elements, much like java.lang.Vector.
|
||||
|
||||
* garray.c: new functions for the single-byte special case of
|
||||
GArray. The functions g_byte_array* operate on arrays of bytes.
|
||||
Internally, a GArray is used.
|
||||
|
||||
* testglib.c: tests for g_ptr_array, g_byte_array, and g_relation...
|
||||
|
||||
1998-06-11 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
||||
|
||||
* gdataset.c: #include <string.h>
|
||||
|
@ -1,3 +1,25 @@
|
||||
Fri Jun 12 00:39:28 1998 Josh MacDonald <jmacd@icw.EECS.Berkeley.EDU>
|
||||
|
||||
* glib.h: add new hash and equal functions g_int_*. complement
|
||||
g_direct_hash with g_direct_equal.
|
||||
|
||||
* grel.c: new file, GRelations implement tuples of N-N mappings.
|
||||
A comment in glib.h briefly describes the interface.
|
||||
|
||||
* ghash.c: new function, g_hash_table_size
|
||||
|
||||
* glib.h: new typedefs, gsize, gssize, gtime.
|
||||
|
||||
* garray.c: new functions implementing a simplified GArray. This
|
||||
GPtrArray is an array of gpointers and has functions to add and
|
||||
remove elements, much like java.lang.Vector.
|
||||
|
||||
* garray.c: new functions for the single-byte special case of
|
||||
GArray. The functions g_byte_array* operate on arrays of bytes.
|
||||
Internally, a GArray is used.
|
||||
|
||||
* testglib.c: tests for g_ptr_array, g_byte_array, and g_relation...
|
||||
|
||||
1998-06-11 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
||||
|
||||
* gdataset.c: #include <string.h>
|
||||
|
@ -1,3 +1,25 @@
|
||||
Fri Jun 12 00:39:28 1998 Josh MacDonald <jmacd@icw.EECS.Berkeley.EDU>
|
||||
|
||||
* glib.h: add new hash and equal functions g_int_*. complement
|
||||
g_direct_hash with g_direct_equal.
|
||||
|
||||
* grel.c: new file, GRelations implement tuples of N-N mappings.
|
||||
A comment in glib.h briefly describes the interface.
|
||||
|
||||
* ghash.c: new function, g_hash_table_size
|
||||
|
||||
* glib.h: new typedefs, gsize, gssize, gtime.
|
||||
|
||||
* garray.c: new functions implementing a simplified GArray. This
|
||||
GPtrArray is an array of gpointers and has functions to add and
|
||||
remove elements, much like java.lang.Vector.
|
||||
|
||||
* garray.c: new functions for the single-byte special case of
|
||||
GArray. The functions g_byte_array* operate on arrays of bytes.
|
||||
Internally, a GArray is used.
|
||||
|
||||
* testglib.c: tests for g_ptr_array, g_byte_array, and g_relation...
|
||||
|
||||
1998-06-11 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
||||
|
||||
* gdataset.c: #include <string.h>
|
||||
|
@ -1,3 +1,25 @@
|
||||
Fri Jun 12 00:39:28 1998 Josh MacDonald <jmacd@icw.EECS.Berkeley.EDU>
|
||||
|
||||
* glib.h: add new hash and equal functions g_int_*. complement
|
||||
g_direct_hash with g_direct_equal.
|
||||
|
||||
* grel.c: new file, GRelations implement tuples of N-N mappings.
|
||||
A comment in glib.h briefly describes the interface.
|
||||
|
||||
* ghash.c: new function, g_hash_table_size
|
||||
|
||||
* glib.h: new typedefs, gsize, gssize, gtime.
|
||||
|
||||
* garray.c: new functions implementing a simplified GArray. This
|
||||
GPtrArray is an array of gpointers and has functions to add and
|
||||
remove elements, much like java.lang.Vector.
|
||||
|
||||
* garray.c: new functions for the single-byte special case of
|
||||
GArray. The functions g_byte_array* operate on arrays of bytes.
|
||||
Internally, a GArray is used.
|
||||
|
||||
* testglib.c: tests for g_ptr_array, g_byte_array, and g_relation...
|
||||
|
||||
1998-06-11 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
||||
|
||||
* gdataset.c: #include <string.h>
|
||||
|
@ -1,3 +1,25 @@
|
||||
Fri Jun 12 00:39:28 1998 Josh MacDonald <jmacd@icw.EECS.Berkeley.EDU>
|
||||
|
||||
* glib.h: add new hash and equal functions g_int_*. complement
|
||||
g_direct_hash with g_direct_equal.
|
||||
|
||||
* grel.c: new file, GRelations implement tuples of N-N mappings.
|
||||
A comment in glib.h briefly describes the interface.
|
||||
|
||||
* ghash.c: new function, g_hash_table_size
|
||||
|
||||
* glib.h: new typedefs, gsize, gssize, gtime.
|
||||
|
||||
* garray.c: new functions implementing a simplified GArray. This
|
||||
GPtrArray is an array of gpointers and has functions to add and
|
||||
remove elements, much like java.lang.Vector.
|
||||
|
||||
* garray.c: new functions for the single-byte special case of
|
||||
GArray. The functions g_byte_array* operate on arrays of bytes.
|
||||
Internally, a GArray is used.
|
||||
|
||||
* testglib.c: tests for g_ptr_array, g_byte_array, and g_relation...
|
||||
|
||||
1998-06-11 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
||||
|
||||
* gdataset.c: #include <string.h>
|
||||
|
@ -1,3 +1,25 @@
|
||||
Fri Jun 12 00:39:28 1998 Josh MacDonald <jmacd@icw.EECS.Berkeley.EDU>
|
||||
|
||||
* glib.h: add new hash and equal functions g_int_*. complement
|
||||
g_direct_hash with g_direct_equal.
|
||||
|
||||
* grel.c: new file, GRelations implement tuples of N-N mappings.
|
||||
A comment in glib.h briefly describes the interface.
|
||||
|
||||
* ghash.c: new function, g_hash_table_size
|
||||
|
||||
* glib.h: new typedefs, gsize, gssize, gtime.
|
||||
|
||||
* garray.c: new functions implementing a simplified GArray. This
|
||||
GPtrArray is an array of gpointers and has functions to add and
|
||||
remove elements, much like java.lang.Vector.
|
||||
|
||||
* garray.c: new functions for the single-byte special case of
|
||||
GArray. The functions g_byte_array* operate on arrays of bytes.
|
||||
Internally, a GArray is used.
|
||||
|
||||
* testglib.c: tests for g_ptr_array, g_byte_array, and g_relation...
|
||||
|
||||
1998-06-11 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
||||
|
||||
* gdataset.c: #include <string.h>
|
||||
|
@ -1,3 +1,25 @@
|
||||
Fri Jun 12 00:39:28 1998 Josh MacDonald <jmacd@icw.EECS.Berkeley.EDU>
|
||||
|
||||
* glib.h: add new hash and equal functions g_int_*. complement
|
||||
g_direct_hash with g_direct_equal.
|
||||
|
||||
* grel.c: new file, GRelations implement tuples of N-N mappings.
|
||||
A comment in glib.h briefly describes the interface.
|
||||
|
||||
* ghash.c: new function, g_hash_table_size
|
||||
|
||||
* glib.h: new typedefs, gsize, gssize, gtime.
|
||||
|
||||
* garray.c: new functions implementing a simplified GArray. This
|
||||
GPtrArray is an array of gpointers and has functions to add and
|
||||
remove elements, much like java.lang.Vector.
|
||||
|
||||
* garray.c: new functions for the single-byte special case of
|
||||
GArray. The functions g_byte_array* operate on arrays of bytes.
|
||||
Internally, a GArray is used.
|
||||
|
||||
* testglib.c: tests for g_ptr_array, g_byte_array, and g_relation...
|
||||
|
||||
1998-06-11 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
||||
|
||||
* gdataset.c: #include <string.h>
|
||||
|
@ -1,3 +1,25 @@
|
||||
Fri Jun 12 00:39:28 1998 Josh MacDonald <jmacd@icw.EECS.Berkeley.EDU>
|
||||
|
||||
* glib.h: add new hash and equal functions g_int_*. complement
|
||||
g_direct_hash with g_direct_equal.
|
||||
|
||||
* grel.c: new file, GRelations implement tuples of N-N mappings.
|
||||
A comment in glib.h briefly describes the interface.
|
||||
|
||||
* ghash.c: new function, g_hash_table_size
|
||||
|
||||
* glib.h: new typedefs, gsize, gssize, gtime.
|
||||
|
||||
* garray.c: new functions implementing a simplified GArray. This
|
||||
GPtrArray is an array of gpointers and has functions to add and
|
||||
remove elements, much like java.lang.Vector.
|
||||
|
||||
* garray.c: new functions for the single-byte special case of
|
||||
GArray. The functions g_byte_array* operate on arrays of bytes.
|
||||
Internally, a GArray is used.
|
||||
|
||||
* testglib.c: tests for g_ptr_array, g_byte_array, and g_relation...
|
||||
|
||||
1998-06-11 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
||||
|
||||
* gdataset.c: #include <string.h>
|
||||
|
@ -23,6 +23,7 @@ libglib_1_1_la_SOURCES = \
|
||||
gslist.c \
|
||||
gtimer.c \
|
||||
gtree.c \
|
||||
grel.c \
|
||||
gstring.c \
|
||||
gscanner.c \
|
||||
gutils.c
|
||||
|
177
garray.c
177
garray.c
@ -141,3 +141,180 @@ g_array_maybe_expand (GRealArray *array,
|
||||
memset (array->data + old_alloc, 0, array->alloc - old_alloc);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pointer Array
|
||||
*/
|
||||
|
||||
typedef struct _GRealPtrArray GRealPtrArray;
|
||||
|
||||
struct _GRealPtrArray
|
||||
{
|
||||
gpointer *pdata;
|
||||
guint len;
|
||||
guint alloc;
|
||||
};
|
||||
|
||||
static void g_ptr_array_maybe_expand (GRealPtrArray *array,
|
||||
gint len);
|
||||
|
||||
|
||||
static GMemChunk *ptr_array_mem_chunk = NULL;
|
||||
|
||||
|
||||
|
||||
GPtrArray*
|
||||
g_ptr_array_new ()
|
||||
{
|
||||
GRealPtrArray *array;
|
||||
|
||||
if (!ptr_array_mem_chunk)
|
||||
ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
||||
sizeof (GRealPtrArray),
|
||||
1024, G_ALLOC_AND_FREE);
|
||||
|
||||
array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
|
||||
|
||||
array->pdata = NULL;
|
||||
array->len = 0;
|
||||
array->alloc = 0;
|
||||
|
||||
return (GPtrArray*) array;
|
||||
}
|
||||
|
||||
void
|
||||
g_ptr_array_free (GPtrArray *array,
|
||||
gboolean free_segment)
|
||||
{
|
||||
g_return_if_fail (array);
|
||||
|
||||
if (free_segment)
|
||||
g_free (array->pdata);
|
||||
|
||||
g_mem_chunk_free (ptr_array_mem_chunk, array);
|
||||
}
|
||||
|
||||
static void
|
||||
g_ptr_array_maybe_expand (GRealPtrArray *array,
|
||||
gint len)
|
||||
{
|
||||
guint old_alloc;
|
||||
|
||||
if ((array->len + len) > array->alloc)
|
||||
{
|
||||
old_alloc = array->alloc;
|
||||
|
||||
array->alloc = g_nearest_pow (array->len + len);
|
||||
array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
|
||||
if (array->pdata)
|
||||
array->pdata = g_realloc (array->pdata, sizeof(gpointer) * array->alloc);
|
||||
else
|
||||
array->pdata = g_new0 (gpointer, array->alloc);
|
||||
|
||||
memset (array->pdata + old_alloc, 0, array->alloc - old_alloc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
g_ptr_array_set_size (GPtrArray *farray,
|
||||
gint length)
|
||||
{
|
||||
GRealPtrArray* array = (GRealPtrArray*) farray;
|
||||
|
||||
g_return_if_fail (array);
|
||||
|
||||
if (length > array->len)
|
||||
g_ptr_array_maybe_expand (array, (length - array->len));
|
||||
|
||||
array->len = length;
|
||||
}
|
||||
|
||||
void
|
||||
g_ptr_array_remove_index (GPtrArray* farray,
|
||||
gint index)
|
||||
{
|
||||
GRealPtrArray* array = (GRealPtrArray*) farray;
|
||||
|
||||
g_return_if_fail (array);
|
||||
|
||||
g_return_if_fail (index >= array->len);
|
||||
|
||||
array->pdata[index] = array->pdata[array->len - 1];
|
||||
|
||||
array->pdata[array->len - 1] = NULL;
|
||||
|
||||
array->len -= 1;
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_ptr_array_remove (GPtrArray* farray,
|
||||
gpointer data)
|
||||
{
|
||||
GRealPtrArray* array = (GRealPtrArray*) farray;
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail (array, FALSE);
|
||||
|
||||
for (i = 0; i < array->len; i += 1)
|
||||
{
|
||||
if (array->pdata[i] == data)
|
||||
{
|
||||
g_ptr_array_remove_index (farray, i);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
g_ptr_array_add (GPtrArray* farray,
|
||||
gpointer data)
|
||||
{
|
||||
GRealPtrArray* array = (GRealPtrArray*) farray;
|
||||
|
||||
g_return_if_fail (array);
|
||||
|
||||
g_ptr_array_maybe_expand (array, 1);
|
||||
|
||||
array->pdata[array->len++] = data;
|
||||
}
|
||||
|
||||
/* Byte arrays
|
||||
*/
|
||||
|
||||
GByteArray* g_byte_array_new (void)
|
||||
{
|
||||
return (GByteArray*) g_array_new (FALSE);
|
||||
}
|
||||
|
||||
void g_byte_array_free (GByteArray *array,
|
||||
gint free_segment)
|
||||
{
|
||||
g_array_free ((GArray*) array, free_segment);
|
||||
}
|
||||
|
||||
GByteArray* g_byte_array_append (GByteArray *array,
|
||||
const guint8 *data,
|
||||
guint len)
|
||||
{
|
||||
g_rarray_append ((GArray*) array, (guint8*)data, len);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
GByteArray* g_byte_array_prepend (GByteArray *array,
|
||||
const guint8 *data,
|
||||
guint len)
|
||||
{
|
||||
g_rarray_prepend ((GArray*) array, (guint8*)data, len);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
GByteArray* g_byte_array_truncate (GByteArray *array,
|
||||
gint length)
|
||||
{
|
||||
g_rarray_truncate ((GArray*) array, length, 1);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
8
ghash.c
8
ghash.c
@ -424,3 +424,11 @@ g_hash_nodes_destroy (GHashNode *hash_node)
|
||||
node_free_list = hash_node;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the number of elements contained in the hash table. */
|
||||
gint g_hash_table_size (GHashTable *hash_table)
|
||||
{
|
||||
g_return_val_if_fail (hash_table, 0);
|
||||
|
||||
return ((GRealHashTable *) hash_table)->nnodes;
|
||||
}
|
||||
|
122
glib.h
122
glib.h
@ -433,6 +433,10 @@ typedef unsigned long guint32;
|
||||
/* This should never happen */
|
||||
#endif
|
||||
|
||||
typedef gint32 gssize;
|
||||
typedef guint32 gsize;
|
||||
typedef gint32 gtime;
|
||||
|
||||
|
||||
typedef struct _GList GList;
|
||||
typedef struct _GSList GSList;
|
||||
@ -445,10 +449,14 @@ typedef struct _GListAllocator GListAllocator;
|
||||
typedef struct _GStringChunk GStringChunk;
|
||||
typedef struct _GString GString;
|
||||
typedef struct _GArray GArray;
|
||||
typedef struct _GPtrArray GPtrArray;
|
||||
typedef struct _GByteArray GByteArray;
|
||||
typedef struct _GDebugKey GDebugKey;
|
||||
typedef struct _GScannerConfig GScannerConfig;
|
||||
typedef struct _GScanner GScanner;
|
||||
typedef union _GValue GValue;
|
||||
typedef struct _GRelation GRelation;
|
||||
typedef struct _GTuples GTuples;
|
||||
|
||||
|
||||
typedef void (*GFunc) (gpointer data,
|
||||
@ -501,6 +509,23 @@ struct _GArray
|
||||
guint len;
|
||||
};
|
||||
|
||||
struct _GByteArray
|
||||
{
|
||||
guint8 *data;
|
||||
guint len;
|
||||
};
|
||||
|
||||
struct _GPtrArray
|
||||
{
|
||||
gpointer *pdata;
|
||||
guint len;
|
||||
};
|
||||
|
||||
struct _GTuples
|
||||
{
|
||||
guint len;
|
||||
};
|
||||
|
||||
struct _GDebugKey
|
||||
{
|
||||
gchar *key;
|
||||
@ -635,6 +660,7 @@ void g_hash_table_thaw (GHashTable *hash_table);
|
||||
void g_hash_table_foreach (GHashTable *hash_table,
|
||||
GHFunc func,
|
||||
gpointer user_data);
|
||||
gint g_hash_table_size (GHashTable *hash_table);
|
||||
|
||||
|
||||
/* Caches
|
||||
@ -891,17 +917,63 @@ GArray* g_rarray_truncate (GArray *array,
|
||||
gint length,
|
||||
gint size);
|
||||
|
||||
/* Resizable pointer array. This interface is much less complicated
|
||||
* than the above. Add appends appends a pointer. Remove fills any
|
||||
* cleared spot and shortens the array.
|
||||
*/
|
||||
|
||||
#define g_ptr_array_index(array,index) (array->pdata)[index]
|
||||
|
||||
GPtrArray* g_ptr_array_new (void);
|
||||
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);
|
||||
|
||||
/* 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,
|
||||
const guint8 *data,
|
||||
guint len);
|
||||
|
||||
GByteArray* g_byte_array_truncate (GByteArray *array,
|
||||
gint length);
|
||||
|
||||
|
||||
/* Hash Functions
|
||||
*/
|
||||
gint g_str_equal (gconstpointer v,
|
||||
gconstpointer v2);
|
||||
guint g_str_hash (gconstpointer v);
|
||||
|
||||
gint g_int_equal (gconstpointer v,
|
||||
gconstpointer v2);
|
||||
guint g_int_hash (gconstpointer v);
|
||||
|
||||
/* This "hash" function will just return the key's adress as an
|
||||
* unsigned integer. Useful for hashing on plain adresses or
|
||||
* simple integer values.
|
||||
*/
|
||||
guint g_direct_hash (gconstpointer key);
|
||||
guint g_direct_hash (gconstpointer v);
|
||||
gint g_direct_equal (gconstpointer v,
|
||||
gconstpointer v2);
|
||||
|
||||
|
||||
|
||||
/* Location Associated Data
|
||||
@ -1141,6 +1213,54 @@ GList* g_completion_complete (GCompletion* cmp,
|
||||
gchar** new_prefix);
|
||||
void g_completion_free (GCompletion* cmp);
|
||||
|
||||
/* GRelation: Indexed Relations. Imagine a really simple table in a
|
||||
* database. Relations are not ordered. This data type is meant for
|
||||
* maintaining a N-way mapping.
|
||||
*
|
||||
* g_relation_new() creates a relation with FIELDS fields
|
||||
*
|
||||
* g_relation_destroy() frees all resources
|
||||
* g_tuples_destroy() frees the result of g_relation_select()
|
||||
*
|
||||
* g_relation_index() indexes relation FIELD with the provided
|
||||
* equality and hash functions. this must be done before any
|
||||
* calls to insert are made.
|
||||
*
|
||||
* g_relation_insert() inserts a new tuple. you are expected to
|
||||
* provide the right number of fields.
|
||||
*
|
||||
* g_relation_delete() deletes all relations with KEY in FIELD
|
||||
* g_relation_select() returns ...
|
||||
* g_relation_count() counts ...
|
||||
*/
|
||||
|
||||
GRelation* g_relation_new (gint fields);
|
||||
void g_relation_destroy (GRelation *relation);
|
||||
void g_relation_index (GRelation *relation,
|
||||
gint field,
|
||||
GHashFunc hash_func,
|
||||
GCompareFunc key_compare_func);
|
||||
void g_relation_insert (GRelation *relation,
|
||||
...);
|
||||
gint g_relation_delete (GRelation *relation,
|
||||
gconstpointer key,
|
||||
gint field);
|
||||
GTuples* g_relation_select (GRelation *relation,
|
||||
gconstpointer key,
|
||||
gint field);
|
||||
gint g_relation_count (GRelation *relation,
|
||||
gconstpointer key,
|
||||
gint field);
|
||||
gboolean g_relation_exists (GRelation *relation,
|
||||
...);
|
||||
void g_relation_print (GRelation *relation);
|
||||
|
||||
void g_tuples_destroy (GTuples *tuples);
|
||||
gpointer g_tuples_index (GTuples *tuples,
|
||||
gint index,
|
||||
gint field);
|
||||
|
||||
|
||||
/* Glib version.
|
||||
*/
|
||||
extern const guint glib_major_version;
|
||||
|
@ -23,6 +23,7 @@ libglib_1_1_la_SOURCES = \
|
||||
gslist.c \
|
||||
gtimer.c \
|
||||
gtree.c \
|
||||
grel.c \
|
||||
gstring.c \
|
||||
gscanner.c \
|
||||
gutils.c
|
||||
|
177
glib/garray.c
177
glib/garray.c
@ -141,3 +141,180 @@ g_array_maybe_expand (GRealArray *array,
|
||||
memset (array->data + old_alloc, 0, array->alloc - old_alloc);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pointer Array
|
||||
*/
|
||||
|
||||
typedef struct _GRealPtrArray GRealPtrArray;
|
||||
|
||||
struct _GRealPtrArray
|
||||
{
|
||||
gpointer *pdata;
|
||||
guint len;
|
||||
guint alloc;
|
||||
};
|
||||
|
||||
static void g_ptr_array_maybe_expand (GRealPtrArray *array,
|
||||
gint len);
|
||||
|
||||
|
||||
static GMemChunk *ptr_array_mem_chunk = NULL;
|
||||
|
||||
|
||||
|
||||
GPtrArray*
|
||||
g_ptr_array_new ()
|
||||
{
|
||||
GRealPtrArray *array;
|
||||
|
||||
if (!ptr_array_mem_chunk)
|
||||
ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
|
||||
sizeof (GRealPtrArray),
|
||||
1024, G_ALLOC_AND_FREE);
|
||||
|
||||
array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
|
||||
|
||||
array->pdata = NULL;
|
||||
array->len = 0;
|
||||
array->alloc = 0;
|
||||
|
||||
return (GPtrArray*) array;
|
||||
}
|
||||
|
||||
void
|
||||
g_ptr_array_free (GPtrArray *array,
|
||||
gboolean free_segment)
|
||||
{
|
||||
g_return_if_fail (array);
|
||||
|
||||
if (free_segment)
|
||||
g_free (array->pdata);
|
||||
|
||||
g_mem_chunk_free (ptr_array_mem_chunk, array);
|
||||
}
|
||||
|
||||
static void
|
||||
g_ptr_array_maybe_expand (GRealPtrArray *array,
|
||||
gint len)
|
||||
{
|
||||
guint old_alloc;
|
||||
|
||||
if ((array->len + len) > array->alloc)
|
||||
{
|
||||
old_alloc = array->alloc;
|
||||
|
||||
array->alloc = g_nearest_pow (array->len + len);
|
||||
array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
|
||||
if (array->pdata)
|
||||
array->pdata = g_realloc (array->pdata, sizeof(gpointer) * array->alloc);
|
||||
else
|
||||
array->pdata = g_new0 (gpointer, array->alloc);
|
||||
|
||||
memset (array->pdata + old_alloc, 0, array->alloc - old_alloc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
g_ptr_array_set_size (GPtrArray *farray,
|
||||
gint length)
|
||||
{
|
||||
GRealPtrArray* array = (GRealPtrArray*) farray;
|
||||
|
||||
g_return_if_fail (array);
|
||||
|
||||
if (length > array->len)
|
||||
g_ptr_array_maybe_expand (array, (length - array->len));
|
||||
|
||||
array->len = length;
|
||||
}
|
||||
|
||||
void
|
||||
g_ptr_array_remove_index (GPtrArray* farray,
|
||||
gint index)
|
||||
{
|
||||
GRealPtrArray* array = (GRealPtrArray*) farray;
|
||||
|
||||
g_return_if_fail (array);
|
||||
|
||||
g_return_if_fail (index >= array->len);
|
||||
|
||||
array->pdata[index] = array->pdata[array->len - 1];
|
||||
|
||||
array->pdata[array->len - 1] = NULL;
|
||||
|
||||
array->len -= 1;
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_ptr_array_remove (GPtrArray* farray,
|
||||
gpointer data)
|
||||
{
|
||||
GRealPtrArray* array = (GRealPtrArray*) farray;
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail (array, FALSE);
|
||||
|
||||
for (i = 0; i < array->len; i += 1)
|
||||
{
|
||||
if (array->pdata[i] == data)
|
||||
{
|
||||
g_ptr_array_remove_index (farray, i);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
g_ptr_array_add (GPtrArray* farray,
|
||||
gpointer data)
|
||||
{
|
||||
GRealPtrArray* array = (GRealPtrArray*) farray;
|
||||
|
||||
g_return_if_fail (array);
|
||||
|
||||
g_ptr_array_maybe_expand (array, 1);
|
||||
|
||||
array->pdata[array->len++] = data;
|
||||
}
|
||||
|
||||
/* Byte arrays
|
||||
*/
|
||||
|
||||
GByteArray* g_byte_array_new (void)
|
||||
{
|
||||
return (GByteArray*) g_array_new (FALSE);
|
||||
}
|
||||
|
||||
void g_byte_array_free (GByteArray *array,
|
||||
gint free_segment)
|
||||
{
|
||||
g_array_free ((GArray*) array, free_segment);
|
||||
}
|
||||
|
||||
GByteArray* g_byte_array_append (GByteArray *array,
|
||||
const guint8 *data,
|
||||
guint len)
|
||||
{
|
||||
g_rarray_append ((GArray*) array, (guint8*)data, len);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
GByteArray* g_byte_array_prepend (GByteArray *array,
|
||||
const guint8 *data,
|
||||
guint len)
|
||||
{
|
||||
g_rarray_prepend ((GArray*) array, (guint8*)data, len);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
GByteArray* g_byte_array_truncate (GByteArray *array,
|
||||
gint length)
|
||||
{
|
||||
g_rarray_truncate ((GArray*) array, length, 1);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
@ -424,3 +424,11 @@ g_hash_nodes_destroy (GHashNode *hash_node)
|
||||
node_free_list = hash_node;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the number of elements contained in the hash table. */
|
||||
gint g_hash_table_size (GHashTable *hash_table)
|
||||
{
|
||||
g_return_val_if_fail (hash_table, 0);
|
||||
|
||||
return ((GRealHashTable *) hash_table)->nnodes;
|
||||
}
|
||||
|
122
glib/glib.h
122
glib/glib.h
@ -433,6 +433,10 @@ typedef unsigned long guint32;
|
||||
/* This should never happen */
|
||||
#endif
|
||||
|
||||
typedef gint32 gssize;
|
||||
typedef guint32 gsize;
|
||||
typedef gint32 gtime;
|
||||
|
||||
|
||||
typedef struct _GList GList;
|
||||
typedef struct _GSList GSList;
|
||||
@ -445,10 +449,14 @@ typedef struct _GListAllocator GListAllocator;
|
||||
typedef struct _GStringChunk GStringChunk;
|
||||
typedef struct _GString GString;
|
||||
typedef struct _GArray GArray;
|
||||
typedef struct _GPtrArray GPtrArray;
|
||||
typedef struct _GByteArray GByteArray;
|
||||
typedef struct _GDebugKey GDebugKey;
|
||||
typedef struct _GScannerConfig GScannerConfig;
|
||||
typedef struct _GScanner GScanner;
|
||||
typedef union _GValue GValue;
|
||||
typedef struct _GRelation GRelation;
|
||||
typedef struct _GTuples GTuples;
|
||||
|
||||
|
||||
typedef void (*GFunc) (gpointer data,
|
||||
@ -501,6 +509,23 @@ struct _GArray
|
||||
guint len;
|
||||
};
|
||||
|
||||
struct _GByteArray
|
||||
{
|
||||
guint8 *data;
|
||||
guint len;
|
||||
};
|
||||
|
||||
struct _GPtrArray
|
||||
{
|
||||
gpointer *pdata;
|
||||
guint len;
|
||||
};
|
||||
|
||||
struct _GTuples
|
||||
{
|
||||
guint len;
|
||||
};
|
||||
|
||||
struct _GDebugKey
|
||||
{
|
||||
gchar *key;
|
||||
@ -635,6 +660,7 @@ void g_hash_table_thaw (GHashTable *hash_table);
|
||||
void g_hash_table_foreach (GHashTable *hash_table,
|
||||
GHFunc func,
|
||||
gpointer user_data);
|
||||
gint g_hash_table_size (GHashTable *hash_table);
|
||||
|
||||
|
||||
/* Caches
|
||||
@ -891,17 +917,63 @@ GArray* g_rarray_truncate (GArray *array,
|
||||
gint length,
|
||||
gint size);
|
||||
|
||||
/* Resizable pointer array. This interface is much less complicated
|
||||
* than the above. Add appends appends a pointer. Remove fills any
|
||||
* cleared spot and shortens the array.
|
||||
*/
|
||||
|
||||
#define g_ptr_array_index(array,index) (array->pdata)[index]
|
||||
|
||||
GPtrArray* g_ptr_array_new (void);
|
||||
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);
|
||||
|
||||
/* 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,
|
||||
const guint8 *data,
|
||||
guint len);
|
||||
|
||||
GByteArray* g_byte_array_truncate (GByteArray *array,
|
||||
gint length);
|
||||
|
||||
|
||||
/* Hash Functions
|
||||
*/
|
||||
gint g_str_equal (gconstpointer v,
|
||||
gconstpointer v2);
|
||||
guint g_str_hash (gconstpointer v);
|
||||
|
||||
gint g_int_equal (gconstpointer v,
|
||||
gconstpointer v2);
|
||||
guint g_int_hash (gconstpointer v);
|
||||
|
||||
/* This "hash" function will just return the key's adress as an
|
||||
* unsigned integer. Useful for hashing on plain adresses or
|
||||
* simple integer values.
|
||||
*/
|
||||
guint g_direct_hash (gconstpointer key);
|
||||
guint g_direct_hash (gconstpointer v);
|
||||
gint g_direct_equal (gconstpointer v,
|
||||
gconstpointer v2);
|
||||
|
||||
|
||||
|
||||
/* Location Associated Data
|
||||
@ -1141,6 +1213,54 @@ GList* g_completion_complete (GCompletion* cmp,
|
||||
gchar** new_prefix);
|
||||
void g_completion_free (GCompletion* cmp);
|
||||
|
||||
/* GRelation: Indexed Relations. Imagine a really simple table in a
|
||||
* database. Relations are not ordered. This data type is meant for
|
||||
* maintaining a N-way mapping.
|
||||
*
|
||||
* g_relation_new() creates a relation with FIELDS fields
|
||||
*
|
||||
* g_relation_destroy() frees all resources
|
||||
* g_tuples_destroy() frees the result of g_relation_select()
|
||||
*
|
||||
* g_relation_index() indexes relation FIELD with the provided
|
||||
* equality and hash functions. this must be done before any
|
||||
* calls to insert are made.
|
||||
*
|
||||
* g_relation_insert() inserts a new tuple. you are expected to
|
||||
* provide the right number of fields.
|
||||
*
|
||||
* g_relation_delete() deletes all relations with KEY in FIELD
|
||||
* g_relation_select() returns ...
|
||||
* g_relation_count() counts ...
|
||||
*/
|
||||
|
||||
GRelation* g_relation_new (gint fields);
|
||||
void g_relation_destroy (GRelation *relation);
|
||||
void g_relation_index (GRelation *relation,
|
||||
gint field,
|
||||
GHashFunc hash_func,
|
||||
GCompareFunc key_compare_func);
|
||||
void g_relation_insert (GRelation *relation,
|
||||
...);
|
||||
gint g_relation_delete (GRelation *relation,
|
||||
gconstpointer key,
|
||||
gint field);
|
||||
GTuples* g_relation_select (GRelation *relation,
|
||||
gconstpointer key,
|
||||
gint field);
|
||||
gint g_relation_count (GRelation *relation,
|
||||
gconstpointer key,
|
||||
gint field);
|
||||
gboolean g_relation_exists (GRelation *relation,
|
||||
...);
|
||||
void g_relation_print (GRelation *relation);
|
||||
|
||||
void g_tuples_destroy (GTuples *tuples);
|
||||
gpointer g_tuples_index (GTuples *tuples,
|
||||
gint index,
|
||||
gint field);
|
||||
|
||||
|
||||
/* Glib version.
|
||||
*/
|
||||
extern const guint glib_major_version;
|
||||
|
428
glib/grel.c
Normal file
428
glib/grel.c
Normal file
@ -0,0 +1,428 @@
|
||||
/* GLIB - Library of useful routines for C programming
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "glib.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef struct _GRealRelation GRealRelation;
|
||||
typedef struct _GRealTuples GRealTuples;
|
||||
|
||||
struct _GRealRelation
|
||||
{
|
||||
gint fields;
|
||||
gint current_field;
|
||||
|
||||
GHashTable *all_tuples;
|
||||
GHashTable **hashed_tuple_tables;
|
||||
GMemChunk *tuple_chunk;
|
||||
|
||||
gint count;
|
||||
};
|
||||
|
||||
struct _GRealTuples
|
||||
{
|
||||
gint len;
|
||||
gint width;
|
||||
gpointer *data;
|
||||
};
|
||||
|
||||
gboolean
|
||||
tuple_equal_2 (gconstpointer v_a, gconstpointer v_b)
|
||||
{
|
||||
gpointer* a = (gpointer*) v_a;
|
||||
gpointer* b = (gpointer*) v_b;
|
||||
|
||||
return a[0] == b[0] && a[1] == b[1];
|
||||
}
|
||||
|
||||
guint
|
||||
tuple_hash_2 (gconstpointer v_a)
|
||||
{
|
||||
gpointer* a = (gpointer*) v_a;
|
||||
|
||||
return (gulong)a[0] ^ (gulong)a[1];
|
||||
}
|
||||
|
||||
GHashFunc
|
||||
tuple_hash (gint fields)
|
||||
{
|
||||
switch (fields)
|
||||
{
|
||||
case 2:
|
||||
return tuple_hash_2;
|
||||
default:
|
||||
g_error ("no tuple hash for %d", fields);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GCompareFunc
|
||||
tuple_equal (gint fields)
|
||||
{
|
||||
switch (fields)
|
||||
{
|
||||
case 2:
|
||||
return tuple_equal_2;
|
||||
default:
|
||||
g_error ("no tuple equal for %d", fields);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GRelation*
|
||||
g_relation_new (gint fields)
|
||||
{
|
||||
GRealRelation* rel = g_new0 (GRealRelation, 1);
|
||||
|
||||
rel->fields = fields;
|
||||
rel->tuple_chunk = g_mem_chunk_new ("Relation Chunk",
|
||||
fields * sizeof (gpointer),
|
||||
fields * sizeof (gpointer) * 128,
|
||||
G_ALLOC_AND_FREE);
|
||||
rel->all_tuples = g_hash_table_new (tuple_hash (fields), tuple_equal (fields));
|
||||
rel->hashed_tuple_tables = g_new0 (GHashTable*, fields);
|
||||
|
||||
return (GRelation*) rel;
|
||||
}
|
||||
|
||||
static void
|
||||
g_relation_free_array (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
g_hash_table_destroy ((GHashTable*) value);
|
||||
}
|
||||
|
||||
void
|
||||
g_relation_destroy (GRelation *relation)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
gint i;
|
||||
|
||||
if (rel)
|
||||
{
|
||||
g_hash_table_destroy (rel->all_tuples);
|
||||
g_mem_chunk_destroy (rel->tuple_chunk);
|
||||
|
||||
for (i = 0; i < rel->fields; i += 1)
|
||||
{
|
||||
if (rel->hashed_tuple_tables[i])
|
||||
{
|
||||
g_hash_table_foreach (rel->hashed_tuple_tables[i], g_relation_free_array, NULL);
|
||||
g_hash_table_destroy (rel->hashed_tuple_tables[i]);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (rel->hashed_tuple_tables);
|
||||
g_free (rel);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
g_relation_index (GRelation *relation,
|
||||
gint field,
|
||||
GHashFunc hash_func,
|
||||
GCompareFunc key_compare_func)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
|
||||
g_assert (rel->count == 0 && rel->hashed_tuple_tables[field] == NULL);
|
||||
|
||||
rel->hashed_tuple_tables[field] = g_hash_table_new (hash_func, key_compare_func);
|
||||
}
|
||||
|
||||
void
|
||||
g_relation_insert (GRelation *relation,
|
||||
...)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
gpointer* tuple = g_chunk_new (gpointer, rel->tuple_chunk);
|
||||
va_list args;
|
||||
gint i;
|
||||
|
||||
va_start(args, relation);
|
||||
|
||||
for (i = 0; i < rel->fields; i += 1)
|
||||
tuple[i] = va_arg(args, gpointer);
|
||||
|
||||
va_end(args);
|
||||
|
||||
g_hash_table_insert (rel->all_tuples, tuple, tuple);
|
||||
|
||||
rel->count += 1;
|
||||
|
||||
for (i = 0; i < rel->fields; i += 1)
|
||||
{
|
||||
GHashTable *table;
|
||||
gpointer key;
|
||||
GHashTable *per_key_table;
|
||||
|
||||
table = rel->hashed_tuple_tables[i];
|
||||
|
||||
if (table == NULL)
|
||||
continue;
|
||||
|
||||
key = tuple[i];
|
||||
per_key_table = g_hash_table_lookup (table, key);
|
||||
|
||||
if (per_key_table == NULL)
|
||||
{
|
||||
per_key_table = g_hash_table_new (tuple_hash (rel->fields), tuple_equal (rel->fields));
|
||||
g_hash_table_insert (table, key, per_key_table);
|
||||
}
|
||||
|
||||
g_hash_table_insert (per_key_table, tuple, tuple);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_relation_delete_tuple (gpointer tuple_key, gpointer tuple_value, gpointer user_data)
|
||||
{
|
||||
gpointer *tuple = (gpointer*) tuple_value;
|
||||
GRealRelation *rel = (GRealRelation *) user_data;
|
||||
gint j;
|
||||
|
||||
g_assert (tuple_key == tuple_value);
|
||||
|
||||
for (j = 0; j < rel->fields; j += 1)
|
||||
{
|
||||
GHashTable *one_table = rel->hashed_tuple_tables[j];
|
||||
gpointer one_key;
|
||||
GHashTable *per_key_table;
|
||||
|
||||
if (one_table == NULL)
|
||||
continue;
|
||||
|
||||
if (j == rel->current_field)
|
||||
/* can't delete from the table we're foreaching in */
|
||||
continue;
|
||||
|
||||
one_key = tuple[j];
|
||||
|
||||
per_key_table = g_hash_table_lookup (one_table, one_key);
|
||||
|
||||
g_hash_table_remove (per_key_table, tuple);
|
||||
}
|
||||
|
||||
g_hash_table_remove (rel->all_tuples, tuple);
|
||||
|
||||
rel->count -= 1;
|
||||
}
|
||||
|
||||
gint
|
||||
g_relation_delete (GRelation *relation,
|
||||
gconstpointer key,
|
||||
gint field)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
GHashTable *table = rel->hashed_tuple_tables[field];
|
||||
GHashTable *key_table;
|
||||
gint count = rel->count;
|
||||
|
||||
g_assert (table);
|
||||
|
||||
key_table = g_hash_table_lookup (table, key);
|
||||
|
||||
if (!key_table)
|
||||
return 0;
|
||||
|
||||
rel->current_field = field;
|
||||
|
||||
g_hash_table_foreach (key_table, g_relation_delete_tuple, rel);
|
||||
|
||||
g_hash_table_remove (table, key);
|
||||
|
||||
g_hash_table_destroy (key_table);
|
||||
|
||||
/* @@@ Remove empty hash tables. */
|
||||
|
||||
return count - rel->count;
|
||||
}
|
||||
|
||||
static void
|
||||
g_relation_select_tuple (gpointer tuple_key, gpointer tuple_value, gpointer user_data)
|
||||
{
|
||||
gpointer *tuple = (gpointer*) tuple_value;
|
||||
GRealTuples *tuples = (GRealTuples*) user_data;
|
||||
gint stride = sizeof (gpointer) * tuples->width;
|
||||
|
||||
g_assert (tuple_key == tuple_value);
|
||||
|
||||
memcpy (tuples->data + (tuples->len * tuples->width),
|
||||
tuple,
|
||||
stride);
|
||||
|
||||
tuples->len += 1;
|
||||
}
|
||||
|
||||
GTuples*
|
||||
g_relation_select (GRelation *relation,
|
||||
gconstpointer key,
|
||||
gint field)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
GHashTable *table = rel->hashed_tuple_tables[field];
|
||||
GHashTable *key_table;
|
||||
GRealTuples *tuples = g_new0 (GRealTuples, 1);
|
||||
gint count;
|
||||
|
||||
g_assert (table);
|
||||
|
||||
key_table = g_hash_table_lookup (table, key);
|
||||
|
||||
if (!key_table)
|
||||
return (GTuples*)tuples;
|
||||
|
||||
count = g_relation_count (relation, key, field);
|
||||
|
||||
tuples->data = g_malloc (sizeof (gpointer) * rel->fields * count);
|
||||
tuples->width = rel->fields;
|
||||
|
||||
g_hash_table_foreach (key_table, g_relation_select_tuple, tuples);
|
||||
|
||||
g_assert (count == tuples->len);
|
||||
|
||||
return (GTuples*)tuples;
|
||||
}
|
||||
|
||||
gint
|
||||
g_relation_count (GRelation *relation,
|
||||
gconstpointer key,
|
||||
gint field)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
GHashTable *table = rel->hashed_tuple_tables[field];
|
||||
GHashTable *key_table;
|
||||
|
||||
g_assert (table);
|
||||
|
||||
key_table = g_hash_table_lookup (table, key);
|
||||
|
||||
if (!key_table)
|
||||
return 0;
|
||||
|
||||
return g_hash_table_size (key_table);
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_relation_exists (GRelation *relation, ...)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
gpointer* tuple = g_chunk_new (gpointer, rel->tuple_chunk);
|
||||
va_list args;
|
||||
gint i;
|
||||
gboolean result;
|
||||
|
||||
va_start(args, relation);
|
||||
|
||||
for (i = 0; i < rel->fields; i += 1)
|
||||
tuple[i] = va_arg(args, gpointer);
|
||||
|
||||
va_end(args);
|
||||
|
||||
result = g_hash_table_lookup (rel->all_tuples, tuple) != NULL;
|
||||
|
||||
g_mem_chunk_free (rel->tuple_chunk, tuple);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
g_tuples_destroy (GTuples *tuples0)
|
||||
{
|
||||
GRealTuples *tuples = (GRealTuples*) tuples0;
|
||||
|
||||
if (tuples)
|
||||
{
|
||||
g_free (tuples->data);
|
||||
g_free (tuples);
|
||||
}
|
||||
}
|
||||
|
||||
gpointer
|
||||
g_tuples_index (GTuples *tuples0,
|
||||
gint index,
|
||||
gint field)
|
||||
{
|
||||
GRealTuples *tuples = (GRealTuples*) tuples0;
|
||||
|
||||
g_assert (field < tuples->width);
|
||||
|
||||
return tuples->data[index * tuples->width + field];
|
||||
}
|
||||
|
||||
/* Print
|
||||
*/
|
||||
|
||||
void
|
||||
g_relation_print_one (gpointer tuple_key, gpointer tuple_value, gpointer user_data)
|
||||
{
|
||||
gint i;
|
||||
GRealRelation* rel = (GRealRelation*) user_data;
|
||||
gpointer* tuples = (gpointer*) tuple_value;
|
||||
|
||||
g_print ("[");
|
||||
|
||||
for (i = 0; i < rel->fields; i += 1)
|
||||
{
|
||||
g_print ("%p", tuples[i]);
|
||||
|
||||
if (i < (rel->fields - 1))
|
||||
g_print (",");
|
||||
}
|
||||
|
||||
g_print ("]\n");
|
||||
}
|
||||
|
||||
void
|
||||
g_relation_print_index (gpointer tuple_key, gpointer tuple_value, gpointer user_data)
|
||||
{
|
||||
GRealRelation* rel = (GRealRelation*) user_data;
|
||||
GHashTable* table = (GHashTable*) tuple_value;
|
||||
|
||||
g_print ("*** key %p\n", tuple_key);
|
||||
|
||||
g_hash_table_foreach (table,
|
||||
g_relation_print_one,
|
||||
rel);
|
||||
}
|
||||
|
||||
void
|
||||
g_relation_print (GRelation *relation)
|
||||
{
|
||||
gint i;
|
||||
GRealRelation* rel = (GRealRelation*) relation;
|
||||
|
||||
g_print ("*** all tuples (%d)\n", rel->count);
|
||||
|
||||
g_hash_table_foreach (rel->all_tuples,
|
||||
g_relation_print_one,
|
||||
rel);
|
||||
|
||||
for (i = 0; i < rel->fields; i += 1)
|
||||
{
|
||||
if (rel->hashed_tuple_tables[i] == NULL)
|
||||
continue;
|
||||
|
||||
g_print ("*** index %d\n", i);
|
||||
|
||||
g_hash_table_foreach (rel->hashed_tuple_tables[i],
|
||||
g_relation_print_index,
|
||||
rel);
|
||||
}
|
||||
|
||||
}
|
@ -16,12 +16,12 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include <glib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
typedef struct _GRealStringChunk GRealStringChunk;
|
||||
|
@ -851,8 +851,25 @@ g_parse_debug_string (const gchar *string,
|
||||
}
|
||||
|
||||
guint
|
||||
g_direct_hash(gconstpointer key)
|
||||
g_direct_hash(gconstpointer v)
|
||||
{
|
||||
return GPOINTER_TO_UINT (key);
|
||||
return GPOINTER_TO_UINT (v);
|
||||
}
|
||||
|
||||
gint
|
||||
g_direct_equal(gconstpointer v, gconstpointer v2)
|
||||
{
|
||||
return GPOINTER_TO_UINT (v) == GPOINTER_TO_UINT (v2);
|
||||
}
|
||||
|
||||
gint
|
||||
g_int_equal (gconstpointer v, gconstpointer v2)
|
||||
{
|
||||
return *((const gint*) v) == *((const gint*) v2);
|
||||
}
|
||||
|
||||
guint
|
||||
g_int_hash (gconstpointer v)
|
||||
{
|
||||
return *(const gint*) v;
|
||||
}
|
||||
|
428
grel.c
Normal file
428
grel.c
Normal file
@ -0,0 +1,428 @@
|
||||
/* GLIB - Library of useful routines for C programming
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "glib.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef struct _GRealRelation GRealRelation;
|
||||
typedef struct _GRealTuples GRealTuples;
|
||||
|
||||
struct _GRealRelation
|
||||
{
|
||||
gint fields;
|
||||
gint current_field;
|
||||
|
||||
GHashTable *all_tuples;
|
||||
GHashTable **hashed_tuple_tables;
|
||||
GMemChunk *tuple_chunk;
|
||||
|
||||
gint count;
|
||||
};
|
||||
|
||||
struct _GRealTuples
|
||||
{
|
||||
gint len;
|
||||
gint width;
|
||||
gpointer *data;
|
||||
};
|
||||
|
||||
gboolean
|
||||
tuple_equal_2 (gconstpointer v_a, gconstpointer v_b)
|
||||
{
|
||||
gpointer* a = (gpointer*) v_a;
|
||||
gpointer* b = (gpointer*) v_b;
|
||||
|
||||
return a[0] == b[0] && a[1] == b[1];
|
||||
}
|
||||
|
||||
guint
|
||||
tuple_hash_2 (gconstpointer v_a)
|
||||
{
|
||||
gpointer* a = (gpointer*) v_a;
|
||||
|
||||
return (gulong)a[0] ^ (gulong)a[1];
|
||||
}
|
||||
|
||||
GHashFunc
|
||||
tuple_hash (gint fields)
|
||||
{
|
||||
switch (fields)
|
||||
{
|
||||
case 2:
|
||||
return tuple_hash_2;
|
||||
default:
|
||||
g_error ("no tuple hash for %d", fields);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GCompareFunc
|
||||
tuple_equal (gint fields)
|
||||
{
|
||||
switch (fields)
|
||||
{
|
||||
case 2:
|
||||
return tuple_equal_2;
|
||||
default:
|
||||
g_error ("no tuple equal for %d", fields);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GRelation*
|
||||
g_relation_new (gint fields)
|
||||
{
|
||||
GRealRelation* rel = g_new0 (GRealRelation, 1);
|
||||
|
||||
rel->fields = fields;
|
||||
rel->tuple_chunk = g_mem_chunk_new ("Relation Chunk",
|
||||
fields * sizeof (gpointer),
|
||||
fields * sizeof (gpointer) * 128,
|
||||
G_ALLOC_AND_FREE);
|
||||
rel->all_tuples = g_hash_table_new (tuple_hash (fields), tuple_equal (fields));
|
||||
rel->hashed_tuple_tables = g_new0 (GHashTable*, fields);
|
||||
|
||||
return (GRelation*) rel;
|
||||
}
|
||||
|
||||
static void
|
||||
g_relation_free_array (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
g_hash_table_destroy ((GHashTable*) value);
|
||||
}
|
||||
|
||||
void
|
||||
g_relation_destroy (GRelation *relation)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
gint i;
|
||||
|
||||
if (rel)
|
||||
{
|
||||
g_hash_table_destroy (rel->all_tuples);
|
||||
g_mem_chunk_destroy (rel->tuple_chunk);
|
||||
|
||||
for (i = 0; i < rel->fields; i += 1)
|
||||
{
|
||||
if (rel->hashed_tuple_tables[i])
|
||||
{
|
||||
g_hash_table_foreach (rel->hashed_tuple_tables[i], g_relation_free_array, NULL);
|
||||
g_hash_table_destroy (rel->hashed_tuple_tables[i]);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (rel->hashed_tuple_tables);
|
||||
g_free (rel);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
g_relation_index (GRelation *relation,
|
||||
gint field,
|
||||
GHashFunc hash_func,
|
||||
GCompareFunc key_compare_func)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
|
||||
g_assert (rel->count == 0 && rel->hashed_tuple_tables[field] == NULL);
|
||||
|
||||
rel->hashed_tuple_tables[field] = g_hash_table_new (hash_func, key_compare_func);
|
||||
}
|
||||
|
||||
void
|
||||
g_relation_insert (GRelation *relation,
|
||||
...)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
gpointer* tuple = g_chunk_new (gpointer, rel->tuple_chunk);
|
||||
va_list args;
|
||||
gint i;
|
||||
|
||||
va_start(args, relation);
|
||||
|
||||
for (i = 0; i < rel->fields; i += 1)
|
||||
tuple[i] = va_arg(args, gpointer);
|
||||
|
||||
va_end(args);
|
||||
|
||||
g_hash_table_insert (rel->all_tuples, tuple, tuple);
|
||||
|
||||
rel->count += 1;
|
||||
|
||||
for (i = 0; i < rel->fields; i += 1)
|
||||
{
|
||||
GHashTable *table;
|
||||
gpointer key;
|
||||
GHashTable *per_key_table;
|
||||
|
||||
table = rel->hashed_tuple_tables[i];
|
||||
|
||||
if (table == NULL)
|
||||
continue;
|
||||
|
||||
key = tuple[i];
|
||||
per_key_table = g_hash_table_lookup (table, key);
|
||||
|
||||
if (per_key_table == NULL)
|
||||
{
|
||||
per_key_table = g_hash_table_new (tuple_hash (rel->fields), tuple_equal (rel->fields));
|
||||
g_hash_table_insert (table, key, per_key_table);
|
||||
}
|
||||
|
||||
g_hash_table_insert (per_key_table, tuple, tuple);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_relation_delete_tuple (gpointer tuple_key, gpointer tuple_value, gpointer user_data)
|
||||
{
|
||||
gpointer *tuple = (gpointer*) tuple_value;
|
||||
GRealRelation *rel = (GRealRelation *) user_data;
|
||||
gint j;
|
||||
|
||||
g_assert (tuple_key == tuple_value);
|
||||
|
||||
for (j = 0; j < rel->fields; j += 1)
|
||||
{
|
||||
GHashTable *one_table = rel->hashed_tuple_tables[j];
|
||||
gpointer one_key;
|
||||
GHashTable *per_key_table;
|
||||
|
||||
if (one_table == NULL)
|
||||
continue;
|
||||
|
||||
if (j == rel->current_field)
|
||||
/* can't delete from the table we're foreaching in */
|
||||
continue;
|
||||
|
||||
one_key = tuple[j];
|
||||
|
||||
per_key_table = g_hash_table_lookup (one_table, one_key);
|
||||
|
||||
g_hash_table_remove (per_key_table, tuple);
|
||||
}
|
||||
|
||||
g_hash_table_remove (rel->all_tuples, tuple);
|
||||
|
||||
rel->count -= 1;
|
||||
}
|
||||
|
||||
gint
|
||||
g_relation_delete (GRelation *relation,
|
||||
gconstpointer key,
|
||||
gint field)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
GHashTable *table = rel->hashed_tuple_tables[field];
|
||||
GHashTable *key_table;
|
||||
gint count = rel->count;
|
||||
|
||||
g_assert (table);
|
||||
|
||||
key_table = g_hash_table_lookup (table, key);
|
||||
|
||||
if (!key_table)
|
||||
return 0;
|
||||
|
||||
rel->current_field = field;
|
||||
|
||||
g_hash_table_foreach (key_table, g_relation_delete_tuple, rel);
|
||||
|
||||
g_hash_table_remove (table, key);
|
||||
|
||||
g_hash_table_destroy (key_table);
|
||||
|
||||
/* @@@ Remove empty hash tables. */
|
||||
|
||||
return count - rel->count;
|
||||
}
|
||||
|
||||
static void
|
||||
g_relation_select_tuple (gpointer tuple_key, gpointer tuple_value, gpointer user_data)
|
||||
{
|
||||
gpointer *tuple = (gpointer*) tuple_value;
|
||||
GRealTuples *tuples = (GRealTuples*) user_data;
|
||||
gint stride = sizeof (gpointer) * tuples->width;
|
||||
|
||||
g_assert (tuple_key == tuple_value);
|
||||
|
||||
memcpy (tuples->data + (tuples->len * tuples->width),
|
||||
tuple,
|
||||
stride);
|
||||
|
||||
tuples->len += 1;
|
||||
}
|
||||
|
||||
GTuples*
|
||||
g_relation_select (GRelation *relation,
|
||||
gconstpointer key,
|
||||
gint field)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
GHashTable *table = rel->hashed_tuple_tables[field];
|
||||
GHashTable *key_table;
|
||||
GRealTuples *tuples = g_new0 (GRealTuples, 1);
|
||||
gint count;
|
||||
|
||||
g_assert (table);
|
||||
|
||||
key_table = g_hash_table_lookup (table, key);
|
||||
|
||||
if (!key_table)
|
||||
return (GTuples*)tuples;
|
||||
|
||||
count = g_relation_count (relation, key, field);
|
||||
|
||||
tuples->data = g_malloc (sizeof (gpointer) * rel->fields * count);
|
||||
tuples->width = rel->fields;
|
||||
|
||||
g_hash_table_foreach (key_table, g_relation_select_tuple, tuples);
|
||||
|
||||
g_assert (count == tuples->len);
|
||||
|
||||
return (GTuples*)tuples;
|
||||
}
|
||||
|
||||
gint
|
||||
g_relation_count (GRelation *relation,
|
||||
gconstpointer key,
|
||||
gint field)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
GHashTable *table = rel->hashed_tuple_tables[field];
|
||||
GHashTable *key_table;
|
||||
|
||||
g_assert (table);
|
||||
|
||||
key_table = g_hash_table_lookup (table, key);
|
||||
|
||||
if (!key_table)
|
||||
return 0;
|
||||
|
||||
return g_hash_table_size (key_table);
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_relation_exists (GRelation *relation, ...)
|
||||
{
|
||||
GRealRelation *rel = (GRealRelation *) relation;
|
||||
gpointer* tuple = g_chunk_new (gpointer, rel->tuple_chunk);
|
||||
va_list args;
|
||||
gint i;
|
||||
gboolean result;
|
||||
|
||||
va_start(args, relation);
|
||||
|
||||
for (i = 0; i < rel->fields; i += 1)
|
||||
tuple[i] = va_arg(args, gpointer);
|
||||
|
||||
va_end(args);
|
||||
|
||||
result = g_hash_table_lookup (rel->all_tuples, tuple) != NULL;
|
||||
|
||||
g_mem_chunk_free (rel->tuple_chunk, tuple);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
g_tuples_destroy (GTuples *tuples0)
|
||||
{
|
||||
GRealTuples *tuples = (GRealTuples*) tuples0;
|
||||
|
||||
if (tuples)
|
||||
{
|
||||
g_free (tuples->data);
|
||||
g_free (tuples);
|
||||
}
|
||||
}
|
||||
|
||||
gpointer
|
||||
g_tuples_index (GTuples *tuples0,
|
||||
gint index,
|
||||
gint field)
|
||||
{
|
||||
GRealTuples *tuples = (GRealTuples*) tuples0;
|
||||
|
||||
g_assert (field < tuples->width);
|
||||
|
||||
return tuples->data[index * tuples->width + field];
|
||||
}
|
||||
|
||||
/* Print
|
||||
*/
|
||||
|
||||
void
|
||||
g_relation_print_one (gpointer tuple_key, gpointer tuple_value, gpointer user_data)
|
||||
{
|
||||
gint i;
|
||||
GRealRelation* rel = (GRealRelation*) user_data;
|
||||
gpointer* tuples = (gpointer*) tuple_value;
|
||||
|
||||
g_print ("[");
|
||||
|
||||
for (i = 0; i < rel->fields; i += 1)
|
||||
{
|
||||
g_print ("%p", tuples[i]);
|
||||
|
||||
if (i < (rel->fields - 1))
|
||||
g_print (",");
|
||||
}
|
||||
|
||||
g_print ("]\n");
|
||||
}
|
||||
|
||||
void
|
||||
g_relation_print_index (gpointer tuple_key, gpointer tuple_value, gpointer user_data)
|
||||
{
|
||||
GRealRelation* rel = (GRealRelation*) user_data;
|
||||
GHashTable* table = (GHashTable*) tuple_value;
|
||||
|
||||
g_print ("*** key %p\n", tuple_key);
|
||||
|
||||
g_hash_table_foreach (table,
|
||||
g_relation_print_one,
|
||||
rel);
|
||||
}
|
||||
|
||||
void
|
||||
g_relation_print (GRelation *relation)
|
||||
{
|
||||
gint i;
|
||||
GRealRelation* rel = (GRealRelation*) relation;
|
||||
|
||||
g_print ("*** all tuples (%d)\n", rel->count);
|
||||
|
||||
g_hash_table_foreach (rel->all_tuples,
|
||||
g_relation_print_one,
|
||||
rel);
|
||||
|
||||
for (i = 0; i < rel->fields; i += 1)
|
||||
{
|
||||
if (rel->hashed_tuple_tables[i] == NULL)
|
||||
continue;
|
||||
|
||||
g_print ("*** index %d\n", i);
|
||||
|
||||
g_hash_table_foreach (rel->hashed_tuple_tables[i],
|
||||
g_relation_print_index,
|
||||
rel);
|
||||
}
|
||||
|
||||
}
|
@ -16,12 +16,12 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include <glib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "glib.h"
|
||||
|
||||
|
||||
typedef struct _GRealStringChunk GRealStringChunk;
|
||||
|
21
gutils.c
21
gutils.c
@ -851,8 +851,25 @@ g_parse_debug_string (const gchar *string,
|
||||
}
|
||||
|
||||
guint
|
||||
g_direct_hash(gconstpointer key)
|
||||
g_direct_hash(gconstpointer v)
|
||||
{
|
||||
return GPOINTER_TO_UINT (key);
|
||||
return GPOINTER_TO_UINT (v);
|
||||
}
|
||||
|
||||
gint
|
||||
g_direct_equal(gconstpointer v, gconstpointer v2)
|
||||
{
|
||||
return GPOINTER_TO_UINT (v) == GPOINTER_TO_UINT (v2);
|
||||
}
|
||||
|
||||
gint
|
||||
g_int_equal (gconstpointer v, gconstpointer v2)
|
||||
{
|
||||
return *((const gint*) v) == *((const gint*) v2);
|
||||
}
|
||||
|
||||
guint
|
||||
g_int_hash (gconstpointer v)
|
||||
{
|
||||
return *(const gint*) v;
|
||||
}
|
||||
|
109
testglib.c
109
testglib.c
@ -104,9 +104,14 @@ main (int argc,
|
||||
gchar *mem[10000], *tmp_string, *tmp_string_2;
|
||||
gint i, j;
|
||||
GArray *garray;
|
||||
GPtrArray *gparray;
|
||||
GByteArray *gbarray;
|
||||
GString *string1, *string2;
|
||||
GTree *tree;
|
||||
char chars[62];
|
||||
GRelation *relation;
|
||||
GTuples *tuples;
|
||||
gint data [1024];
|
||||
|
||||
g_print ("checking size of gint8...%ld (should be 1)\n", (glong)sizeof (gint8));
|
||||
g_print ("checking size of gint16...%ld (should be 2)\n", (glong)sizeof (gint16));
|
||||
@ -396,6 +401,110 @@ main (int argc,
|
||||
|
||||
/* g_debug (argv[0]); */
|
||||
|
||||
/* Relation tests */
|
||||
|
||||
g_print ("checking relations...");
|
||||
|
||||
relation = g_relation_new (2);
|
||||
|
||||
g_relation_index (relation, 0, g_int_hash, g_int_equal);
|
||||
g_relation_index (relation, 1, g_int_hash, g_int_equal);
|
||||
|
||||
for (i = 0; i < 1024; i += 1)
|
||||
data[i] = i;
|
||||
|
||||
for (i = 1; i < 1023; i += 1)
|
||||
{
|
||||
g_relation_insert (relation, data + i, data + i + 1);
|
||||
g_relation_insert (relation, data + i, data + i - 1);
|
||||
}
|
||||
|
||||
for (i = 2; i < 1022; i += 1)
|
||||
{
|
||||
g_assert (! g_relation_exists (relation, data + i, data + i));
|
||||
g_assert (! g_relation_exists (relation, data + i, data + i + 2));
|
||||
g_assert (! g_relation_exists (relation, data + i, data + i - 2));
|
||||
}
|
||||
|
||||
for (i = 1; i < 1023; i += 1)
|
||||
{
|
||||
g_assert (g_relation_exists (relation, data + i, data + i + 1));
|
||||
g_assert (g_relation_exists (relation, data + i, data + i - 1));
|
||||
}
|
||||
|
||||
for (i = 2; i < 1022; i += 1)
|
||||
{
|
||||
g_assert (g_relation_count (relation, data + i, 0) == 2);
|
||||
g_assert (g_relation_count (relation, data + i, 1) == 2);
|
||||
}
|
||||
|
||||
g_assert (g_relation_count (relation, data, 0) == 0);
|
||||
|
||||
g_assert (g_relation_count (relation, data + 42, 0) == 2);
|
||||
g_assert (g_relation_count (relation, data + 43, 1) == 2);
|
||||
g_assert (g_relation_count (relation, data + 41, 1) == 2);
|
||||
g_relation_delete (relation, data + 42, 0);
|
||||
g_assert (g_relation_count (relation, data + 42, 0) == 0);
|
||||
g_assert (g_relation_count (relation, data + 43, 1) == 1);
|
||||
g_assert (g_relation_count (relation, data + 41, 1) == 1);
|
||||
|
||||
tuples = g_relation_select (relation, data + 200, 0);
|
||||
|
||||
g_assert (tuples->len == 2);
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < tuples->len; i += 1)
|
||||
{
|
||||
printf ("%d %d\n",
|
||||
*(gint*) g_tuples_index (tuples, i, 0),
|
||||
*(gint*) g_tuples_index (tuples, i, 1));
|
||||
}
|
||||
#endif
|
||||
|
||||
g_assert (g_relation_exists (relation, data + 300, data + 301));
|
||||
g_relation_delete (relation, data + 300, 0);
|
||||
g_assert (!g_relation_exists (relation, data + 300, data + 301));
|
||||
|
||||
g_tuples_destroy (tuples);
|
||||
|
||||
g_relation_destroy (relation);
|
||||
|
||||
relation = NULL;
|
||||
|
||||
g_print ("ok\n");
|
||||
|
||||
g_print ("checking pointer arrays...");
|
||||
|
||||
gparray = g_ptr_array_new ();
|
||||
for (i = 0; i < 10000; i++)
|
||||
g_ptr_array_add (gparray, (void*)i);
|
||||
|
||||
for (i = 0; i < 10000; i++)
|
||||
if (g_ptr_array_index (gparray, i) != (void*)i)
|
||||
g_print ("array fails: %p ( %p )\n", g_ptr_array_index (gparray, i), (void*)i);
|
||||
|
||||
g_ptr_array_free (gparray, TRUE);
|
||||
|
||||
g_print ("ok\n");
|
||||
|
||||
|
||||
g_print ("checking byte arrays...");
|
||||
|
||||
gbarray = g_byte_array_new ();
|
||||
for (i = 0; i < 10000; i++)
|
||||
g_byte_array_append (gbarray, "abcd", 4);
|
||||
|
||||
for (i = 0; i < 10000; i++)
|
||||
{
|
||||
g_assert (gbarray->data[4*i] == 'a');
|
||||
g_assert (gbarray->data[4*i+1] == 'b');
|
||||
g_assert (gbarray->data[4*i+2] == 'c');
|
||||
g_assert (gbarray->data[4*i+3] == 'd');
|
||||
}
|
||||
|
||||
g_byte_array_free (gbarray, TRUE);
|
||||
|
||||
g_print ("ok\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
109
tests/testglib.c
109
tests/testglib.c
@ -104,9 +104,14 @@ main (int argc,
|
||||
gchar *mem[10000], *tmp_string, *tmp_string_2;
|
||||
gint i, j;
|
||||
GArray *garray;
|
||||
GPtrArray *gparray;
|
||||
GByteArray *gbarray;
|
||||
GString *string1, *string2;
|
||||
GTree *tree;
|
||||
char chars[62];
|
||||
GRelation *relation;
|
||||
GTuples *tuples;
|
||||
gint data [1024];
|
||||
|
||||
g_print ("checking size of gint8...%ld (should be 1)\n", (glong)sizeof (gint8));
|
||||
g_print ("checking size of gint16...%ld (should be 2)\n", (glong)sizeof (gint16));
|
||||
@ -396,6 +401,110 @@ main (int argc,
|
||||
|
||||
/* g_debug (argv[0]); */
|
||||
|
||||
/* Relation tests */
|
||||
|
||||
g_print ("checking relations...");
|
||||
|
||||
relation = g_relation_new (2);
|
||||
|
||||
g_relation_index (relation, 0, g_int_hash, g_int_equal);
|
||||
g_relation_index (relation, 1, g_int_hash, g_int_equal);
|
||||
|
||||
for (i = 0; i < 1024; i += 1)
|
||||
data[i] = i;
|
||||
|
||||
for (i = 1; i < 1023; i += 1)
|
||||
{
|
||||
g_relation_insert (relation, data + i, data + i + 1);
|
||||
g_relation_insert (relation, data + i, data + i - 1);
|
||||
}
|
||||
|
||||
for (i = 2; i < 1022; i += 1)
|
||||
{
|
||||
g_assert (! g_relation_exists (relation, data + i, data + i));
|
||||
g_assert (! g_relation_exists (relation, data + i, data + i + 2));
|
||||
g_assert (! g_relation_exists (relation, data + i, data + i - 2));
|
||||
}
|
||||
|
||||
for (i = 1; i < 1023; i += 1)
|
||||
{
|
||||
g_assert (g_relation_exists (relation, data + i, data + i + 1));
|
||||
g_assert (g_relation_exists (relation, data + i, data + i - 1));
|
||||
}
|
||||
|
||||
for (i = 2; i < 1022; i += 1)
|
||||
{
|
||||
g_assert (g_relation_count (relation, data + i, 0) == 2);
|
||||
g_assert (g_relation_count (relation, data + i, 1) == 2);
|
||||
}
|
||||
|
||||
g_assert (g_relation_count (relation, data, 0) == 0);
|
||||
|
||||
g_assert (g_relation_count (relation, data + 42, 0) == 2);
|
||||
g_assert (g_relation_count (relation, data + 43, 1) == 2);
|
||||
g_assert (g_relation_count (relation, data + 41, 1) == 2);
|
||||
g_relation_delete (relation, data + 42, 0);
|
||||
g_assert (g_relation_count (relation, data + 42, 0) == 0);
|
||||
g_assert (g_relation_count (relation, data + 43, 1) == 1);
|
||||
g_assert (g_relation_count (relation, data + 41, 1) == 1);
|
||||
|
||||
tuples = g_relation_select (relation, data + 200, 0);
|
||||
|
||||
g_assert (tuples->len == 2);
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < tuples->len; i += 1)
|
||||
{
|
||||
printf ("%d %d\n",
|
||||
*(gint*) g_tuples_index (tuples, i, 0),
|
||||
*(gint*) g_tuples_index (tuples, i, 1));
|
||||
}
|
||||
#endif
|
||||
|
||||
g_assert (g_relation_exists (relation, data + 300, data + 301));
|
||||
g_relation_delete (relation, data + 300, 0);
|
||||
g_assert (!g_relation_exists (relation, data + 300, data + 301));
|
||||
|
||||
g_tuples_destroy (tuples);
|
||||
|
||||
g_relation_destroy (relation);
|
||||
|
||||
relation = NULL;
|
||||
|
||||
g_print ("ok\n");
|
||||
|
||||
g_print ("checking pointer arrays...");
|
||||
|
||||
gparray = g_ptr_array_new ();
|
||||
for (i = 0; i < 10000; i++)
|
||||
g_ptr_array_add (gparray, (void*)i);
|
||||
|
||||
for (i = 0; i < 10000; i++)
|
||||
if (g_ptr_array_index (gparray, i) != (void*)i)
|
||||
g_print ("array fails: %p ( %p )\n", g_ptr_array_index (gparray, i), (void*)i);
|
||||
|
||||
g_ptr_array_free (gparray, TRUE);
|
||||
|
||||
g_print ("ok\n");
|
||||
|
||||
|
||||
g_print ("checking byte arrays...");
|
||||
|
||||
gbarray = g_byte_array_new ();
|
||||
for (i = 0; i < 10000; i++)
|
||||
g_byte_array_append (gbarray, "abcd", 4);
|
||||
|
||||
for (i = 0; i < 10000; i++)
|
||||
{
|
||||
g_assert (gbarray->data[4*i] == 'a');
|
||||
g_assert (gbarray->data[4*i+1] == 'b');
|
||||
g_assert (gbarray->data[4*i+2] == 'c');
|
||||
g_assert (gbarray->data[4*i+3] == 'd');
|
||||
}
|
||||
|
||||
g_byte_array_free (gbarray, TRUE);
|
||||
|
||||
g_print ("ok\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user