move rule cache off style objects as styles should be immutable - amends 1c4b67ba98 - refs #916

This commit is contained in:
Dane Springmeyer 2013-02-20 13:25:57 -08:00
parent b359a89616
commit 966af84cbd
5 changed files with 132 additions and 97 deletions

View file

@ -39,6 +39,7 @@ class layer;
class projection; class projection;
class proj_transform; class proj_transform;
class feature_type_style; class feature_type_style;
class rule_cache;
enum eAttributeCollectionPolicy enum eAttributeCollectionPolicy
{ {
@ -77,11 +78,11 @@ private:
*/ */
void render_style(layer const& lay, void render_style(layer const& lay,
Processor & p, Processor & p,
feature_type_style* style, feature_type_style const* style,
rule_cache const& rules,
std::string const& style_name, std::string const& style_name,
featureset_ptr features, featureset_ptr features,
proj_transform const& prj_trans, proj_transform const& prj_trans);
double scale_denom);
Map const& m_; Map const& m_;
double scale_factor_; double scale_factor_;

View file

@ -38,6 +38,7 @@
#include <mapnik/box2d.hpp> #include <mapnik/box2d.hpp>
#include <mapnik/layer.hpp> #include <mapnik/layer.hpp>
#include <mapnik/rule.hpp> #include <mapnik/rule.hpp>
#include <mapnik/rule_cache.hpp>
#include <mapnik/attribute_collector.hpp> #include <mapnik/attribute_collector.hpp>
#include <mapnik/expression_evaluator.hpp> #include <mapnik/expression_evaluator.hpp>
#include <mapnik/utils.hpp> #include <mapnik/utils.hpp>
@ -136,7 +137,6 @@ struct has_process
); );
}; };
template <typename Processor> template <typename Processor>
feature_style_processor<Processor>::feature_style_processor(Map const& m, double scale_factor) feature_style_processor<Processor>::feature_style_processor(Map const& m, double scale_factor)
: m_(m), scale_factor_(scale_factor) : m_(m), scale_factor_(scale_factor)
@ -361,10 +361,11 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
m_.height()/qh); m_.height()/qh);
query q(layer_ext,res,scale_denom,m_.get_current_extent()); query q(layer_ext,res,scale_denom,m_.get_current_extent());
std::vector<feature_type_style*> active_styles; std::vector<feature_type_style const*> active_styles;
attribute_collector collector(names); attribute_collector collector(names);
double filt_factor = 1.0; double filt_factor = 1.0;
directive_collector d_collector(filt_factor); directive_collector d_collector(filt_factor);
boost::ptr_vector<rule_cache> rule_caches;
// iterate through all named styles collecting active styles and attribute names // iterate through all named styles collecting active styles and attribute names
BOOST_FOREACH(std::string const& style_name, style_names) BOOST_FOREACH(std::string const& style_name, style_names)
@ -379,12 +380,14 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
continue; continue;
} }
std::vector<rule> const& rules=(*style).get_rules(); std::vector<rule> const& rules = style->get_rules();
bool active_rules = false; bool active_rules = false;
std::auto_ptr<rule_cache> rc(new rule_cache);
BOOST_FOREACH(rule const& r, rules) BOOST_FOREACH(rule const& r, rules)
{ {
if (r.active(scale_denom)) if (r.active(scale_denom))
{ {
rc->add_rule(r);
active_rules = true; active_rules = true;
if (ds->type() == datasource::Vector) if (ds->type() == datasource::Vector)
{ {
@ -395,7 +398,8 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
} }
if (active_rules) if (active_rules)
{ {
active_styles.push_back(const_cast<feature_type_style*>(&(*style))); rule_caches.push_back(rc);
active_styles.push_back(&(*style));
} }
} }
@ -419,7 +423,7 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
} }
// Update filter_factor for all enabled raster layers. // Update filter_factor for all enabled raster layers.
BOOST_FOREACH (feature_type_style * style, active_styles) BOOST_FOREACH (feature_type_style const* style, active_styles)
{ {
BOOST_FOREACH(rule const& r, style->get_rules()) BOOST_FOREACH(rule const& r, style->get_rules())
{ {
@ -464,10 +468,11 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
// We're at a value boundary, so render what we have // We're at a value boundary, so render what we have
// up to this point. // up to this point.
int i = 0; int i = 0;
BOOST_FOREACH (feature_type_style * style, active_styles) BOOST_FOREACH (feature_type_style const* style, active_styles)
{ {
render_style(lay, p, style, style_names[i++], render_style(lay, p, style, rule_caches[i], style_names[i],
cache.features(q), prj_trans, scale_denom); cache.features(q), prj_trans);
i++;
} }
cache.clear(); cache.clear();
} }
@ -476,10 +481,11 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
} }
int i = 0; int i = 0;
BOOST_FOREACH (feature_type_style * style, active_styles) BOOST_FOREACH (feature_type_style const* style, active_styles)
{ {
render_style(lay, p, style, style_names[i++], render_style(lay, p, style, rule_caches[i], style_names[i],
cache.features(q), prj_trans, scale_denom); cache.features(q), prj_trans);
i++;
} }
} }
} }
@ -496,20 +502,22 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
} }
} }
int i = 0; int i = 0;
BOOST_FOREACH (feature_type_style * style, active_styles) BOOST_FOREACH (feature_type_style const* style, active_styles)
{ {
render_style(lay, p, style, style_names[i++], render_style(lay, p, style, rule_caches[i], style_names[i],
cache.features(q), prj_trans, scale_denom); cache.features(q), prj_trans);
i++;
} }
} }
// We only have a single style and no grouping. // We only have a single style and no grouping.
else else
{ {
int i = 0; int i = 0;
BOOST_FOREACH (feature_type_style * style, active_styles) BOOST_FOREACH (feature_type_style const* style, active_styles)
{ {
render_style(lay, p, style, style_names[i++], render_style(lay, p, style, rule_caches[i], style_names[i],
ds->features(q), prj_trans, scale_denom); ds->features(q), prj_trans);
i++;
} }
} }
} }
@ -526,11 +534,11 @@ template <typename Processor>
void feature_style_processor<Processor>::render_style( void feature_style_processor<Processor>::render_style(
layer const& lay, layer const& lay,
Processor & p, Processor & p,
feature_type_style* style, feature_type_style const* style,
rule_cache const& rc,
std::string const& style_name, std::string const& style_name,
featureset_ptr features, featureset_ptr features,
proj_transform const& prj_trans, proj_transform const& prj_trans)
double scale_denom)
{ {
p.start_style_processing(*style); p.start_style_processing(*style);
if (!features) if (!features)
@ -560,7 +568,7 @@ void feature_style_processor<Processor>::render_style(
bool do_else = true; bool do_else = true;
bool do_also = false; bool do_also = false;
BOOST_FOREACH(rule * r, style->get_if_rules(scale_denom) ) BOOST_FOREACH(rule const* r, rc.get_if_rules() )
{ {
expression_ptr const& expr=r->get_filter(); expression_ptr const& expr=r->get_filter();
value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr); value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr);
@ -589,13 +597,14 @@ void feature_style_processor<Processor>::render_style(
if (style->get_filter_mode() == FILTER_FIRST) if (style->get_filter_mode() == FILTER_FIRST)
{ {
// Stop iterating over rules and proceed with next feature. // Stop iterating over rules and proceed with next feature.
do_also=false;
break; break;
} }
} }
} }
if (do_else) if (do_else)
{ {
BOOST_FOREACH( rule * r, style->get_else_rules(scale_denom) ) BOOST_FOREACH( rule const* r, rc.get_else_rules() )
{ {
#if defined(RENDERING_STATS) #if defined(RENDERING_STATS)
feat_processed = true; feat_processed = true;
@ -617,7 +626,7 @@ void feature_style_processor<Processor>::render_style(
} }
if (do_also) if (do_also)
{ {
BOOST_FOREACH( rule * r, style->get_also_rules(scale_denom) ) BOOST_FOREACH( rule const* r, rc.get_also_rules() )
{ {
#if defined(RENDERING_STATS) #if defined(RENDERING_STATS)
feat_processed = true; feat_processed = true;

View file

@ -50,7 +50,6 @@ enum filter_mode_enum {
DEFINE_ENUM( filter_mode_e, filter_mode_enum ); DEFINE_ENUM( filter_mode_e, filter_mode_enum );
typedef std::vector<rule> rules; typedef std::vector<rule> rules;
typedef std::vector<rule*> rule_ptrs;
class MAPNIK_DECL feature_type_style class MAPNIK_DECL feature_type_style
{ {
@ -62,11 +61,6 @@ private:
std::vector<filter::filter_type> direct_filters_; std::vector<filter::filter_type> direct_filters_;
// comp-op // comp-op
boost::optional<composite_mode_e> comp_op_; boost::optional<composite_mode_e> comp_op_;
// The rule_ptrs vectors are only valid for the scale_denom_validity_.
double scale_denom_validity_;
rule_ptrs if_rules_;
rule_ptrs else_rules_;
rule_ptrs also_rules_;
float opacity_; float opacity_;
public: public:
feature_type_style(); feature_type_style();
@ -77,9 +71,6 @@ public:
void add_rule(rule const& rule); void add_rule(rule const& rule);
rules const& get_rules() const; rules const& get_rules() const;
rule_ptrs const& get_if_rules(double scale_denom);
rule_ptrs const& get_else_rules(double scale_denom);
rule_ptrs const& get_also_rules(double scale_denom);
rules& get_rules_nonconst(); rules& get_rules_nonconst();
bool active(double scale_denom) const; bool active(double scale_denom) const;
@ -100,9 +91,6 @@ public:
~feature_type_style() {} ~feature_type_style() {}
private:
void update_rule_cache(double scale_denom);
}; };
} }

View file

@ -0,0 +1,95 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2013 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef MAPNIK_RULE_CACHE_HPP
#define MAPNIK_RULE_CACHE_HPP
// mapnik
#include <mapnik/rule.hpp>
#include <mapnik/feature_type_style.hpp>
// boost
#include <boost/foreach.hpp>
// stl
#include <vector>
namespace mapnik
{
class rule_cache
{
public:
typedef std::vector<rule const*> rule_ptrs;
rule_cache()
: if_rules_(),
else_rules_(),
also_rules_(),
active_(false) {}
bool active()
{
return active_;
}
void add_rule(rule const& r)
{
if (r.has_else_filter())
{
else_rules_.push_back(&r);
}
else if (r.has_also_filter())
{
also_rules_.push_back(&r);
}
else
{
if_rules_.push_back(&r);
}
active_ = true;
}
rule_ptrs const& get_if_rules() const
{
return if_rules_;
}
rule_ptrs const& get_else_rules() const
{
return else_rules_;
}
rule_ptrs const& get_also_rules() const
{
return also_rules_;
}
private:
rule_ptrs if_rules_;
rule_ptrs else_rules_;
rule_ptrs also_rules_;
bool active_;
};
}
#endif // MAPNIK_RULE_CACHE_HPP

View file

@ -42,7 +42,6 @@ feature_type_style::feature_type_style()
: filter_mode_(FILTER_ALL), : filter_mode_(FILTER_ALL),
filters_(), filters_(),
direct_filters_(), direct_filters_(),
scale_denom_validity_(-1),
opacity_(1.0f) opacity_(1.0f)
{} {}
@ -51,7 +50,6 @@ feature_type_style::feature_type_style(feature_type_style const& rhs, bool deep_
filters_(rhs.filters_), filters_(rhs.filters_),
direct_filters_(rhs.direct_filters_), direct_filters_(rhs.direct_filters_),
comp_op_(rhs.comp_op_), comp_op_(rhs.comp_op_),
scale_denom_validity_(-1),
opacity_(rhs.opacity_) opacity_(rhs.opacity_)
{ {
if (!deep_copy) { if (!deep_copy) {
@ -72,7 +70,6 @@ feature_type_style& feature_type_style::operator=(feature_type_style const& rhs)
filters_ = rhs.filters_; filters_ = rhs.filters_;
direct_filters_ = rhs.direct_filters_; direct_filters_ = rhs.direct_filters_;
comp_op_ = rhs.comp_op_; comp_op_ = rhs.comp_op_;
scale_denom_validity_ = -1;
opacity_= rhs.opacity_; opacity_= rhs.opacity_;
return *this; return *this;
} }
@ -80,7 +77,6 @@ feature_type_style& feature_type_style::operator=(feature_type_style const& rhs)
void feature_type_style::add_rule(rule const& rule) void feature_type_style::add_rule(rule const& rule)
{ {
rules_.push_back(rule); rules_.push_back(rule);
scale_denom_validity_ = -1;
} }
rules const& feature_type_style::get_rules() const rules const& feature_type_style::get_rules() const
@ -155,59 +151,5 @@ float feature_type_style::get_opacity() const
return opacity_; return opacity_;
} }
void feature_type_style::update_rule_cache(double scale_denom)
{
if_rules_.clear();
else_rules_.clear();
also_rules_.clear();
BOOST_FOREACH(rule & r, rules_)
{
if (r.active(scale_denom))
{
if (r.has_else_filter())
{
else_rules_.push_back(&r);
}
else if (r.has_also_filter())
{
also_rules_.push_back(&r);
}
else
{
if_rules_.push_back(&r);
}
}
}
scale_denom_validity_ = scale_denom;
}
rule_ptrs const& feature_type_style::get_if_rules(double scale_denom)
{
if (scale_denom_validity_ != scale_denom)
{
update_rule_cache(scale_denom);
}
return if_rules_;
}
rule_ptrs const& feature_type_style::get_else_rules(double scale_denom)
{
if (scale_denom_validity_ != scale_denom)
{
update_rule_cache(scale_denom);
}
return else_rules_;
}
rule_ptrs const& feature_type_style::get_also_rules(double scale_denom)
{
if (scale_denom_validity_ != scale_denom)
{
update_rule_cache(scale_denom);
}
return also_rules_;
}
} }