]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 4380: Some optimizations during dispatching
authorDavid Kastrup <dak@gnu.org>
Sat, 9 May 2015 18:37:19 +0000 (20:37 +0200)
committerDavid Kastrup <dak@gnu.org>
Sat, 16 May 2015 08:19:25 +0000 (10:19 +0200)
Don't generate hashes multiple times and stop detection of pending grobs
when the first one is encountered.

lily/dispatcher.cc
lily/engraver-group.cc
lily/include/engraver-group.hh

index 7f6e0cb70b9bed7f14a78048c4db9c4ade169bcb..d47c2739d29d0adc53867a30ad4de2f0ed1fdbe2 100644 (file)
@@ -218,7 +218,8 @@ Dispatcher::add_listener (SCM callback, SCM ev_class)
 inline void
 Dispatcher::internal_add_listener (SCM callback, SCM ev_class, int priority)
 {
-  SCM list = scm_hashq_ref (listeners_, ev_class, SCM_EOL);
+  SCM handle = scm_hashq_create_handle_x (listeners_, ev_class, SCM_EOL);
+  SCM list = scm_cdr (handle);
   // if ev_class is not yet listened to, we go through our list of
   // source dispatchers and register ourselves there with the priority
   // we have reserved for this dispatcher.  The priority system
@@ -242,20 +243,21 @@ Dispatcher::internal_add_listener (SCM callback, SCM ev_class, int priority)
     }
   SCM entry = scm_cons (scm_from_int (priority), callback);
   list = scm_merge (list, scm_list_1 (entry), ly_lily_module_constant ("car<"));
-  scm_hashq_set_x (listeners_, ev_class, list);
+  scm_set_cdr_x (handle, list);
 }
 
 void
 Dispatcher::remove_listener (Listener l, SCM ev_class)
 {
-  SCM list = scm_hashq_ref (listeners_, ev_class, SCM_EOL);
+  SCM handle = scm_hashq_get_handle (listeners_, ev_class);
 
-  if (scm_is_null (list))
+  if (scm_is_false (handle))
     {
       programming_error ("remove_listener called with incorrect class.");
       return;
     }
 
+  SCM list = scm_cdr (handle);
   // We just remove the listener once.
   bool first = true;
 
@@ -271,7 +273,7 @@ Dispatcher::remove_listener (Listener l, SCM ev_class)
     else
       e = scm_cdr (e);
   list = scm_cdr (dummy);
-  scm_hashq_set_x (listeners_, ev_class, list);
+  scm_set_cdr_x (handle, list);
 
   if (first)
     warning (_ ("Attempting to remove nonexisting listener."));
index b7de6e9e77ac67cbcda0bb2a21079362a4b044c2..9b5efb27797015c40e0b39fc5a24ff6d732eebae 100644 (file)
@@ -101,11 +101,10 @@ Engraver_group::acknowledge_grobs ()
       else
         continue;
 
-      SCM acklist = scm_hashq_ref (acknowledge_hash_table_drul_[info.start_end ()],
-                                   nm, SCM_BOOL_F);
+      SCM ackhandle = scm_hashq_create_handle_x (acknowledge_hash_table_drul_[info.start_end ()],
+                                                 nm, SCM_BOOL_F);
 
-      Engraver_dispatch_list *dispatch
-        = Engraver_dispatch_list::unsmob (acklist);
+      SCM acklist = scm_cdr (ackhandle);
 
       if (scm_is_false (acklist))
         {
@@ -114,12 +113,12 @@ Engraver_group::acknowledge_grobs ()
           acklist = Engraver_dispatch_list::create (get_simple_trans_list (),
                                                     ifaces, info.start_end ());
 
-          dispatch
-            = Engraver_dispatch_list::unsmob (acklist);
-
-          scm_hashq_set_x (acknowledge_hash_table_drul_[info.start_end ()], nm, acklist);
+          scm_set_cdr_x (ackhandle, acklist);
         }
 
+      Engraver_dispatch_list *dispatch
+        = Engraver_dispatch_list::unsmob (acklist);
+
       if (dispatch)
         dispatch->apply (info);
     }
@@ -129,10 +128,11 @@ Engraver_group::acknowledge_grobs ()
   Ugh. This is slightly expensive. We could/should cache the value of
   the group count?
 */
-int
-Engraver_group::pending_grob_count () const
+bool
+Engraver_group::pending_grobs () const
 {
-  int count = announce_infos_.size ();
+  if (!announce_infos_.empty ())
+    return true;
   for (SCM s = context_->children_contexts ();
        scm_is_pair (s); s = scm_cdr (s))
     {
@@ -140,10 +140,10 @@ Engraver_group::pending_grob_count () const
       Engraver_group *group
         = dynamic_cast<Engraver_group *> (c->implementation ());
 
-      if (group)
-        count += group->pending_grob_count ();
+      if (group && group->pending_grobs ())
+        return true;
     }
-  return count;
+  return false;
 }
 
 void
@@ -174,7 +174,7 @@ Engraver_group::do_announces ()
           announce_infos_.clear ();
         }
     }
-  while (pending_grob_count () > 0);
+  while (pending_grobs ());
 }
 
 Engraver_group::Engraver_group ()
index ec7c8f330dc708ef0a23a6bd128016b6aefafd33..aa3cd478bce652c5bc6a098e0250be689a38d0f0 100644 (file)
@@ -38,7 +38,7 @@ public:
   virtual void connect_to_context (Context *c);
   virtual void disconnect_from_context ();
   virtual void announce_grob (Grob_info);
-  int pending_grob_count () const;
+  bool pending_grobs () const;
 private:
   virtual void acknowledge_grobs ();
 };