1 // g2o - General Graph Optimization 2 // Copyright (C) 2011 G. Grisetti, R. Kuemmerle, W. Burgard 3 // All rights reserved. 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright notice, 10 // this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above copyright 12 // notice, this list of conditions and the following disclaimer in the 13 // documentation and/or other materials provided with the distribution. 14 // 15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 16 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 18 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27 #include "cache.h" 28 #include "optimizable_graph.h" 29 #include "factory.h" 30 31 #include <iostream> 32 33 namespace g2o { 34 using namespace std; 35 CacheKey()36 Cache::CacheKey::CacheKey() : 37 _type(), _parameters() 38 { 39 } 40 CacheKey(const std::string & type_,const ParameterVector & parameters_)41 Cache::CacheKey::CacheKey(const std::string& type_, const ParameterVector& parameters_) : 42 _type(type_), _parameters(parameters_) 43 { 44 } 45 Cache(CacheContainer * container_,const ParameterVector & parameters_)46 Cache::Cache(CacheContainer* container_, const ParameterVector& parameters_) : 47 _updateNeeded(true), _parameters(parameters_), _container(container_) 48 { 49 } 50 operator <(const Cache::CacheKey & c) const51 bool Cache::CacheKey::operator<(const Cache::CacheKey& c) const{ 52 if (_type < c._type) 53 return true; 54 else if (c._type < _type) 55 return false; 56 return std::lexicographical_compare (_parameters.begin( ), _parameters.end( ), 57 c._parameters.begin( ), c._parameters.end( ) ); 58 } 59 60 vertex()61 OptimizableGraph::Vertex* Cache::vertex() { 62 if (container() ) 63 return container()->vertex(); 64 return nullptr; 65 } 66 graph()67 OptimizableGraph* Cache::graph() { 68 if (container()) 69 return container()->graph(); 70 return nullptr; 71 } 72 container()73 CacheContainer* Cache::container() { 74 return _container; 75 } 76 parameters()77 ParameterVector& Cache::parameters() { 78 return _parameters; 79 } 80 key() const81 Cache::CacheKey Cache::key() const { 82 Factory* factory=Factory::instance(); 83 return CacheKey(factory->tag(this), _parameters); 84 }; 85 86 update()87 void Cache::update(){ 88 if (! _updateNeeded) 89 return; 90 for(std::vector<Cache*>::iterator it=_parentCaches.begin(); it!=_parentCaches.end(); ++it){ 91 (*it)->update(); 92 } 93 updateImpl(); 94 _updateNeeded=false; 95 } 96 installDependency(const std::string & type_,const std::vector<int> & parameterIndices)97 Cache* Cache::installDependency(const std::string& type_, const std::vector<int>& parameterIndices){ 98 ParameterVector pv(parameterIndices.size()); 99 for (size_t i=0; i<parameterIndices.size(); i++){ 100 if (parameterIndices[i]<0 || parameterIndices[i] >=(int)_parameters.size()) 101 return nullptr; 102 pv[i]=_parameters[ parameterIndices[i] ]; 103 } 104 CacheKey k(type_, pv); 105 if (!container()) 106 return nullptr; 107 Cache* c=container()->findCache(k); 108 if (!c) { 109 c = container()->createCache(k); 110 } 111 if (c) 112 _parentCaches.push_back(c); 113 return c; 114 } 115 resolveDependancies()116 bool Cache::resolveDependancies(){ 117 return true; 118 } 119 CacheContainer(OptimizableGraph::Vertex * vertex_)120 CacheContainer::CacheContainer(OptimizableGraph::Vertex* vertex_) : _updateNeeded(true) { _vertex = vertex_; } 121 findCache(const Cache::CacheKey & key)122 Cache* CacheContainer::findCache(const Cache::CacheKey& key) { 123 iterator it=find(key); 124 if (it==end()) 125 return nullptr; 126 return it->second; 127 } 128 createCache(const Cache::CacheKey & key)129 Cache* CacheContainer::createCache(const Cache::CacheKey& key){ 130 Factory* f = Factory::instance(); 131 HyperGraph::HyperGraphElement* e = f->construct(key.type()); 132 if (!e) { 133 cerr << __PRETTY_FUNCTION__ << endl; 134 cerr << "fatal error in creating cache of type " << key.type() << endl; 135 return nullptr; 136 } 137 Cache* c = dynamic_cast<Cache*>(e); 138 if (! c){ 139 cerr << __PRETTY_FUNCTION__ << endl; 140 cerr << "fatal error in creating cache of type " << key.type() << endl; 141 return nullptr; 142 } 143 c->_container = this; 144 c->_parameters = key._parameters; 145 if (c->resolveDependancies()){ 146 insert(make_pair(key,c)); 147 c->update(); 148 return c; 149 } 150 return nullptr; 151 } 152 vertex()153 OptimizableGraph::Vertex* CacheContainer::vertex() { 154 return _vertex; 155 } 156 graph()157 OptimizableGraph* CacheContainer::graph(){ 158 if (_vertex) 159 return _vertex->graph(); 160 return nullptr; 161 } 162 update()163 void CacheContainer::update() { 164 for (iterator it=begin(); it!=end(); ++it){ 165 (it->second)->update(); 166 } 167 _updateNeeded=false; 168 } 169 setUpdateNeeded(bool needUpdate)170 void CacheContainer::setUpdateNeeded(bool needUpdate) { 171 _updateNeeded=needUpdate; 172 for (iterator it=begin(); it!=end(); ++it){ 173 (it->second)->_updateNeeded = needUpdate; 174 } 175 } 176 ~CacheContainer()177 CacheContainer::~CacheContainer(){ 178 for (iterator it=begin(); it!=end(); ++it){ 179 delete (it->second); 180 } 181 } 182 183 } // end namespace 184