dlvhex
2.5.0
|
00001 /* dlvhex -- Answer-Set Programming with external interfaces. 00002 * Copyright (C) 2005-2007 Roman Schindlauer 00003 * Copyright (C) 2006-2015 Thomas Krennwallner 00004 * Copyright (C) 2009-2016 Peter Schüller 00005 * Copyright (C) 2011-2016 Christoph Redl 00006 * Copyright (C) 2015-2016 Tobias Kaminski 00007 * Copyright (C) 2015-2016 Antonius Weinzierl 00008 * 00009 * This file is part of dlvhex. 00010 * 00011 * dlvhex is free software; you can redistribute it and/or modify it 00012 * under the terms of the GNU Lesser General Public License as 00013 * published by the Free Software Foundation; either version 2.1 of 00014 * the License, or (at your option) any later version. 00015 * 00016 * dlvhex is distributed in the hope that it will be useful, but 00017 * WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 * Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with dlvhex; if not, write to the Free Software 00023 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 00024 * 02110-1301 USA. 00025 */ 00026 00034 #ifndef MODULETABLE_HPP_INCLUDED__20122010 00035 #define MODULETABLE_HPP_INCLUDED__20102010 00036 00037 #include "dlvhex2/PlatformDefinitions.h" 00038 #include "dlvhex2/Logger.h" 00039 #include "dlvhex2/ID.h" 00040 #include "dlvhex2/Module.h" 00041 #include "dlvhex2/Table.h" 00042 00043 #include <boost/multi_index/member.hpp> 00044 #include <boost/multi_index/hashed_index.hpp> 00045 #include <boost/multi_index/random_access_index.hpp> 00046 00047 DLVHEX_NAMESPACE_BEGIN 00048 00050 class ModuleTable: 00051 public Table< 00052 // value type is symbol struct 00053 Module, 00054 // index is 00055 boost::multi_index::indexed_by< 00056 // address = running ID for constant access 00057 boost::multi_index::random_access< 00058 boost::multi_index::tag<impl::AddressTag> 00059 >, 00060 // unique IDs for unique symbol strings 00061 boost::multi_index::hashed_unique< 00062 boost::multi_index::tag<impl::ModuleNameTag>, 00063 BOOST_MULTI_INDEX_MEMBER(Module,std::string,moduleName) 00064 > 00065 > 00066 > 00067 { 00068 public: 00069 // types 00070 typedef Container::index<impl::AddressTag>::type AddressIndex; 00071 typedef AddressIndex::iterator AddressIterator; 00072 typedef Container::index<impl::ModuleNameTag>::type ModuleNameIndex; 00073 00074 // methods 00075 public: 00076 00080 inline const Module& getByAddress(int address) const throw (); 00081 00085 inline const std::string& getModuleName(int address) const throw (); 00086 00091 inline std::pair<AddressIterator, AddressIterator> getAllByAddress() const throw(); 00092 00095 inline const Module& getModuleByName(const std::string& moduleName) const throw(); 00096 00100 inline int getAddressByName(const std::string& moduleName) const throw(); 00101 00107 inline int storeAndGetAddress(const Module& mod) throw(); 00108 00115 inline virtual std::ostream& print(std::ostream& o) const; 00116 00117 }; 00118 00119 // get range over all atoms sorted by address 00120 // NOTE: you may need to lock the mutex also while iterating! 00121 std::pair<ModuleTable::AddressIterator, ModuleTable::AddressIterator> 00122 ModuleTable::getAllByAddress() const throw() 00123 { 00124 ReadLock lock(mutex); 00125 const AddressIndex& idx = container.get<impl::AddressTag>(); 00126 return std::make_pair(idx.begin(), idx.end()); 00127 } 00128 00129 00130 std::ostream& ModuleTable::print(std::ostream& o) const 00131 { 00132 ReadLock lock(mutex); 00133 const AddressIndex& idx = container.get<impl::AddressTag>(); 00134 AddressIndex::const_iterator it = idx.begin(); 00135 int address = 0; 00136 while ( it != idx.end() ) { 00137 o << "[" << address << "]" << ": " << *it << std::endl; 00138 it++; 00139 address++; 00140 } 00141 return o; 00142 } 00143 00144 00145 // retrieve by address 00146 const Module& ModuleTable::getByAddress(int address) const throw () 00147 { 00148 ReadLock lock(mutex); 00149 const AddressIndex& idx = container.get<impl::AddressTag>(); 00150 // the following check only works for random access indices, but here it is ok 00151 const uint32_t& uaddress = address; 00152 assert( uaddress < idx.size() ); 00153 return idx.at(address); 00154 } 00155 00156 00157 // retrieve by address 00158 const std::string& ModuleTable::getModuleName(int address) const throw () 00159 { 00160 ReadLock lock(mutex); 00161 const AddressIndex& idx = container.get<impl::AddressTag>(); 00162 // the following check only works for random access indices, but here it is ok 00163 const uint32_t& uaddress = address; 00164 assert( uaddress < idx.size() ); 00165 return idx.at(address).moduleName; 00166 } 00167 00168 00169 // given a module name, look if already stored 00170 // if no, return MODULE_FAIL, otherwise return the module struct 00171 const Module& ModuleTable::getModuleByName(const std::string& moduleName) const throw() 00172 { 00173 ReadLock lock(mutex); 00174 const ModuleNameIndex& sidx = container.get<impl::ModuleNameTag>(); 00175 ModuleNameIndex::const_iterator it = sidx.find(moduleName); 00176 if( it == sidx.end() ) { 00177 return MODULE_FAIL; 00178 } 00179 else { 00180 return *it; 00181 } 00182 } 00183 00184 00185 // given a module name, look if already stored 00186 // if no, return -1, otherwise return the address 00187 int ModuleTable::getAddressByName(const std::string& moduleName) const throw() 00188 { 00189 ReadLock lock(mutex); 00190 const ModuleNameIndex& sidx = container.get<impl::ModuleNameTag>(); 00191 ModuleNameIndex::const_iterator it = sidx.find(moduleName); 00192 if( it == sidx.end() ) { 00193 return -1; 00194 } 00195 else { 00196 return container.project<impl::AddressTag>( it ) - container.get<impl::AddressTag>().begin(); 00197 } 00198 } 00199 00200 00201 // store module, assuming it does not exist 00202 // assert that symbol did not exist 00203 int ModuleTable::storeAndGetAddress(const Module& mod) throw() 00204 { 00205 assert(!mod.moduleName.empty()); 00206 00207 AddressIndex::const_iterator it; 00208 bool success; 00209 00210 WriteLock lock(mutex); 00211 AddressIndex& idx = container.get<impl::AddressTag>(); 00212 boost::tie(it, success) = idx.push_back(mod); 00213 (void)success; 00214 assert(success); 00215 00216 return ( container.project<impl::AddressTag>(it) - idx.begin() ); 00217 00218 } 00219 00220 00221 DLVHEX_NAMESPACE_END 00222 #endif // MODULETABLE_HPP_INCLUDED__20122010 00223 00224 // vim:expandtab:ts=4:sw=4: 00225 // mode: C++ 00226 // End: