Menu

[r12]: / trunk / libtop_engine / rdf_index.h  Maximize  Restore  History

Download this file

635 lines (492 with data), 16.6 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
#ifndef RDF_INDEX_H_
#define RDF_INDEX_H_
#include "rdf_rule_core.h"
#include "rdf_rule_cback.h"
namespace rdf {
/////////////////////////////////////////////////////////////////////////////////////////
// class index_triple
//
/////////////////////////////////////////////////////////////////////////////////////////
class index_triple {
public:
inline index_triple():
m_subject(0),
m_predicate(0),
m_object(0) {};
inline index_triple(index_type s, index_type p,index_type o):
m_subject(s),
m_predicate(p),
m_object(o) {};
inline index_triple(index_type const* t3):
m_subject(t3[0]),
m_predicate(t3[1]),
m_object(t3[2]) {};
inline index_triple(index_triple const& rhs):
m_subject(rhs.m_subject),
m_predicate(rhs.m_predicate),
m_object(rhs.m_object) {};
inline index_triple& operator=(index_triple const& rhs)
{
m_subject = rhs.m_subject;
m_predicate = rhs.m_predicate;
m_object = rhs.m_object;
return *this;
};
inline index_type get_subject() const{return m_subject;};
inline index_type get_predicate() const{return m_predicate;};
inline index_type get_object() const{return m_object;};
inline index_type * as_array(index_type * t3)const{
t3[0] = m_subject;
t3[1] = m_predicate;
t3[2] = m_object;
return t3;
};
private:
friend std::ostream& operator<<(std::ostream& out, index_triple const& t);
friend struct eq_index_triple;
friend struct hash_index_triple;
index_type m_subject;
index_type m_predicate;
index_type m_object;
};
inline std::ostream& operator<<(std::ostream& out, index_triple const& t)
{
out << "(" << to_string(t.m_subject) << ", "
<< to_string(t.m_predicate) << ", "
<< to_string(t.m_object) << ")";
return out;
};
struct eq_index_triple
{
inline bool operator()(index_triple const& lhs, index_triple const& rhs)const
{
return lhs.m_subject==rhs.m_subject && lhs.m_predicate==rhs.m_predicate && lhs.m_object==rhs.m_object;
};
inline bool operator()(index_type * lhs, index_type * rhs)const
{
return lhs[0]==rhs[0] && lhs[1]==rhs[1] && lhs[2]==rhs[2];
};
};
struct hash_index_triple
{
inline std::size_t operator()(index_triple const& triple)const
{
return std::size_t(triple.m_subject) + std::size_t(triple.m_predicate) + std::size_t(triple.m_object);
};
inline std::size_t operator()(index_type * t3)const
{
return std::size_t(t3[0]) + std::size_t(t3[1]) + std::size_t(t3[2]);
};
};
namespace internal {
/////////////////////////////////////////////////////////////////////////////////////////
// class wc_type
//
/////////////////////////////////////////////////////////////////////////////////////////
class wc_type {
public:
wc_type(index_type w_index, unsigned int const count=1):
m_index(w_index),
m_ref_count(count)
{};
index_type
get_index()const
{
return m_index;
};
unsigned int
get_ref_count()const
{
return m_ref_count;
};
unsigned int
add_ref_count(unsigned int count=1)const
{
m_ref_count+=count; return m_ref_count;
};
unsigned int
del_ref_count(unsigned int count=1) const
{
// //*
// if(0 == m_ref_count) std::cout << "+++++++ ERROR +++++++ SUBSTRACTING FROM 0!! in del_ref_count\n";
m_ref_count -= count;
return m_ref_count;
};
unsigned int
reset_ref_count(unsigned int count=1)const
{
m_ref_count=count; return m_ref_count;
};
private:
friend struct hash_wc;
friend struct eq_wc;
index_type m_index;
mutable unsigned int m_ref_count;
};
struct hash_wc
{
inline std::size_t operator()(wc_type const& wc)const{return std::size_t(wc.m_index);};
};
struct eq_wc
{
inline bool operator()(wc_type const& lhs, wc_type const& rhs)const{return lhs.m_index == rhs.m_index;};
};
typedef std::tr1::unordered_set<wc_type, hash_wc, eq_wc> w_set_type;
typedef std::tr1::unordered_map<index_type , w_set_type> v_map_type;
typedef std::tr1::unordered_map<index_type , v_map_type> u_map_type;
/////////////////////////////////////////////////////////////////////////////////////////
// class w_itor_set
//
/////////////////////////////////////////////////////////////////////////////////////////
class w_itor_set {
public:
inline w_itor_set():
m_itor(),
m_end()
{};
inline w_itor_set(w_set_type::const_iterator const& itor_, w_set_type::const_iterator const& end_):
m_itor(itor_),
m_end(end_)
{};
inline w_itor_set(const w_itor_set& rhs):
m_itor(rhs.m_itor),
m_end(rhs.m_end)
{};
inline w_itor_set&
operator=(const w_itor_set& rhs)
{
m_itor = rhs.m_itor; m_end = rhs.m_end;
return *this;
};
inline void
set_itor(w_set_type::const_iterator const& itor, w_set_type::const_iterator const& end)
{
m_itor=itor;
m_end=end;
};
inline index_type
get_index()const
{
return m_itor->get_index();
};
inline bool
is_end()const
{
return m_itor == m_end;
};
inline bool
next()
{
++m_itor;
return !is_end();
};
private:
w_set_type::const_iterator m_itor;
w_set_type::const_iterator m_end;
};
/////////////////////////////////////////////////////////////////////////////////////////
// class itor_map
//
/////////////////////////////////////////////////////////////////////////////////////////
template<class RItor> // RItor is either v_map_type or u_map_type
class itor_map {
public:
inline itor_map():
m_v(0),
m_itor(),
m_end(),
m_is_end(true)
{};
inline itor_map(index_type v_, typename RItor::const_iterator const& itor_, typename RItor::const_iterator const& end_):
m_v(v_),
m_itor(itor_),
m_end(end_),
m_is_end(false)
{
if(m_itor!=m_end) m_v = m_itor->first; else if(m_v==0) m_is_end = true;
};
inline itor_map(const itor_map& rhs):
m_v(rhs.m_v),
m_itor(rhs.m_itor),
m_end(rhs.m_end),
m_is_end(rhs.m_is_end){};
inline itor_map&
operator=(const itor_map& rhs)
{
m_v = rhs.m_v; m_itor = rhs.m_itor; m_end = rhs.m_end; m_is_end = rhs.m_is_end;
return *this;
};
inline void
set_itor(typename RItor::const_iterator const& itor, typename RItor::const_iterator const& end)
{
m_itor=itor; m_end=end;
};
inline index_type
get_index()const
{
return m_v;
};
inline bool
is_end()const
{
return m_is_end;
};
template<class W> // W is either itor_map<v_map_type> or w_itor_set
inline bool next(W& w_itor)
{
if(m_itor != m_end) ++m_itor;
if(m_itor == m_end) {
m_is_end = true;
m_v = 0;
return false;
}
this->set_itor_position(w_itor);
return true;
};
template<class W> // W is either itor_map<v_map_type> or w_itor_set
inline void set_itor_position(W& w_itor)
{
if(m_itor != m_end) {
m_is_end = false;
m_v = m_itor->first;
w_itor.set_itor(m_itor->second.begin(), m_itor->second.end());
}
};
private:
index_type m_v;
typename RItor::const_iterator m_itor;
typename RItor::const_iterator m_end;
bool m_is_end;
};
/////////////////////////////////////////////////////////////////////////////////////////
// class index_graph_iterator
//
/////////////////////////////////////////////////////////////////////////////////////////
class index_graph_iterator {
public:
typedef index_triple value_type;
inline index_graph_iterator(itor_map<u_map_type> const& u_itor_, itor_map<v_map_type> const& v_itor_, w_itor_set const& w_itor_):
m_u_itor(u_itor_),
m_v_itor(v_itor_),
m_w_itor(w_itor_)
{};
inline index_graph_iterator():
m_u_itor(),
m_v_itor(),
m_w_itor()
{};
inline index_graph_iterator(index_graph_iterator const& rhs):
m_u_itor(rhs.m_u_itor),
m_v_itor(rhs.m_v_itor),
m_w_itor(rhs.m_w_itor)
{};
inline index_graph_iterator&
operator=(index_graph_iterator const& rhs)
{
m_u_itor = rhs.m_u_itor; m_v_itor = rhs.m_v_itor; m_w_itor = rhs.m_w_itor;
return *this;
};
inline bool
is_end()const
{
return m_u_itor.is_end() and m_v_itor.is_end() and m_w_itor.is_end();
};
inline bool
next() {
if(is_end()) return false;
if(!m_w_itor.next()) {
if(!m_v_itor.next(m_w_itor)) {
if(m_u_itor.next(m_v_itor)) {
m_v_itor.set_itor_position(m_w_itor);
}
}
}
return !is_end();
};
// function member not used by rdf_graph since lookup_spo must be called
// to unwind the indexes.
inline value_type
get_triple()const
{
return value_type(m_u_itor.get_index(), m_v_itor.get_index(), m_w_itor.get_index());
};
private:
friend void lookup_spo(char const m_lookup, index_type &s, index_type &p, index_type &o, index_graph_iterator const& m_index_itor);
itor_map<u_map_type> m_u_itor;
itor_map<v_map_type> m_v_itor;
w_itor_set m_w_itor;
};
/////////////////////////////////////////////////////////////////////////////////////////
// lookup_spo
//
/////////////////////////////////////////////////////////////////////////////////////////
inline void lookup_spo(char const m_lookup, index_type &s, index_type &p, index_type &o, index_graph_iterator const& m_index_itor)
{
if(m_lookup == 's') { // case 'spo' <==> "uvw'
s = m_index_itor.m_u_itor.get_index();
p = m_index_itor.m_v_itor.get_index();
o = m_index_itor.m_w_itor.get_index();
} else if(m_lookup == 'p') { // case 'pos' <==> "uvw'
s = m_index_itor.m_w_itor.get_index();
p = m_index_itor.m_u_itor.get_index();
o = m_index_itor.m_v_itor.get_index();
} else { // case 'osp' <==> "uvw'
s = m_index_itor.m_v_itor.get_index();
p = m_index_itor.m_w_itor.get_index();
o = m_index_itor.m_u_itor.get_index();
}
};
/////////////////////////////////////////////////////////////////////////////////////////
// class index_graph
//
/////////////////////////////////////////////////////////////////////////////////////////
class index_graph {
public:
typedef index_graph_iterator iterator;
typedef w_set_type::iterator w_itor_type;
typedef v_map_type::iterator v_itor_type;
typedef u_map_type::iterator u_itor_type;
typedef w_set_type::const_iterator w_const_itor_type;
typedef v_map_type::const_iterator v_const_itor_type;
typedef u_map_type::const_iterator u_const_itor_type;
inline index_graph(unsigned int size=20):
m_initial_size(size),
m_index(m_initial_size),
m_v_end(),
m_w_end(),
m_session_p(NULL),
m_index_triple_cback_mgr_p(NULL) {};
inline void set_initial_size(unsigned int size) {m_initial_size = size;};
/*
* return true if (u, v, w) exist, false otherwise.
*/
inline bool
contains(index_type u, index_type v, index_type w) const
{
u_const_itor_type utor = m_index.find(u);
if(utor == m_index.end()) return false;
v_const_itor_type vtor = utor->second.find(v);
if(vtor == utor->second.end()) return false;
w_set_type::const_iterator wtor = vtor->second.find(wc_type(w));
if(wtor == vtor->second.end()) return false;
return true;
};
/*
* return true if (u, v, *) exist, false otherwise.
*/
inline bool
contains(index_type u, index_type v) const
{
u_const_itor_type utor = m_index.find(u);
if(utor == m_index.end()) return false;
v_const_itor_type vtor = utor->second.find(v);
if(vtor == utor->second.end()) return false;
return true;
};
iterator
find() const;
inline iterator
find_all()const
{
return find();
};
iterator
find(index_type u) const;
iterator
find(index_type u, index_type v) const;
// returns the reference count in the inferred graph.
// used by rule_term to determine if an inferred triple will
// be removed as result of retract call.
inline unsigned int
get_ref_count(index_type u, index_type v, index_type w)const
{
u_const_itor_type utor = m_index.find(u);
if(utor == m_index.end()) return 0;
v_const_itor_type vtor = utor->second.find(v);
if(vtor == utor->second.end()) return 0;
w_set_type::const_iterator wtor = vtor->second.find(wc_type(w));
if(wtor == vtor->second.end()) return 0;
return wtor->get_ref_count();
};
// increase the reference count if type wc_type
inline bool insert(index_type u, index_type v, index_type w, bool notify_listners=true)
{
u_itor_type utor = m_index.find(u);
if(utor == m_index.end()) {
utor = m_index.insert(u_map_type::value_type(u, v_map_type(m_initial_size))).first;
}
v_itor_type vtor = utor->second.find(v);
if(vtor == utor->second.end()) {
vtor = utor->second.insert(v_map_type::value_type(v, w_set_type(m_initial_size))).first;
}
std::pair<w_set_type::iterator, bool> pair = vtor->second.insert(wc_type(w));
if(!pair.second) pair.first->add_ref_count();
// apply the call back functors
if(notify_listners and m_index_triple_cback_mgr_p and pair.second) m_index_triple_cback_mgr_p->triple_inserted(m_session_p, u, v, w);
return pair.second;
};
// delete the triple regardless if reference count is in use
inline unsigned int erase (index_type u, index_type v, index_type w)
{
u_itor_type utor = m_index.find(u);
if(utor == m_index.end()) return 0;
v_itor_type vtor = utor->second.find(v);
if(vtor == utor->second.end()) return 0;
unsigned int count = vtor->second.erase(wc_type(w));
if(vtor->second.empty()) {
utor->second.erase(v);
if(utor->second.empty()) {
m_index.erase(u);
}
}
// apply the call back functors
if(m_index_triple_cback_mgr_p and count>0) m_index_triple_cback_mgr_p->triple_deleted(m_session_p, u, v, w);
return count;
};
// reduce reference count, if in use, delete if ref count is zero
inline unsigned int retract(index_type u, index_type v, index_type w)
{
u_itor_type utor = m_index.find(u);
if(utor == m_index.end()) return 0;
v_itor_type vtor = utor->second.find(v);
if(vtor == utor->second.end()) return 0;
unsigned int count = 0;
w_set_type::iterator wtor = vtor->second.find(wc_type(w));
if(wtor == vtor->second.end()) return 0;
if(wtor->del_ref_count() == 0) {
vtor->second.erase(wtor);
if(vtor->second.empty()) {
utor->second.erase(v);
if(utor->second.empty()) {
m_index.erase(u);
}
}
count = 1;
}
// apply the call back functors
if(m_index_triple_cback_mgr_p and count>0) m_index_triple_cback_mgr_p->triple_deleted(m_session_p, u, v, w);
return count;
};
inline void register_call_back_manager(rule::rule_session * session_p, index_triple_cback_mgr const* callback_mgr_p)
{
m_session_p = session_p;
m_index_triple_cback_mgr_p = callback_mgr_p;
};
inline void unregister_call_back_manager()
{
m_session_p = NULL;
m_index_triple_cback_mgr_p = NULL;
};
private:
unsigned int m_initial_size;
u_map_type m_index;
// have empty iterators
v_const_itor_type m_v_end;
w_const_itor_type m_w_end;
// callback functors manager
rule::rule_session * m_session_p;
index_triple_cback_mgr const* m_index_triple_cback_mgr_p;
};
}; /*namespace internal */
}; /*namespace rdf */
#endif /*RDF_INDEX_H_*/
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.