[gtk+] selector: Redo from list to array



commit 0a5b42c4fc69b2f83cbef2d163e53b28aa1babfd
Author: Benjamin Otte <otte redhat com>
Date:   Thu Mar 1 18:33:33 2012 +0100

    selector: Redo from list to array
    
    Should save ~30% of memory

 gtk/gtkcssselector.c |   47 +++++++++++++++++++++++++++++++++--------------
 1 files changed, 33 insertions(+), 14 deletions(-)
---
diff --git a/gtk/gtkcssselector.c b/gtk/gtkcssselector.c
index 8a52b60..1a2b1d4 100644
--- a/gtk/gtkcssselector.c
+++ b/gtk/gtkcssselector.c
@@ -19,6 +19,8 @@
 
 #include "gtkcssselectorprivate.h"
 
+#include <string.h>
+
 #include "gtkcssprovider.h"
 #include "gtkstylecontextprivate.h"
 
@@ -42,7 +44,6 @@ struct _GtkCssSelectorClass {
 struct _GtkCssSelector
 {
   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:
                                              - interned string for CLASS, NAME and ID
                                              - GUINT_TO_POINTER() for PSEUDOCLASS_REGION/STATE */
@@ -63,7 +64,9 @@ gtk_css_selector_match (const GtkCssSelector *selector,
 static const GtkCssSelector *
 gtk_css_selector_previous (const GtkCssSelector *selector)
 {
-  return selector->previous;
+  selector = selector + 1;
+
+  return selector->class ? selector : NULL;
 }
 
 /* ANY */
@@ -445,16 +448,35 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_PSEUDOCLASS_REGION = {
 
 /* 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 *
 gtk_css_selector_new (const GtkCssSelectorClass *class,
-                      GtkCssSelector            *previous,
+                      GtkCssSelector            *selector,
                       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->previous = previous;
   selector->data = data;
 
   return selector;
@@ -655,9 +677,9 @@ try_parse_name (GtkCssParser   *parser,
 
 static GtkCssSelector *
 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);
 
@@ -668,12 +690,12 @@ parse_simple_selector (GtkCssParser   *parser,
         selector = parse_selector_class (parser, selector);
       else if (_gtk_css_parser_try (parser, ":", FALSE))
         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");
           if (selector)
             _gtk_css_selector_free (selector);
-          selector = NULL;
+          return NULL;
         }
       else
         break;
@@ -709,10 +731,7 @@ _gtk_css_selector_free (GtkCssSelector *selector)
 {
   g_return_if_fail (selector != NULL);
 
-  if (selector->previous)
-    _gtk_css_selector_free (selector->previous);
-
-  g_slice_free (GtkCssSelector, selector);
+  g_free (selector);
 }
 
 void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]