]> git.donarmstrong.com Git - lilypond.git/commitdiff
Optimizations for pure-height approximations.
authorJoe Neeman <joeneeman@gmail.com>
Fri, 14 Jan 2011 12:32:16 +0000 (13:32 +0100)
committerJoe Neeman <joeneeman@gmail.com>
Sun, 13 Feb 2011 22:37:20 +0000 (09:37 +1100)
Since we end up querying the height of each VerticalAxisGroup
multiple times for each line, cache the intermediate results.

lily/axis-group-interface.cc
lily/include/axis-group-interface.hh
lily/include/spanner.hh
lily/spanner.cc

index 25952d6783d026593379f480bd3a8d4cc0ba14b3..520d024516a5f350eee316028114e2684f61ab90 100644 (file)
@@ -90,7 +90,7 @@ Axis_group_interface::relative_group_extent (vector<Grob*> const &elts,
 }
 
 Interval
-Axis_group_interface::cached_pure_height (Grob *me, int start, int end)
+Axis_group_interface::sum_partial_pure_heights (Grob *me, int start, int end)
 {
   Interval iv = begin_of_line_pure_height (me, start);
   iv.unite (rest_of_line_pure_height (me, start, end));
@@ -99,27 +99,47 @@ Axis_group_interface::cached_pure_height (Grob *me, int start, int end)
 }
 
 Interval
-Axis_group_interface::rest_of_line_pure_height (Grob *me, int start, int end)
+Axis_group_interface::part_of_line_pure_height (Grob *me, bool begin, int start, int end)
 {
+  Spanner *sp = dynamic_cast<Spanner*> (me);
+  SCM cache_symbol = begin
+    ? ly_symbol2scm ("begin-of-line-pure-height")
+    : ly_symbol2scm ("rest-of-line-pure-height");
+  SCM cached = sp->get_cached_pure_property (cache_symbol, start, end);
+  if (scm_is_pair (cached))
+    return robust_scm2interval (cached, Interval (0, 0));
+
   SCM adjacent_pure_heights = me->get_property ("adjacent-pure-heights");
+  Interval ret;
+
+  if (!scm_is_pair (adjacent_pure_heights))
+    ret = Interval (0, 0);
+  else
+    {
+      SCM these_pure_heights = begin
+       ? scm_car (adjacent_pure_heights)
+       : scm_cdr (adjacent_pure_heights);
 
-  if (!scm_is_pair (adjacent_pure_heights)
-      || !scm_is_vector (scm_cdr (adjacent_pure_heights)))
-    return Interval (0, 0);
+      if (scm_is_vector (these_pure_heights))
+       ret = combine_pure_heights (me, these_pure_heights, start, end);
+      else
+       ret = Interval (0, 0);
+    }
 
-  return combine_pure_heights (me, scm_cdr (adjacent_pure_heights), start, end);
+  sp->cache_pure_property (cache_symbol, start, end, ly_interval2scm (ret));
+  return ret;
 }
 
 Interval
 Axis_group_interface::begin_of_line_pure_height (Grob *me, int start)
 {
-  SCM adjacent_pure_heights = me->get_property ("adjacent-pure-heights");
-
-  if (!scm_is_pair (adjacent_pure_heights)
-      || !scm_is_vector (scm_car (adjacent_pure_heights)))
-    return Interval (0, 0);
+  return part_of_line_pure_height (me, true, start, start + 1);
+}
 
-  return combine_pure_heights (me, scm_car (adjacent_pure_heights), start, start+1);
+Interval
+Axis_group_interface::rest_of_line_pure_height (Grob *me, int start, int end)
+{
+  return part_of_line_pure_height (me, false, start, end);
 }
 
 Interval
@@ -260,7 +280,7 @@ Axis_group_interface::relative_pure_height (Grob *me, int start, int end)
      we can assume additivity and cache things nicely. */
   Grob *p = me->get_parent (Y_AXIS);
   if (p && Align_interface::has_interface (p))
-    return Axis_group_interface::cached_pure_height (me, start, end);
+    return Axis_group_interface::sum_partial_pure_heights (me, start, end);
 
   Grob *common = unsmob_grob (me->get_object ("pure-Y-common"));
   extract_grob_set (me, "pure-relevant-grobs", elts);
index fba715489da32b7443c2877a2eb950e3f5452fdb..fa662020967bfbe57f6234c2ef9cded251b94225 100644 (file)
@@ -48,9 +48,10 @@ struct Axis_group_interface
                                         Grob *common, Axis);
   static Interval relative_pure_height (Grob *me, int start, int end);
   static Interval combine_pure_heights (Grob *me, SCM, int, int);
-  static Interval cached_pure_height (Grob *me, int, int);
+  static Interval sum_partial_pure_heights (Grob *me, int, int);
   static Interval begin_of_line_pure_height (Grob *me, int);
   static Interval rest_of_line_pure_height (Grob *me, int, int);
+  static Interval part_of_line_pure_height (Grob *me, bool begin, int, int);
 
   static Skyline_pair skyline_spacing (Grob *me, vector<Grob*> elements);
   static void add_element (Grob *me, Grob *);
index 834c1c8e6e4b5c440f0cd3439ea873e1eb4cc2c5..43468754edb5077d7e4973021a50f3b6fb5fe2b2 100644 (file)
@@ -78,7 +78,12 @@ public:
   DECLARE_GROB_INTERFACE();
   virtual System *get_system () const;
 
+  SCM get_cached_pure_property (SCM sym, int start, int end);
+  void cache_pure_property (SCM sym, int start, int end, SCM value);
+
 protected:
+  SCM pure_property_cache_;
+
   void set_my_columns ();
   virtual Grob *clone () const;
   virtual void do_break_processing ();
index 3887797d9098fcae8675319b058999cc7ac2e36c..f3d13c84f9879a5878a6dc9739528842b94e8205 100644 (file)
@@ -226,12 +226,14 @@ Spanner::Spanner (SCM s)
 {
   break_index_ = 0;
   spanned_drul_.set (0, 0);
+  pure_property_cache_ = SCM_UNDEFINED;
 }
 
 Spanner::Spanner (Spanner const &s)
   : Grob (s)
 {
   spanned_drul_.set (0, 0);
+  pure_property_cache_ = SCM_UNDEFINED;
 }
 
 Real
@@ -327,6 +329,8 @@ Spanner::get_broken_left_end_align () const
 void
 Spanner::derived_mark () const
 {
+  scm_gc_mark (pure_property_cache_);
+
   Direction d = LEFT;
   do
     if (spanned_drul_[d])
@@ -454,6 +458,29 @@ Spanner::kill_zero_spanned_time (SCM grob)
   return SCM_UNSPECIFIED;
 }
 
+SCM
+Spanner::get_cached_pure_property (SCM sym, int start, int end)
+{
+  // The pure property cache is indexed by (name start . end), where name is
+  // a symbol, and start and end are numbers referring to the starting and
+  // ending column ranks of the current line.
+  if (scm_hash_table_p (pure_property_cache_) == SCM_BOOL_F)
+    return SCM_UNDEFINED;
+
+  SCM key = scm_cons (sym, scm_cons (scm_from_int (start), scm_from_int (end)));
+  return scm_hash_ref (pure_property_cache_, key, SCM_UNDEFINED);
+}
+
+void
+Spanner::cache_pure_property (SCM sym, int start, int end, SCM val)
+{
+  if (scm_hash_table_p (pure_property_cache_) == SCM_BOOL_F)
+    pure_property_cache_ = scm_c_make_hash_table (17);
+
+  SCM key = scm_cons (sym, scm_cons (scm_from_int (start), scm_from_int (end)));
+  scm_hash_set_x (pure_property_cache_, key, val);
+}
+
 ADD_INTERFACE (Spanner,
               "Some objects are horizontally spanned between objects.  For"
               " example, slurs, beams, ties, etc.  These grobs form a subtype"