#ifndef RDF_RULE_CBACK_H_
#define RDF_RULE_CBACK_H_
#include "rdf_rule_core.h"
namespace rule {
class knowledge_rule;
class rule_session;
namespace internal {
class knowledge_term;
class beta_relation;
class rule_term_base;
typedef std::tr1::shared_ptr<rule_term_base> rule_term_ptr_type;
};
};
namespace rdf {
class index_triple_cback {
typedef rule::internal::rule_vertex vertex_t;
public:
index_triple_cback(rule::knowledge_rule const* rule_p, rule::internal::knowledge_term const* kterm_p, vertex_t const u, vertex_t const v):
m_krule_p(rule_p),
m_kterm_p(kterm_p),
m_u(u), m_v(v) {};
index_triple_cback():
m_krule_p(NULL),
m_kterm_p(NULL),
m_u(0), m_v(0) {};
index_triple_cback(index_triple_cback const& rhs):
m_krule_p(rhs.m_krule_p),
m_kterm_p(rhs.m_kterm_p),
m_u(rhs.m_u), m_v(rhs.m_v) {};
void triple_inserted(rule::rule_session *session, index_type s, index_type p, index_type o)const;
void triple_deleted (rule::rule_session *session, index_type s, index_type p, index_type o)const;
protected:
/* Called by triple_inserted / triple_deleted */
void perform_merge_row (
rule::rule_session *session_p,
rule::internal::beta_relation& relation,
rule::internal::rule_term_ptr_type const& rule_term,
index_type const s, index_type const p, index_type const o)const;
void perform_remove_row(
rule::rule_session *session_p,
rule::internal::beta_relation& relation,
rule::internal::rule_term_ptr_type const& rule_term,
index_type const s, index_type const p, index_type const o)const;
private:
rule::knowledge_rule const* m_krule_p;
rule::internal::knowledge_term const* m_kterm_p;
vertex_t m_u, m_v;
};
typedef std::tr1::shared_ptr<index_triple_cback> index_triple_cback_ptr_type;
// class to manage the callbacks, callbacks are dependent on schema graph, not user session graph
// therefore the lookups are factored out and constructed by knowledge_base
typedef index_triple_cback_ptr_type cback_t;
typedef std::vector<cback_t> cback_map_t;
typedef std::tr1::unordered_multimap<index_type , cback_t> cback_u_map_t;
typedef std::tr1::unordered_multimap<internal::uv_t, cback_t, internal::hash_uv, internal::eq_uv> cback_uv_map_t;
class index_triple_cback_mgr {
public:
inline index_triple_cback_mgr(char const lookup):
m_lookup(lookup),
m_cback_map(),
m_cback_u_map(),
m_cback_uv_map() {};
void register_call_back(index_triple_cback_ptr_type const& callback)
{
m_cback_map.push_back(callback);
};
void register_call_back(index_type u, index_triple_cback_ptr_type const& callback)
{
m_cback_u_map.insert(cback_u_map_t::value_type(u, callback));
};
void register_call_back(index_type u, index_type v, index_triple_cback_ptr_type const& callback)
{
m_cback_uv_map.insert(cback_uv_map_t::value_type(internal::uv_t(u, v), callback));
};
inline void triple_inserted(rule::rule_session *session, index_type u, index_type v, index_type w)const
{
index_type s;
index_type p;
index_type o;
lookup_spo(m_lookup, s, p, o, u, v, w);
cback_map_t::const_iterator itor = m_cback_map.begin();
cback_map_t::const_iterator end = m_cback_map.end();
for(; itor!=end; ++itor) (*itor)->triple_inserted(session, s, p, o);
if(!m_cback_u_map.empty()) {
cback_u_map_t::const_iterator itor;
cback_u_map_t::const_iterator end;
boost::tie(itor, end) = m_cback_u_map.equal_range(u);
for(; itor!=end; ++itor) itor->second->triple_inserted(session, s, p, o);
};
if(!m_cback_uv_map.empty()) {
cback_uv_map_t::const_iterator itor;
cback_uv_map_t::const_iterator end;
boost::tie(itor, end) = m_cback_uv_map.equal_range(internal::uv_t(u, v));
for(; itor!=end; ++itor) itor->second->triple_inserted(session, s, p, o);
};
};
inline void triple_deleted(rule::rule_session *session, index_type u, index_type v, index_type w)const
{
index_type s;
index_type p;
index_type o;
lookup_spo(m_lookup, s, p, o, u, v, w);
cback_map_t::const_iterator itor = m_cback_map.begin();
cback_map_t::const_iterator end = m_cback_map.end();
for(; itor!=end; ++itor) (*itor)->triple_deleted(session, s, p, o);
if(!m_cback_u_map.empty()) {
cback_u_map_t::const_iterator itor;
cback_u_map_t::const_iterator end;
boost::tie(itor, end) = m_cback_u_map.equal_range(u);
for(; itor!=end; ++itor) itor->second->triple_deleted(session, s, p, o);
};
if(!m_cback_uv_map.empty()) {
cback_uv_map_t::const_iterator itor;
cback_uv_map_t::const_iterator end;
boost::tie(itor, end) = m_cback_uv_map.equal_range(internal::uv_t(u, v));
for(; itor!=end; ++itor) itor->second->triple_deleted(session, s, p, o);
};
};
inline unsigned int
size()const
{
return m_cback_map.size() + m_cback_u_map.size() + m_cback_uv_map.size();
};
private:
char const m_lookup;
cback_map_t m_cback_map;
cback_u_map_t m_cback_u_map;
cback_uv_map_t m_cback_uv_map;
};
class rdf_cback_mgr {
public:
inline rdf_cback_mgr():
m_spo_cback_mgr('s'),
m_pos_cback_mgr('p'),
m_osp_cback_mgr('o') {};
inline void register_call_back(all_subjects, all_predicates, all_objects, index_triple_cback_ptr_type const& callback)
{
m_spo_cback_mgr.register_call_back(callback);
};
inline void register_call_back(index_type s, index_type p, all_objects, index_triple_cback_ptr_type const& callback)
{
m_spo_cback_mgr.register_call_back(s, p, callback);
};
inline void register_call_back(index_type s, all_predicates , all_objects, index_triple_cback_ptr_type const& callback)
{
m_spo_cback_mgr.register_call_back(s, callback);
};
inline void register_call_back(all_subjects, index_type p, index_type o, index_triple_cback_ptr_type const& callback)
{
m_pos_cback_mgr.register_call_back(p, o, callback);
};
inline void register_call_back(all_subjects, index_type p, all_objects, index_triple_cback_ptr_type const& callback)
{
m_pos_cback_mgr.register_call_back(p, callback);
};
inline void register_call_back(index_type s, all_predicates, index_type o, index_triple_cback_ptr_type const& callback)
{
m_osp_cback_mgr.register_call_back(o, s, callback);
};
inline void register_call_back(all_subjects , all_predicates, index_type o, index_triple_cback_ptr_type const& callback)
{
m_osp_cback_mgr.register_call_back(o, callback);
};
inline index_triple_cback_mgr const& get_spo_cback_mgr()const{return m_spo_cback_mgr;};
inline index_triple_cback_mgr const& get_pos_cback_mgr()const{return m_pos_cback_mgr;};
inline index_triple_cback_mgr const& get_osp_cback_mgr()const{return m_osp_cback_mgr;};
private:
friend std::ostream& operator<<(std::ostream& out, rdf_cback_mgr const& mgr);
index_triple_cback_mgr m_spo_cback_mgr;
index_triple_cback_mgr m_pos_cback_mgr;
index_triple_cback_mgr m_osp_cback_mgr;
};
inline std::ostream& operator<<(std::ostream& out, rdf_cback_mgr const& mgr)
{
out << "rdf_cback_mgr at " << &mgr << ", which have " <<
(mgr.m_spo_cback_mgr.size() + mgr.m_pos_cback_mgr.size() + mgr.m_osp_cback_mgr.size()) <<
" callback functions registered";
return out;
};
}; /*rdf namespace */
#endif /*RDF_RULE_CBACK_H_*/