Make the skip list check for uniqueness.

This patch removes a redundant call to skip_list_find()
that was being used to detect duplicate intersection events.
Instead, skip_list_insert() now takes an additional parameter
letting it know what to do with duplicates.
This commit is contained in:
Joonas Pihlaja 2006-11-20 03:56:07 +02:00 committed by Carl Worth
parent 8bec0bac56
commit b177573b72
3 changed files with 24 additions and 21 deletions

View file

@ -660,13 +660,8 @@ _cairo_bo_event_queue_insert (cairo_bo_event_queue_t *queue,
cairo_bo_event_t *event)
{
/* Don't insert if there's already an equivalent intersection event in the queue. */
if (event->type == CAIRO_BO_EVENT_TYPE_INTERSECTION &&
skip_list_find (&queue->intersection_queue, event) != NULL)
{
return;
}
skip_list_insert (&queue->intersection_queue, event);
skip_list_insert (&queue->intersection_queue, event,
event->type == CAIRO_BO_EVENT_TYPE_INTERSECTION);
}
static void
@ -819,7 +814,8 @@ _cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t *sweep_line,
sweep_line_elt_t *sweep_line_elt;
cairo_bo_edge_t **prev_of_next, **next_of_prev;
sweep_line_elt = skip_list_insert (&sweep_line->active_edges, &edge);
sweep_line_elt = skip_list_insert (&sweep_line->active_edges, &edge,
1 /* unique inserts*/);
next_elt = sweep_line_elt->elt.next[0];
if (next_elt)

View file

@ -75,10 +75,12 @@ void
skip_list_fini (skip_list_t *list);
/* Insert a new element into the list at the correct sort order as
* determined by compare. Data will be copied (elt_size bytes from
* <data> via memcpy). The new element is returned. */
* determined by compare. If unique is true, then duplicate elements
* are ignored and the already inserted element is returned.
* Otherwise data will be copied (elt_size bytes from <data> via
* memcpy) and the new element is returned. */
void *
skip_list_insert (skip_list_t *list, void *data);
skip_list_insert (skip_list_t *list, void *data, int unique);
/* Find an element which compare considers equal to <data> */
void *

View file

@ -304,32 +304,36 @@ free_elt (skip_list_t *list, skip_elt_t *elt)
* Insert 'data' into the list
*/
void *
skip_list_insert (skip_list_t *list, void *data)
skip_list_insert (skip_list_t *list, void *data, int unique)
{
skip_elt_t **update[MAX_LEVEL];
skip_elt_t *prev[MAX_LEVEL];
char *data_and_elt;
skip_elt_t *elt, *prev, **next;
skip_elt_t *elt, **next;
int i, level, prev_index;
level = random_level ();
prev_index = level - 1;
/*
* Find links along each chain
*/
prev = NULL;
next = list->chains;
for (i = list->max_level; --i >= 0; )
{
for (; (elt = next[i]); next = elt->next)
{
if (list->compare (list, ELT_DATA(elt), data) > 0)
int cmp = list->compare (list, ELT_DATA(elt), data);
if (unique && 0 == cmp)
return ELT_DATA(elt);
if (cmp > 0)
break;
}
update[i] = next;
if (i == prev_index && next != list->chains)
prev = NEXT_TO_ELT (next);
if (next != list->chains)
prev[i] = NEXT_TO_ELT (next);
else
prev[i] = NULL;
}
level = random_level ();
prev_index = level - 1;
/*
* Create new list element
@ -338,6 +342,7 @@ skip_list_insert (skip_list_t *list, void *data)
{
level = list->max_level + 1;
prev_index = level - 1;
prev[prev_index] = NULL;
update[list->max_level] = list->chains;
list->max_level = level;
}
@ -347,7 +352,7 @@ skip_list_insert (skip_list_t *list, void *data)
elt = (skip_elt_t *) (data_and_elt + list->data_size);
elt->prev_index = prev_index;
elt->prev = prev;
elt->prev = prev[prev_index];
/*
* Insert into all chains