From b177573b729401117a061cd6f07743fa81c01724 Mon Sep 17 00:00:00 2001 From: Joonas Pihlaja Date: Mon, 20 Nov 2006 03:56:07 +0200 Subject: [PATCH] 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. --- src/cairo-bentley-ottmann.c | 12 ++++-------- src/cairo-skiplist-private.h | 8 +++++--- src/cairo-skiplist.c | 25 +++++++++++++++---------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c index d3cdce43e..c959e2f90 100644 --- a/src/cairo-bentley-ottmann.c +++ b/src/cairo-bentley-ottmann.c @@ -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) diff --git a/src/cairo-skiplist-private.h b/src/cairo-skiplist-private.h index 4cbbf0941..d4333986c 100644 --- a/src/cairo-skiplist-private.h +++ b/src/cairo-skiplist-private.h @@ -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 - * 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 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 */ void * diff --git a/src/cairo-skiplist.c b/src/cairo-skiplist.c index 7a542d9e6..6dc4e3c20 100644 --- a/src/cairo-skiplist.c +++ b/src/cairo-skiplist.c @@ -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