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 EXTERNALATOMTABLE_HPP_INCLUDED__18102010 00035 #define EXTERNALATOMTABLE_HPP_INCLUDED__18102010 00036 00037 #include "dlvhex2/PlatformDefinitions.h" 00038 #include "dlvhex2/fwd.h" 00039 #include "dlvhex2/Atoms.h" 00040 #include "dlvhex2/Table.h" 00041 00042 #include <boost/multi_index/member.hpp> 00043 #include <boost/multi_index/ordered_index.hpp> 00044 00045 DLVHEX_NAMESPACE_BEGIN 00046 00048 class ExternalAtomTable: 00049 public Table< 00050 // value type is symbol struct 00051 ExternalAtom, 00052 // index is 00053 boost::multi_index::indexed_by< 00054 // address = running ID for constant access 00055 boost::multi_index::random_access< 00056 boost::multi_index::tag<impl::AddressTag> 00057 >, 00058 boost::multi_index::ordered_non_unique< 00059 boost::multi_index::tag<impl::PredicateTag>, 00060 BOOST_MULTI_INDEX_MEMBER(ExternalAtom,ID,predicate) 00061 > 00062 > 00063 > 00064 { 00065 // types 00066 public: 00067 typedef Container::index<impl::AddressTag>::type AddressIndex; 00068 typedef Container::index<impl::PredicateTag>::type PredicateIndex; 00069 typedef PredicateIndex::iterator PredicateIterator; 00070 00071 // methods 00072 public: 00079 inline const ExternalAtom& getByID(ID id) const throw (); 00080 00084 // NOTE: you may need to lock the mutex also while iterating! 00085 // if you intend to use this method frequently, consider to use a PredicateMask instead for better efficiency (iteration is slow) 00086 inline std::pair<PredicateIterator, PredicateIterator> 00087 getRangeByPredicateID(ID id) const throw(); 00088 00092 inline ID storeAndGetID(const ExternalAtom& atom) throw(); 00093 00099 inline void update( 00100 const ExternalAtom& oldStorage, ExternalAtom& newStorage) throw(); 00101 00109 std::ostream& print(std::ostream& o, RegistryPtr reg) const throw(); 00110 }; 00111 00112 // retrieve by ID 00113 // assert that id.kind is correct for Term 00114 // assert that ID exists 00115 const ExternalAtom& 00116 ExternalAtomTable::getByID(ID id) const throw () 00117 { 00118 assert(id.isAtom() || id.isLiteral()); 00119 assert(id.isExternalAtom()); 00120 00121 ReadLock lock(mutex); 00122 const AddressIndex& idx = container.get<impl::AddressTag>(); 00123 // the following check only works for random access indices, but here it is ok 00124 assert( id.address < idx.size() ); 00125 return idx.at(id.address); 00126 } 00127 00128 00129 // get all external atoms with certain predicate id 00130 // NOTE: you may need to lock the mutex also while iterating! 00131 // if you intend to use this method frequently, consider to use a PredicateMask instead for better efficiency (iteration is slow) 00132 std::pair<ExternalAtomTable::PredicateIterator, ExternalAtomTable::PredicateIterator> 00133 ExternalAtomTable::getRangeByPredicateID(ID id) const throw() 00134 { 00135 assert(id.isTerm() && id.isConstantTerm()); 00136 ReadLock lock(mutex); 00137 const PredicateIndex& idx = container.get<impl::PredicateTag>(); 00138 return idx.equal_range(id); 00139 } 00140 00141 00142 // store symbol, assuming it does not exist (this is only asserted) 00143 ID ExternalAtomTable::storeAndGetID( 00144 const ExternalAtom& atm) throw() 00145 { 00146 assert(ID(atm.kind,0).isAtom()); 00147 assert(ID(atm.kind,0).isExternalAtom()); 00148 00149 AddressIndex::const_iterator it; 00150 bool success; 00151 00152 WriteLock lock(mutex); 00153 AddressIndex& idx = container.get<impl::AddressTag>(); 00154 boost::tie(it, success) = idx.push_back(atm); 00155 (void)success; 00156 assert(success); 00157 00158 return ID( 00159 atm.kind, // kind 00160 // address 00161 container.project<impl::AddressTag>(it) - idx.begin() 00162 ); 00163 } 00164 00165 00166 void ExternalAtomTable::update( 00167 const ExternalAtom& oldStorage, ExternalAtom& newStorage) throw() 00168 { 00169 bool success; 00170 00171 WriteLock lock(mutex); 00172 AddressIndex& idx = container.get<impl::AddressTag>(); 00173 AddressIndex::iterator it(idx.iterator_to(oldStorage)); 00174 assert(it != idx.end()); 00175 success = idx.replace(it, newStorage); 00176 (void)success; 00177 assert(success); 00178 } 00179 00180 00181 DLVHEX_NAMESPACE_END 00182 #endif // BUILTINATOMTABLE_HPP_INCLUDED__12102010 00183 00184 // vim:expandtab:ts=4:sw=4: 00185 // mode: C++ 00186 // End: