blob: 9b483390914880e23c4c0e17b9209d2a7deb06ad [file] [log] [blame]
/* gheap.c
*
* Copyright (C) 2014 Christian Hergert <christian@hergert.me>
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <glib.h>
typedef struct
{
gint64 size;
gpointer pointer;
} Tuple;
static int
cmpint_rev (gconstpointer a,
gconstpointer b)
{
return *(const gint *)b - *(const gint *)a;
}
static int
cmpptr_rev (gconstpointer a,
gconstpointer b)
{
return GPOINTER_TO_SIZE(*(gpointer *)b) - GPOINTER_TO_SIZE (*(gpointer *)a);
}
static int
cmptuple_rev (gconstpointer a,
gconstpointer b)
{
Tuple *at = (Tuple *)a;
Tuple *bt = (Tuple *)b;
return bt->size - at->size;
}
static void
test_GHeap_insert_val_int (void)
{
GHeap *heap;
gint i;
heap = g_heap_new (sizeof (gint), cmpint_rev);
for (i = 0; i < 100000; i++) {
g_heap_insert_val (heap, i);
g_assert_cmpint (heap->len, ==, i + 1);
}
for (i = 0; i < 100000; i++) {
g_assert_cmpint (heap->len, ==, 100000 - i);
g_assert_cmpint (g_heap_peek (heap, gint), ==, i);
g_heap_extract (heap, NULL);
}
g_heap_unref (heap);
}
static void
test_GHeap_insert_val_ptr (void)
{
gconstpointer ptr;
GHeap *heap;
gint i;
heap = g_heap_new (sizeof (gpointer), cmpptr_rev);
for (i = 0; i < 100000; i++) {
ptr = GINT_TO_POINTER (i);
g_heap_insert_val (heap, ptr);
g_assert_cmpint (heap->len, ==, i + 1);
}
for (i = 0; i < 100000; i++) {
g_assert_cmpint (heap->len, ==, 100000 - i);
g_assert (g_heap_peek (heap, gpointer) == GINT_TO_POINTER (i));
g_heap_extract (heap, NULL);
}
g_heap_unref (heap);
}
static void
test_GHeap_insert_val_tuple (void)
{
Tuple t;
GHeap *heap;
gint i;
heap = g_heap_new (sizeof (Tuple), cmptuple_rev);
for (i = 0; i < 100000; i++) {
t.pointer = GINT_TO_POINTER (i);
t.size = i;
g_heap_insert_val (heap, t);
g_assert_cmpint (heap->len, ==, i + 1);
}
for (i = 0; i < 100000; i++) {
g_assert_cmpint (heap->len, ==, 100000 - i);
g_assert (g_heap_peek (heap, Tuple).size == i);
g_assert (g_heap_peek (heap, Tuple).pointer == GINT_TO_POINTER (i));
g_heap_extract (heap, NULL);
}
g_heap_unref (heap);
}
static void
test_GHeap_extract_int (void)
{
GHeap *heap;
gint removed[5];
gint i;
gint v;
heap = g_heap_new (sizeof (gint), cmpint_rev);
for (i = 0; i < 100000; i++) {
g_heap_insert_val (heap, i);
}
removed [0] = g_heap_index (heap, gint, 1578); g_heap_extract_index (heap, 1578, NULL);
removed [1] = g_heap_index (heap, gint, 2289); g_heap_extract_index (heap, 2289, NULL);
removed [2] = g_heap_index (heap, gint, 3312); g_heap_extract_index (heap, 3312, NULL);
removed [3] = g_heap_index (heap, gint, 78901); g_heap_extract_index (heap, 78901, NULL);
removed [4] = g_heap_index (heap, gint, 99000); g_heap_extract_index (heap, 99000, NULL);
for (i = 0; i < 100000; i++) {
if (g_heap_peek (heap, gint) != i) {
g_assert ((i == removed[0]) ||
(i == removed[1]) ||
(i == removed[2]) ||
(i == removed[3]) ||
(i == removed[4]));
} else {
g_heap_extract (heap, &v);
g_assert_cmpint (v, ==, i);
}
}
g_assert_cmpint (heap->len, ==, 0);
g_heap_unref (heap);
}
int
main (gint argc,
gchar *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/GHeap/insert_and_extract<gint>", test_GHeap_insert_val_int);
g_test_add_func ("/GHeap/insert_and_extract<gpointer>", test_GHeap_insert_val_ptr);
g_test_add_func ("/GHeap/insert_and_extract<Tuple>", test_GHeap_insert_val_tuple);
g_test_add_func ("/GHeap/extract_index<int>", test_GHeap_extract_int);
return g_test_run ();
}