g_ptr_array bsearch & etc [RESEND]
- From: Joshua N Pritikin <vishnu pobox com>
- To: gtk-devel-list gnome org
- Subject: g_ptr_array bsearch & etc [RESEND]
- Date: Tue, 21 Aug 2001 19:06:36 +0530
Can the following be added to g_ptr_array?
gboolean
g_ptr_array_bsearch (GPtrArray * array,
guint * ret,
gconstpointer sample,
GCompareFunc compare_func);
void
g_ptr_array_add_index (GPtrArray * array,
guint index,
gpointer data);
void
g_ptr_array_add_sorted (GPtrArray * array,
gpointer data,
GCompareFunc compare_func);
Implementation and test suite are attached.
--
Get self-realization at <http://sahajayoga.org> ... <http://why-compete.org> ?
Victory to the Divine Mother!!
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
gint strcmp_count=0;
// ---------------------------- copied from garray.c
typedef struct _GRealPtrArray GRealPtrArray;
struct _GRealPtrArray
{
gpointer *pdata;
guint len;
guint alloc;
};
static gint
g_nearest_pow (gint num)
{
gint n = 1;
while (n < num)
n <<= 1;
return n;
}
static void
g_ptr_array_maybe_expand (GRealPtrArray *array,
gint len)
{
if ((array->len + len) > array->alloc)
{
#ifdef ENABLE_GC_FRIENDLY
guint old_alloc = array->alloc;
#endif /* ENABLE_GC_FRIENDLY */
array->alloc = g_nearest_pow (array->len + len);
array->alloc = MAX (array->alloc, 16);
array->pdata = g_realloc (array->pdata, sizeof(gpointer) * array->alloc);
#ifdef ENABLE_GC_FRIENDLY
for ( ; old_alloc < array->alloc; old_alloc++)
array->pdata [old_alloc] = NULL;
#endif /* ENABLE_GC_FRIENDLY */
}
}
// ----------------------------
gboolean
g_ptr_array_bsearch (GPtrArray * array,
guint * ret,
gconstpointer sample,
GCompareFunc compare_func)
{
guint first, last;
guint mid;
guint midsize;
gint cmp;
guint tx;
if (!array->len)
{
*ret = 0;
return FALSE;
}
first = 0;
last = array->len - 1;
midsize = last - first;
while (midsize > 1) {
mid = first + midsize / 2;
cmp = compare_func (sample, g_ptr_array_index (array, mid));
if (cmp == 0)
{
*ret = mid;
return TRUE;
}
if (cmp < 0)
last = mid-1;
else
first = mid+1;
midsize = last - first;
}
for (tx = first; tx <= last; tx++)
{
cmp = compare_func (sample, g_ptr_array_index (array, tx));
if (cmp < 0)
{
*ret = tx;
return FALSE;
}
if (cmp == 0)
{
*ret = tx;
return TRUE;
}
}
*ret = last+1;
return FALSE;
}
void
g_ptr_array_add_index (GPtrArray * array,
guint index,
gpointer data)
{
g_return_if_fail (array);
g_ptr_array_maybe_expand (array, 1);
g_memmove (&g_ptr_array_index (array, 1 + index),
&g_ptr_array_index (array, index),
sizeof(gpointer) * (array->len - index));
g_ptr_array_index (array, index) = data;
array->len += 1;
}
void
g_ptr_array_add_sorted (GPtrArray * array,
gpointer data,
GCompareFunc compare_func)
{
guint at;
if (g_ptr_array_bsearch (array, &at, data, compare_func))
++at; // reduce memmove
g_ptr_array_add_index (array, at, data);
}
// -----------------------------------------
gint count_strcmp (gchar *s1, gchar *s2)
{
++strcmp_count;
return strcmp(s1, s2);
}
gint indirect_strcmp (gchar **s1, gchar **s2)
{ return strcmp(*s1, *s2); }
gint simple_strcmp (gchar *s1, gchar *s2)
{ return strcmp(s1, s2); }
int
main(int argc, char *argv[])
{
FILE *file;
GPtrArray *dict;
GPtrArray *disorder;
GPtrArray *subset;
int xx;
const gint bufsize = 100;
gchar buf[bufsize];
GRand *rand;
gint bsearch_count = 0;
int word_count = argv[1]? atoi (argv[1]) : 50;
rand = g_rand_new_with_seed (0);
file = fopen("/usr/share/dict/words", "r");
g_assert (file);
dict = g_ptr_array_new ();
disorder = g_ptr_array_new ();
subset = g_ptr_array_new ();
for (xx=0; xx < word_count; xx++) {
gchar *ready;
fgets(buf, bufsize, file);
g_strchomp (buf);
ready = g_strdup(buf);
g_ptr_array_add (dict, ready);
if (xx && xx < word_count-1 && g_rand_int_range(rand, 0,10))
g_ptr_array_add (disorder, ready);
}
while (disorder->len)
{
guint from;
from = g_rand_int_range(rand, 0, disorder->len);
g_ptr_array_add_sorted (subset,
g_ptr_array_index (disorder, from),
(GCompareFunc) simple_strcmp);
g_ptr_array_remove_index (disorder, from);
}
for (xx=0; xx < dict->len; xx++)
{
glong rx;
guint at;
gboolean match;
++ bsearch_count;
match = g_ptr_array_bsearch (subset,
&at,
g_ptr_array_index(dict, xx),
(GCompareFunc) count_strcmp);
if (match)
{
if (strcmp(g_ptr_array_index (subset, at),
g_ptr_array_index(dict, xx)) == 0)
continue;
}
else
{
if (at > 0 && at < subset->len &&
strcmp(g_ptr_array_index (subset, at-1),
g_ptr_array_index(dict, xx)) < 0 &&
strcmp(g_ptr_array_index(dict, xx),
g_ptr_array_index (subset, at)) < 0)
continue;
if (at == 0 &&
strcmp(g_ptr_array_index(dict, xx),
g_ptr_array_index (subset, at)) < 0)
continue;
if (at == subset->len &&
strcmp(g_ptr_array_index (subset, at-1),
g_ptr_array_index(dict, xx)) < 0)
continue;
}
g_print ("\n%d> %s\n", match, (gchar*) g_ptr_array_index(dict, xx));
if (match)
{
for (rx = at-1; rx <= at+1; rx++) {
if (rx < 0)
{ g_print ("---\n"); continue; }
if (rx >= subset->len)
{ g_print ("-+-\n"); continue; }
g_print ("%s\n", (gchar*) g_ptr_array_index(subset, rx));
}
}
else
{
for (rx = ((glong)at)-1; rx <= at; rx++) {
if (rx < 0)
{ g_print ("---\n"); continue; }
if (rx >= subset->len)
{ g_print ("-+-\n"); continue; }
g_print ("%s\n", (gchar*) g_ptr_array_index(subset, rx));
}
}
}
g_print ("%d / %d = %.2f\n",
strcmp_count, bsearch_count, strcmp_count / (double) bsearch_count);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]