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 TABLE_HPP_INCLUDED__12102010 00035 #define TABLE_HPP_INCLUDED__12102010 00036 00037 #include "dlvhex2/PlatformDefinitions.h" 00038 #include "dlvhex2/ID.h" 00039 #include "dlvhex2/Logger.h" 00040 00041 #include <boost/multi_index_container.hpp> 00042 #include <boost/thread/shared_mutex.hpp> 00043 00044 DLVHEX_NAMESPACE_BEGIN 00045 00046 namespace impl 00047 { 00048 // these tags are common to all tables 00049 struct KindTag {}; 00050 struct AddressTag {}; 00051 00052 // these tags are special 00053 struct TermTag // Term 00054 { 00055 }; 00056 struct PredicateNameTag // Predicate 00057 { 00058 }; 00059 struct ModuleNameTag // Module 00060 { 00061 }; 00062 struct TextTag // OrdinaryGroundAtom 00063 { 00064 }; 00065 struct TupleTag // OrdinaryAtom, OrdinaryGroundAtom 00066 { 00067 }; 00068 struct PredicateTag // ExternalAtom 00069 { 00070 }; 00071 struct ElementTag // for MLPSolver 00072 { 00073 }; 00074 struct InstTag // instantiation Tag, for ordinary ground atom (for MLP case) 00075 { 00076 }; 00077 } 00078 00079 00081 template<typename ValueT, typename IndexT> 00082 class Table: 00083 public ostream_printable< Table<ValueT,IndexT> > 00084 { 00085 // types 00086 public: 00087 typedef typename 00088 boost::multi_index_container<ValueT, IndexT> Container; 00089 00090 // public, because other algorithms might need to lock this 00092 mutable boost::shared_mutex mutex; 00093 typedef boost::shared_lock<boost::shared_mutex> ReadLock; 00094 typedef boost::unique_lock<boost::shared_mutex> WriteLock; 00095 00096 // storage 00097 protected: 00099 Container container; 00100 00101 // methods 00102 public: 00104 Table() {} 00105 // no virtual functions allowed, no virtual destructor 00106 // -> never store this in a ref to baseclass, destruction will not work! 00107 // 00108 // -> make all derived classes efficient using small inline methods 00109 //virtual ~Table() {} 00110 00111 // all accessors using indices are specific to the respective tables 00112 // we will only create those accessors we really need 00113 // two important objectives: space efficiency and time efficiency 00114 00118 std::ostream& print(std::ostream& o) const; 00119 00122 Table(const Table& other): 00123 container(other.container) { 00124 } 00125 00129 Table& operator=(const Table& other) { 00130 WriteLock lock(mutex); 00131 container = other.container; 00132 } 00133 00136 inline unsigned getSize() const 00137 { 00138 ReadLock lock(mutex); 00139 return container.size(); 00140 } 00141 }; 00142 00143 template<typename ValueT, typename IndexT> 00144 std::ostream& Table<ValueT,IndexT>::print(std::ostream& o) const 00145 { 00146 ReadLock lock(mutex); 00147 // debugging assumes that each container can be iterated by AddressTag index and contains KindTag index 00148 typedef typename Container::template index<impl::AddressTag>::type AddressIndex; 00149 const AddressIndex& aidx = container.template get<impl::AddressTag>(); 00150 00151 for(typename AddressIndex::const_iterator it = aidx.begin(); 00152 it != aidx.end(); ++it) { 00153 const uint32_t address = static_cast<uint32_t>(it - aidx.begin()); 00154 // for the next line to work, ValueT must be derived from ostream_printable<ValueT> 00155 o << 00156 " " << ID(it->kind, address) << std::endl << 00157 " -> " << static_cast<const ValueT&>(*it) << std::endl; 00158 } 00159 return o; 00160 } 00161 00162 00163 DLVHEX_NAMESPACE_END 00164 #endif // TABLE_HPP_INCLUDED__12102010 00165 00166 // vim:expandtab:ts=4:sw=4: 00167 // mode: C++ 00168 // End: