OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ClassServer.h
Go to the documentation of this file.
1 /*
2  * opencog/atomspace/ClassServer.h
3  *
4  * Copyright (C) 2011 by The OpenCog Foundation
5  * All Rights Reserved
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License v3 as
9  * published by the Free Software Foundation and including the exceptions
10  * at http://opencog.org/wiki/Licenses
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program; if not, write to:
19  * Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #ifndef _OPENCOG_CLASS_SERVER_H
24 #define _OPENCOG_CLASS_SERVER_H
25 
26 #include <mutex>
27 #include <unordered_map>
28 #include <vector>
29 
30 #include <boost/signals2.hpp>
31 
33 #include <opencog/atomspace/atom_types.h>
34 
35 namespace opencog
36 {
41 class ClassServer;
42 
44 
50 typedef boost::signals2::signal<void (Type)> TypeSignal;
52 {
53 private:
54 
56  ClassServer();
57 
58  /* It is very tempting to make the type_mutex into a reader-writer
59  * mutex. However, it appears that this is a bad idea: reader-writer
60  * mutexes cause cache-line ping-ponging when there is contention,
61  * effecitvely serializing access, and are just plain slower when
62  * there is no contention. Thus, the current implementations seem
63  * to be a lose-lose proposition. See the Anthony Williams post here:
64  * http://permalink.gmane.org/gmane.comp.lib.boost.devel/211180
65  */
66  mutable std::mutex type_mutex;
67 
69 
70  std::vector< std::vector<bool> > inheritanceMap;
71  std::vector< std::vector<bool> > recursiveMap;
72  std::unordered_map<std::string, Type> name2CodeMap;
73  std::unordered_map<Type, const std::string*> code2NameMap;
75 
76  void setParentRecursively(Type parent, Type type);
77 
78 public:
80  static ClassServer* createInstance(void);
81 
83  Type addType(const Type parent, const std::string& name);
84 
90 
95  template<typename OutputIterator>
96  unsigned long getChildren(Type type, OutputIterator result)
97  {
98  unsigned long n_children = 0;
99  for (Type i = 0; i < nTypes; ++i) {
100  if (inheritanceMap[type][i] && (type != i)) {
101  *(result++) = i;
102  n_children++;
103  }
104  }
105  return n_children;
106  }
107 
108  template <typename OutputIterator>
109  unsigned long getChildrenRecursive(Type type, OutputIterator result)
110  {
111  unsigned long n_children = 0;
112  for (Type i = 0; i < nTypes; ++i) {
113  if (recursiveMap[type][i] && (type != i)) {
114  *(result++) = i;
115  n_children++;
116  }
117  }
118  return n_children;
119  }
120 
121  template <typename Function>
122  void foreachRecursive(Function func, Type type)
123  {
124  for (Type i = 0; i < nTypes; ++i) {
125  if (recursiveMap[type][i]) (func)(i);
126  }
127  }
128 
135 
144  bool isA(Type sub, Type super)
145  {
146  /* Because this method is called extremely often, we want
147  * the best-case fast-path for it. Since updates are extremely
148  * unlikely after initialization, we use a multi-reader lock,
149  * and don't care at all about writer starvation, since there
150  * will almost never be writers. However, see comments above
151  * about multi-reader-locks -- we are not using them just right
152  * now, because they don't seem to actually help. */
153  std::lock_guard<std::mutex> l(type_mutex);
154  if ((sub >= nTypes) || (super >= nTypes)) return false;
155  return recursiveMap[super][sub];
156  }
157 
158  bool isA_non_recursive(Type sub, Type super);
159 
166  bool isValid(Type t) { return isA(t, ATOM); }
167 
174  bool isLink(Type t) { return isA(t, LINK); }
175 
182  bool isNode(Type t) { return isA(t, NODE); }
183 
187  bool isDefined(const std::string& typeName);
188 
195  Type getType(const std::string& typeName);
196 
203  const std::string& getTypeName(Type type);
204 };
205 
208 
210 } // namespace opencog
211 
212 #endif // _OPENCOG_CLASS_SERVER_H
bool isNode(Type t)
Definition: ClassServer.h:182
std::unordered_map< std::string, Type > name2CodeMap
Definition: ClassServer.h:72
std::vector< std::vector< bool > > recursiveMap
Definition: ClassServer.h:71
std::mutex type_mutex
Definition: ClassServer.h:66
unsigned long getChildrenRecursive(Type type, OutputIterator result)
Definition: ClassServer.h:109
Type addType(const Type parent, const std::string &name)
Definition: ClassServer.cc:60
ClassServer & classserver(ClassServerFactory *=ClassServer::createInstance)
Definition: ClassServer.cc:159
unsigned long getChildren(Type type, OutputIterator result)
Definition: ClassServer.h:96
bool isValid(Type t)
Definition: ClassServer.h:166
static ClassServer * createInstance(void)
Definition: ClassServer.cc:55
bool isDefined(const std::string &typeName)
Definition: ClassServer.cc:132
ClassServer * ClassServerFactory(void)
Definition: ClassServer.h:43
TypeSignal & addTypeSignal()
Definition: ClassServer.cc:115
const std::string & getTypeName(Type type)
Definition: ClassServer.cc:148
bool isA(Type sub, Type super)
Definition: ClassServer.h:144
void setParentRecursively(Type parent, Type type)
Definition: ClassServer.cc:105
std::unordered_map< Type, const std::string * > code2NameMap
Definition: ClassServer.h:73
bool isA_non_recursive(Type sub, Type super)
Definition: ClassServer.cc:125
void foreachRecursive(Function func, Type type)
Definition: ClassServer.h:122
bool isLink(Type t)
Definition: ClassServer.h:174
Type getType(const std::string &typeName)
Definition: ClassServer.cc:138
boost::signals2::signal< void(Type)> TypeSignal
Definition: ClassServer.h:50
unsigned short Type
type of Atoms, represented as short integer (16 bits)
Definition: types.h:40
std::vector< std::vector< bool > > inheritanceMap
Definition: ClassServer.h:70
TypeSignal _addTypeSignal
Definition: ClassServer.h:74