selector: Redo from list to array

Should save ~30% of memory
This commit is contained in:
Benjamin Otte 2012-03-01 18:33:33 +01:00
parent ae1cd1b354
commit 0a5b42c4fc

View File

@ -19,6 +19,8 @@
#include "gtkcssselectorprivate.h" #include "gtkcssselectorprivate.h"
#include <string.h>
#include "gtkcssprovider.h" #include "gtkcssprovider.h"
#include "gtkstylecontextprivate.h" #include "gtkstylecontextprivate.h"
@ -42,7 +44,6 @@ struct _GtkCssSelectorClass {
struct _GtkCssSelector struct _GtkCssSelector
{ {
const GtkCssSelectorClass *class; /* type of check this selector does */ const GtkCssSelectorClass *class; /* type of check this selector does */
GtkCssSelector *previous; /* link to next element in selector or NULL if last */
gconstpointer data; /* data for matching: gconstpointer data; /* data for matching:
- interned string for CLASS, NAME and ID - interned string for CLASS, NAME and ID
- GUINT_TO_POINTER() for PSEUDOCLASS_REGION/STATE */ - GUINT_TO_POINTER() for PSEUDOCLASS_REGION/STATE */
@ -63,7 +64,9 @@ gtk_css_selector_match (const GtkCssSelector *selector,
static const GtkCssSelector * static const GtkCssSelector *
gtk_css_selector_previous (const GtkCssSelector *selector) gtk_css_selector_previous (const GtkCssSelector *selector)
{ {
return selector->previous; selector = selector + 1;
return selector->class ? selector : NULL;
} }
/* ANY */ /* ANY */
@ -445,16 +448,35 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_PSEUDOCLASS_REGION = {
/* API */ /* API */
static guint
gtk_css_selector_size (const GtkCssSelector *selector)
{
guint size = 0;
while (selector)
{
selector = gtk_css_selector_previous (selector);
size++;
}
return size;
}
static GtkCssSelector * static GtkCssSelector *
gtk_css_selector_new (const GtkCssSelectorClass *class, gtk_css_selector_new (const GtkCssSelectorClass *class,
GtkCssSelector *previous, GtkCssSelector *selector,
gconstpointer data) gconstpointer data)
{ {
GtkCssSelector *selector; guint size;
size = gtk_css_selector_size (selector);
selector = g_realloc (selector, sizeof (GtkCssSelector) * (size + 1) + sizeof (gpointer));
if (size == 0)
selector[1].class = NULL;
else
memmove (selector + 1, selector, sizeof (GtkCssSelector) * size + sizeof (gpointer));
selector = g_slice_new0 (GtkCssSelector);
selector->class = class; selector->class = class;
selector->previous = previous;
selector->data = data; selector->data = data;
return selector; return selector;
@ -655,9 +677,9 @@ try_parse_name (GtkCssParser *parser,
static GtkCssSelector * static GtkCssSelector *
parse_simple_selector (GtkCssParser *parser, parse_simple_selector (GtkCssParser *parser,
GtkCssSelector *previous) GtkCssSelector *selector)
{ {
GtkCssSelector *selector = previous; guint size = gtk_css_selector_size (selector);
selector = try_parse_name (parser, selector); selector = try_parse_name (parser, selector);
@ -668,12 +690,12 @@ parse_simple_selector (GtkCssParser *parser,
selector = parse_selector_class (parser, selector); selector = parse_selector_class (parser, selector);
else if (_gtk_css_parser_try (parser, ":", FALSE)) else if (_gtk_css_parser_try (parser, ":", FALSE))
selector = parse_selector_pseudo_class (parser, selector); selector = parse_selector_pseudo_class (parser, selector);
else if (selector == previous) else if (gtk_css_selector_size (selector) == size)
{ {
_gtk_css_parser_error (parser, "Expected a valid selector"); _gtk_css_parser_error (parser, "Expected a valid selector");
if (selector) if (selector)
_gtk_css_selector_free (selector); _gtk_css_selector_free (selector);
selector = NULL; return NULL;
} }
else else
break; break;
@ -709,10 +731,7 @@ _gtk_css_selector_free (GtkCssSelector *selector)
{ {
g_return_if_fail (selector != NULL); g_return_if_fail (selector != NULL);
if (selector->previous) g_free (selector);
_gtk_css_selector_free (selector->previous);
g_slice_free (GtkCssSelector, selector);
} }
void void