dlvhex  2.5.0
include/dlvhex2/Table.h
Go to the documentation of this file.
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: