fix possible race condition in Normalizer cache

This commit is contained in:
Patrick Brosi 2020-11-20 16:51:04 +01:00
parent 08b0685ad1
commit b0a2cff43a
5 changed files with 117 additions and 66 deletions

View file

@ -3,7 +3,9 @@
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
#include <algorithm>
#include <cassert>
#include <iostream>
#include <mutex>
#include <regex>
#include <sstream>
#include <stdexcept>
@ -15,12 +17,39 @@
using pfaedle::trgraph::Normalizer;
// _____________________________________________________________________________
Normalizer::Normalizer(const ReplRules& rules) : _rulesOrig(rules) {
Normalizer::Normalizer(const ReplRules& rules)
: _rulesOrig(rules) {
buildRules(rules);
}
// _____________________________________________________________________________
Normalizer::Normalizer(const Normalizer& other)
: _rules(other._rules),
_rulesOrig(other._rulesOrig),
_cache(other._cache) {}
// _____________________________________________________________________________
Normalizer& Normalizer::operator=(Normalizer other) {
std::swap(this->_rules, other._rules);
std::swap(this->_rulesOrig, other._rulesOrig);
std::swap(this->_cache, other._cache);
return *this;
}
// _____________________________________________________________________________
std::string Normalizer::operator()(std::string sn) const {
return normTS(sn);
}
// _____________________________________________________________________________
std::string Normalizer::normTS(const std::string& sn) const {
std::lock_guard<std::mutex> lock(_mutex);
return norm(sn);
}
// _____________________________________________________________________________
std::string Normalizer::norm(const std::string& sn) const {
auto i = _cache.find(sn);
if (i != _cache.end()) return i->second;

View file

@ -10,6 +10,7 @@
#include <unordered_map>
#include <utility>
#include <vector>
#include <mutex>
namespace pfaedle {
namespace trgraph {
@ -28,7 +29,19 @@ class Normalizer {
Normalizer() {}
explicit Normalizer(const ReplRules& rules);
// Normalize sn based on the rules of this normalizer
// copy constructor
Normalizer(const Normalizer& other);
// assignment op
Normalizer& operator=(Normalizer other);
// Normalize sn, not thread safe
std::string norm(const std::string& sn) const;
// Normalize sn, thread safe
std::string normTS(const std::string& sn) const;
// Normalize sn based on the rules of this normalizer, uses the thread safe
// version of norm() internally
std::string operator()(std::string sn) const;
bool operator==(const Normalizer& b) const;
@ -36,6 +49,7 @@ class Normalizer {
ReplRulesComp _rules;
ReplRules _rulesOrig;
mutable std::unordered_map<std::string, std::string> _cache;
mutable std::mutex _mutex;
void buildRules(const ReplRules& rules);
};

View file

@ -68,7 +68,7 @@ double StatGroup::getPen(const Stop* s, trgraph::Node* n,
double distPen = util::geo::webMercMeterDist(p, *n->pl().getGeom());
distPen *= distPenFac;
std::string platform = platformNorm(s->getPlatformCode());
std::string platform = platformNorm.norm(s->getPlatformCode());
if (!platform.empty() && !n->pl().getSI()->getTrack().empty() &&
n->pl().getSI()->getTrack() == platform) {