OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
AtomCache.cc
Go to the documentation of this file.
1 
13 #ifdef HAVE_LIBMEMCACHED
14 
15 #include "AtomCache.h"
16 
17 #include <string>
18 
19 #include <memcached.h>
20 
21 #include <opencog/util/platform.h>
22 #include <opencog/atomspace/Atom.h>
25 #include <opencog/atomspace/Node.h>
26 #include <opencog/atomspace/Link.h>
28 #include <opencog/atomspace/TLB.h>
30 
31 using namespace opencog;
32 
33 AtomCache::AtomCache(const std::string server, int portno)
34 {
35  memcached_return rc;
36  mc = memcached_create(NULL);
37 
38  memcached_server_st *servers;
39  const char *servername = server.c_str();
40  servers = memcached_server_list_append(NULL, (char *) servername, portno, &rc);
41 
42  connect_status = memcached_server_push(mc, servers);
43 
44  memcached_server_list_free(servers);
45 
46  store_count = 0;
47 }
48 
49 AtomCache::~AtomCache()
50 {
51  memcached_free(mc);
52 }
53 
54 /* ================================================================== */
55 
56 #define CHECK_RC(rc) \
57  if(MEMCACHED_SUCCESS != rc) \
58  { \
59  fprintf(stderr, "Error: memcachedb: %s\n", memcached_strerror(mc, rc)); \
60  return; \
61  }
62 
63 void AtomCache::storeAtom(Atom *atom)
64 {
65  memcached_return rc;
66 
67  Handle h = atom->getHandle();
68 
69  // Set up the basic root of the key
70 #define KBSIZE 50
71  char keybuff[KBSIZE];
72  int rootlen = snprintf(keybuff, KBSIZE, "%lu/", h);
73  char *p = &keybuff[rootlen];
74 
75  // The buffer for values.
76 #define VBSIZE 1050
77  char valbuff[VBSIZE];
78 
79  // Get the atom type.
80  Type t = atom->getType();
81  strcpy(p, "type");
82  int vlen = snprintf(valbuff, VBSIZE, "%d", t);
83 
84  rc = memcached_set (mc, keybuff, rootlen+4, valbuff, vlen, 0, 0);
85  CHECK_RC(rc);
86 
87  // If a node, store the name
88  Node *n = dynamic_cast<Node *>(atom);
89  if (n)
90  {
91  strcpy(p, "name");
92  const char *name = n->getName().c_str();
93  vlen = n->getName().size();
94  rc = memcached_set (mc, keybuff, rootlen+4, name, vlen, 0, 0);
95  CHECK_RC(rc);
96  }
97  else
98  {
99  // Store the outgoing set
100  Link *l = dynamic_cast<Link *>(atom);
101  int arity = l->getArity();
102  vlen = snprintf(valbuff, VBSIZE, "(%d", arity);
103 
104  std::vector<Handle> out = l->getOutgoingSet();
105  for (int i=0; i<arity; i++)
106  {
107  vlen += snprintf(valbuff+vlen, VBSIZE-vlen, ", %lu", out[i]);
108  }
109 
110  vlen += snprintf(valbuff+vlen, VBSIZE-vlen, ")");
111  strcpy(p, "edges");
112  rc = memcached_set (mc, keybuff, rootlen+5, valbuff, vlen, 0, 0);
113  CHECK_RC(rc);
114  }
115 
116  // Store the truth value
117  const TruthValue &tv = atom->getTruthValue();
118  const SimpleTruthValue *stv = dynamic_cast<const SimpleTruthValue *>(&tv);
119  if (NULL == stv)
120  {
121  fprintf(stderr, "Error: non-simple truth values are not handled\n");
122  return;
123  }
124 
125  vlen = snprintf(valbuff, VBSIZE, "(%20.16g, %20.16g)", tv.getMean(), tv.getCount());
126  strcpy(p, "stv");
127  rc = memcached_set (mc, keybuff, rootlen+3, valbuff, vlen, 0, 0);
128  CHECK_RC(rc);
129 }
130 
131 /* ================================================================== */
132 
133 #define NCHECK_RC(rc, val) \
134  if(MEMCACHED_SUCCESS != rc) \
135  { \
136  fprintf(stderr, "Error: memcachedb: %s\n", memcached_strerror(mc, rc)); \
137  if (val) free(val); \
138  return atom; \
139  }
140 
141 Atom * AtomCache::getAtom(Handle h)
142 {
143  size_t vlen;
144  uint32_t flags;
145  memcached_return rc;
146  char * val;
147 
148  char keybuff[KBSIZE];
149  int rootlen = snprintf(keybuff, KBSIZE, "%lu/", h);
150  char *p = &keybuff[rootlen];
151 
152  // Does the atom exist already ?
153  Atom *atom = TLB::getAtom(h);
154 
155  if (NULL == atom)
156  {
157  // Get the atom type.
158  strcpy(p, "type");
159  val = memcached_get(mc, keybuff, rootlen+4, &vlen, &flags, &rc);
160  NCHECK_RC(rc, val);
161  int atype = atoi(val);
162  free(val);
163 
164  if (classserver().isAssignableFrom(NODE, atype))
165  {
166  // Get the atom name
167  strcpy(p, "name");
168  val = memcached_get(mc, keybuff, rootlen+4, &vlen, &flags, &rc);
169  NCHECK_RC(rc, val);
170  atom = new Node(atype, val);
171  free(val);
172  }
173  else
174  {
175  // Get the outvec.
176  strcpy(p, "edges");
177  val = memcached_get(mc, keybuff, rootlen+5, &vlen, &flags, &rc);
178  NCHECK_RC(rc, val);
179 
180  int arity = atoi(val+1);
181  std::vector<Handle> outvec;
182  outvec.resize(arity);
183 
184  char *comma = strchr(val+2, ',');
185  for (int i=0; i<arity; i++)
186  {
187  Handle ho = (Handle) strtoul(comma+1, &comma, 10);
188  outvec.at(i) = ho;
189  }
190  atom = new Link(atype, outvec);
191  }
192  }
193 
194  // Fetch the truth value
195  const TruthValue &tv = atom->getTruthValue();
196  const SimpleTruthValue *stv = dynamic_cast<const SimpleTruthValue *>(&tv);
197  if (NULL == stv)
198  {
199  fprintf(stderr, "Error: non-simple truth values are not handled\n");
200  return atom;
201  }
202 
203  strcpy(p, "stv");
204  val = memcached_get(mc, keybuff, rootlen+3, &vlen, &flags, &rc);
205  NCHECK_RC(rc, val);
206 
207  double mean = atof(val+1);
208  char *comma = strchr(val+2, ',');
209  double count = atof(comma+1);
210  SimpleTruthValue nstv(mean,count);
211  atom->setTruthValue(nstv);
212 
213  return atom;
214 }
215 
216 /* ================================================================== */
217 
218 void AtomCache::load_list(AtomTable &table, int depth)
219 {
220  size_t vlen;
221  uint32_t flags;
222  memcached_return rc;
223  char * val;
224 
225  char keybuff[KBSIZE];
226  size_t klen = snprintf(keybuff, KBSIZE, "depth-list-%d", depth);
227  val = memcached_get(mc, keybuff, klen, &vlen, &flags, &rc);
228 
229 printf("duude depth=%d nodelist len=%d\n", depth, vlen);
230  if ((vlen == 0) || (NULL == val)) return;
231 
232  unsigned long ilc = load_count;
233  char *comma = val;
234  while (comma)
235  {
236  Handle h = (Handle) strtoul(comma+1, &comma, 10);
237  getAtom(h);
238  load_count ++;
239  if (load_count%1000 == 0)
240  {
241  fprintf(stderr, "\tLoaded %lu atoms.\n", load_count);
242  }
243  }
244  free(val);
245 
246  fprintf(stderr, "\tLoaded %lu atoms of depth %d.\n", load_count- ilc, depth);
247 }
248 
249 void AtomCache::load(AtomTable &table)
250 {
251  load_count = 0;
252  for (int i=0; i<MAX_LATTICE_DEPTH; i++)
253  {
254  load_list(table, i);
255  }
256 }
257 
258 /* ================================================================== */
259 
260 int AtomCache::depth(Atom *atom)
261 {
262  Link *l = dynamic_cast<Link *>(atom);
263  if (NULL == l) return 0;
264 
265  int maxd = 0;
266  int arity = l->getArity();
267 
268  std::vector<Handle> out = l->getOutgoingSet();
269  for (int i=0; i<arity; i++)
270  {
271  Handle h = out[i];
272  int d = depth(TLB::getAtom(h));
273  if (maxd < d) maxd = d;
274  }
275  return maxd +1;
276 }
277 
278 /* ================================================================== */
279 
280 bool AtomCache::store_cb(Atom *atom)
281 {
282  Handle h = atom->getHandle();
283 
284  // Build an index of atoms of a given depth
285  char hbuff[KBSIZE];
286  snprintf(hbuff, KBSIZE, "%lu, ", h);
287 
288  int d = depth(atom);
289  depth_list[d] += hbuff;
290  if (maxdepth < d) maxdepth = d;
291 
292  // store the acctual atom.
293  storeAtom(atom);
294  store_count ++;
295  if (store_count%1000 == 0)
296  {
297  fprintf(stderr, "\tStored %lu atoms.\n", store_count);
298  }
299  return false;
300 }
301 
302 void AtomCache::store(const AtomTable &table)
303 {
304  memcached_return rc;
305  int i;
306  maxdepth = 0;
307 
308  for (i=0; i<MAX_LATTICE_DEPTH; i++)
309  {
310  depth_list[i] = "(";
311  }
312 
313  table.foreach_atom(&AtomCache::store_cb, this);
314 
315  // store the index lists too
316  for (i=0; i<maxdepth; i++)
317  {
318  depth_list[i] += ")";
319 
320  char keybuff[KBSIZE];
321  size_t klen = snprintf(keybuff, KBSIZE, "depth-list-%d", i);
322  rc = memcached_set (mc, keybuff, klen, depth_list[i].c_str(), depth_list[i].size(), 0, 0);
323  CHECK_RC(rc);
324  }
325 }
326 
327 #endif /* HAVE_LIBMEMCACHED */
328 
329 /* ======================= END OF FILE ============================== */
virtual count_t getCount() const =0
a TruthValue that stores a mean and the number of observations (strength and confidence) ...
Handle getHandle()
Definition: Atom.h:211
Type getType() const
Definition: Atom.h:197
void setTruthValue(TruthValuePtr)
Sets the TruthValue object of the atom.
Definition: Atom.cc:81
ClassServer & classserver(ClassServerFactory *=ClassServer::createInstance)
Definition: ClassServer.cc:159
const std::string & getName() const
Definition: Node.h:87
TruthValuePtr getTruthValue()
Definition: Atom.cc:104
unsigned short Type
type of Atoms, represented as short integer (16 bits)
Definition: types.h:40
virtual strength_t getMean() const =0