[gegl] graph: cache output visitables of GeglNode



commit 856b32395789b1307fc2902e4f804a8b99526792
Author: Ell <ell_se yahoo com>
Date:   Sun Nov 12 10:33:34 2017 -0500

    graph: cache output visitables of GeglNode
    
    Have each GeglNode maintain a unique GeglNodeOutputVisitable
    member, adapting itself into an output visitable, which can then be
    used by GeglNodeOutputVisitable::depends_on(), instead of having it
    construct output visitables on-the-fly and maintain their
    uniqueness.

 gegl/graph/gegl-node-output-visitable.c |   76 ++++++-------------------------
 gegl/graph/gegl-node-output-visitable.h |    8 +---
 gegl/graph/gegl-node-private.h          |    8 +++
 gegl/graph/gegl-node.c                  |   22 +++++++---
 4 files changed, 41 insertions(+), 73 deletions(-)
---
diff --git a/gegl/graph/gegl-node-output-visitable.c b/gegl/graph/gegl-node-output-visitable.c
index be164be..68a238c 100644
--- a/gegl/graph/gegl-node-output-visitable.c
+++ b/gegl/graph/gegl-node-output-visitable.c
@@ -31,16 +31,13 @@
 #include "gegl-visitor.h"
 
 
-static void                      gegl_node_output_visitable_class_init           
(GeglNodeOutputVisitableClass *klass);
-static void                      gegl_node_output_visitable_init                 (GeglNodeOutputVisitable    
  *self);
-static void                      gegl_node_output_visitable_finalize             (GObject                    
  *object);
-static void                      gegl_node_output_visitable_visitable_iface_init (gpointer                   
   ginterface,
-                                                                                  gpointer                   
   interface_data);
-static gboolean                  gegl_node_output_visitable_visitable_accept     (GeglVisitable              
  *visitable,
-                                                                                  GeglVisitor                
  *visitor);
-static GSList                  * gegl_node_output_visitable_visitable_depends_on (GeglVisitable              
  *visitable);
-
-static GeglNodeOutputVisitable * _gegl_node_output_visitable_new                 (GeglNode                   
  *node);
+static void       gegl_node_output_visitable_class_init           (GeglNodeOutputVisitableClass *klass);
+static void       gegl_node_output_visitable_init                 (GeglNodeOutputVisitable      *self);
+static void       gegl_node_output_visitable_visitable_iface_init (gpointer                      ginterface,
+                                                                   gpointer                      
interface_data);
+static gboolean   gegl_node_output_visitable_visitable_accept     (GeglVisitable                *visitable,
+                                                                   GeglVisitor                  *visitor);
+static GSList   * gegl_node_output_visitable_visitable_depends_on (GeglVisitable                *visitable);
 
 
 G_DEFINE_TYPE_WITH_CODE (GeglNodeOutputVisitable, gegl_node_output_visitable, G_TYPE_OBJECT,
@@ -51,16 +48,12 @@ G_DEFINE_TYPE_WITH_CODE (GeglNodeOutputVisitable, gegl_node_output_visitable, G_
 static void
 gegl_node_output_visitable_class_init (GeglNodeOutputVisitableClass *klass)
 {
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
-  gobject_class->finalize = gegl_node_output_visitable_finalize;
 }
 
 static void
 gegl_node_output_visitable_init (GeglNodeOutputVisitable *self)
 {
-  self->node       = NULL;
-  self->visitables = NULL;
+  self->node = NULL;
 }
 
 static void
@@ -73,17 +66,6 @@ gegl_node_output_visitable_visitable_iface_init (gpointer ginterface,
   visitable_class->depends_on = gegl_node_output_visitable_visitable_depends_on;
 }
 
-static void
-gegl_node_output_visitable_finalize (GObject *object)
-{
-  GeglNodeOutputVisitable *self = GEGL_NODE_OUTPUT_VISITABLE (object);
-
-  if (self->is_root)
-    g_hash_table_unref (self->visitables);
-
-  G_OBJECT_CLASS (gegl_node_output_visitable_parent_class)->finalize (object);
-}
-
 static gboolean
 gegl_node_output_visitable_visitable_accept (GeglVisitable *visitable,
                                              GeglVisitor   *visitor)
@@ -102,23 +84,12 @@ gegl_node_output_visitable_visitable_depends_on (GeglVisitable *visitable)
 
   for (iter = gegl_node_get_sinks (self->node); iter; iter = g_slist_next (iter))
     {
-      GeglConnection          *connection = iter->data;
-      GeglNode                *sink_node;
-      GeglNodeOutputVisitable *sink_visitable;
-
-      sink_node = gegl_connection_get_sink_node (connection);
-
-      sink_visitable = g_hash_table_lookup (self->visitables, sink_node);
-
-      if (! sink_visitable)
-        {
-          sink_visitable = _gegl_node_output_visitable_new (sink_node);
+      GeglConnection *connection = iter->data;
+      GeglNode       *sink_node;
+      GeglVisitable  *sink_visitable;
 
-          /* don't ref 'visitables'; the root visitable owns it */
-          sink_visitable->visitables = self->visitables;
-
-          g_hash_table_insert (self->visitables, sink_node, sink_visitable);
-        }
+      sink_node      = gegl_connection_get_sink_node (connection);
+      sink_visitable = gegl_node_get_output_visitable (sink_node);
 
       dependencies = g_slist_prepend (dependencies, sink_visitable);
     }
@@ -126,22 +97,6 @@ gegl_node_output_visitable_visitable_depends_on (GeglVisitable *visitable)
   return dependencies;
 }
 
-GeglNodeOutputVisitable *
-_gegl_node_output_visitable_new (GeglNode *node)
-{
-  GeglNodeOutputVisitable *self;
-
-  self = g_object_new (GEGL_TYPE_NODE_OUTPUT_VISITABLE, NULL);
-
-  /* don't ref 'node', since we might be called during its destruction */
-  self->node       = node;
-
-  self->is_root    = FALSE;
-  self->visitables = NULL;
-
-  return self;
-}
-
 GeglVisitable *
 gegl_node_output_visitable_new (GeglNode *node)
 {
@@ -149,10 +104,9 @@ gegl_node_output_visitable_new (GeglNode *node)
 
   g_return_val_if_fail (GEGL_IS_NODE (node), NULL);
 
-  self = _gegl_node_output_visitable_new (node);
+  self = g_object_new (GEGL_TYPE_NODE_OUTPUT_VISITABLE, NULL);
 
-  self->is_root    = TRUE;
-  self->visitables = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
+  self->node = node;
 
   return GEGL_VISITABLE (self);
 }
diff --git a/gegl/graph/gegl-node-output-visitable.h b/gegl/graph/gegl-node-output-visitable.h
index 54e3328..a82a66f 100644
--- a/gegl/graph/gegl-node-output-visitable.h
+++ b/gegl/graph/gegl-node-output-visitable.h
@@ -35,13 +35,9 @@ typedef struct _GeglNodeOutputVisitableClass GeglNodeOutputVisitableClass;
 
 struct _GeglNodeOutputVisitable
 {
-  GObject     parent_instance;
+  GObject   parent_instance;
 
-  GeglNode   *node;
-
-  /*< private >*/
-  gboolean    is_root;
-  GHashTable *visitables;
+  GeglNode *node;
 };
 
 struct _GeglNodeOutputVisitableClass
diff --git a/gegl/graph/gegl-node-private.h b/gegl/graph/gegl-node-private.h
index f458176..a4cc0f9 100644
--- a/gegl/graph/gegl-node-private.h
+++ b/gegl/graph/gegl-node-private.h
@@ -72,6 +72,11 @@ struct _GeglNode
    */
   GeglCache      *cache;
 
+  /* Used for traversing the graph in the output direction, rather
+   * than the input direction.
+   */
+  GeglVisitable  *output_visitable;
+
   /* Whether result is cached or not, inherited by children */
   gboolean        dont_cache;
 
@@ -126,6 +131,9 @@ void          gegl_node_invalidated         (GeglNode      *node,
                                              const GeglRectangle *rect,
                                              gboolean             clean_cache);
 
+GeglVisitable *
+             gegl_node_get_output_visitable (GeglNode      *self);
+
 const gchar * gegl_node_get_name            (GeglNode      *self);
 void          gegl_node_set_name            (GeglNode      *self,
                                              const gchar   *name);
diff --git a/gegl/graph/gegl-node.c b/gegl/graph/gegl-node.c
index 6f7082c..b00c154 100644
--- a/gegl/graph/gegl-node.c
+++ b/gegl/graph/gegl-node.c
@@ -223,12 +223,13 @@ gegl_node_init (GeglNode *self)
                                             GEGL_TYPE_NODE,
                                             GeglNodePrivate);
 
-  self->pads        = NULL;
-  self->input_pads  = NULL;
-  self->output_pads = NULL;
-  self->operation   = NULL;
-  self->is_graph    = FALSE;
-  self->cache       = NULL;
+  self->pads             = NULL;
+  self->input_pads       = NULL;
+  self->output_pads      = NULL;
+  self->operation        = NULL;
+  self->is_graph         = FALSE;
+  self->cache            = NULL;
+  self->output_visitable = gegl_node_output_visitable_new (self);
   g_mutex_init (&self->mutex);
 
 }
@@ -275,6 +276,7 @@ gegl_node_finalize (GObject *gobject)
   g_slist_free (self->output_pads);
 
   g_clear_object (&self->operation);
+  g_clear_object (&self->output_visitable);
   g_free (self->priv->name);
   g_free (self->priv->debug_name);
 
@@ -2022,6 +2024,14 @@ gegl_node_get_cache (GeglNode *node)
   return node->cache;
 }
 
+GeglVisitable *
+gegl_node_get_output_visitable (GeglNode *self)
+{
+  g_return_val_if_fail (GEGL_IS_NODE (self), NULL);
+
+  return self->output_visitable;
+}
+
 const gchar *
 gegl_node_get_name (GeglNode *self)
 {


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