尝试分离hierarchy的中间版本

This commit is contained in:
zhengchao
2020-06-01 10:59:29 +08:00
parent a69ab5c609
commit 8a89dcfdae
3 changed files with 488 additions and 53 deletions

View File

@@ -0,0 +1,401 @@
struct Maat_group_internal
{
int group_id;
int ref_by_compile_cnt;
};
struct Maat_CNF_literal
{
int group_id;
int virtual_table_id;
};
struct Maat_CNF_clause
{
int compile_id;
int Nth_clause;
char not_flag;
TAILQ_ENTRY(Maat_CNF_clause) entries;
};
TAILQ_HEAD(Maat_clause_id_q, Maat_CNF_clause);
struct Maat_clause_list
{
size_t clause_id_count;
Maat_clause_id_q clause_id_q;
};
struct _CNF_clause
{
char not_flag;
char in_use;
//Following varibles are used when no Nth clause is given, another word, this is forward compatible.
int vt_id;
int group_id;
};
struct Maat_CNF
{
int compile_id;
int clause_cnt;
struct _CNF_clause clauses[MAX_ITEMS_PER_BOOL_EXPR];
};
enum MAAT_HIERARCHY_LEVEL
{
HIERARCHY_LVL_GROUP,
HIERARCHY_LVL_LITERAL,
HIERARCHY_LVL_CLAUSE
};
struct Maat_hierarchy_element
{
int vertex_id;
enum MAAT_HIERARCHY_LEVEL level;
union
{
struct Maat_group_internal group;
struct Maat_CNF_literal literal;
struct Maat_CNF_clause clause;
};
int ref_by_superior_cnt;
int ref_by_subordinate_cnt;
};
struct Maat_hierarchy
{
igraph_t hierarchy_graph;
igraph_t cnf_graph;//?
igraph_integer_t vcount;
igraph_vector_t dfs_vids;
int vertex_id_generator;
int global_clause_id_generator;
MESA_htable_handle vertex_id2ele;//key:vertex_id, value: struct Maat_hierarchy_element*
MESA_htable_handle grp_and_vt2clause_id_hash; //key: virtual_table<<32|group_id, value: struct Maat_clause_list*
struct bool_matcher * bool_matcher_expr_compiler;
MESA_htable_handle cnf_hash; //key: compile_id, value: struct Maat_CNF *
MESA_htable_handle clause_hash; //key: compile_id+Nth_clause, value: global_clause_id
MESA_htable_handle literal_hash;
MESA_htable_handle group_hash; //
};
struct Maat_hierarchy* Maat_hierarchy_new()
{
struct Maat_hierarchy* hier=ALLOC(struct Maat_hierarchy, 1);
int ret=0;
MESA_htable_create_args_t hargs;
memset(&hargs,0,sizeof(hargs));
hargs.thread_safe=0;
hargs.hash_slot_size = 1024*1024;
hargs.max_elem_num = 0;
hargs.eliminate_type = HASH_ELIMINATE_ALGO_FIFO;
hargs.expire_time = 0;
hargs.key_comp = NULL;
hargs.key2index = NULL;
hargs.recursive = 0;
// hargs.data_free = _void_destroy_compile_rule;
hargs.data_free = free;
hargs.data_expire_with_condition = NULL;
hargs.thread_safe=0;
hargs.data_free = free;
hier->cnf_hash=MESA_htable_create(&hargs, sizeof(hargs));
MESA_htable_print_crtl(hier->cnf_hash, 0);
hargs.thread_safe=0;
hargs.data_free = free;
hier->clause_hash=MESA_htable_create(&hargs, sizeof(hargs));
MESA_htable_print_crtl(hier->clause_hash, 0);
hargs.thread_safe=0;
hargs.data_free = free;
hier->literal_hash=MESA_htable_create(&hargs, sizeof(hargs));
MESA_htable_print_crtl(hier->literal_hash, 0);
hargs.thread_safe=0;
hargs.data_free = free;
hier->group_hash=MESA_htable_create(&hargs, sizeof(hargs));
MESA_htable_print_crtl(hier->group_hash,0);
hargs.thread_safe=0;
hargs.data_free = EMPTY_FREE; //data stored in cnf_hash, group_hash, clause_hash
hier->vertex_id2ele=MESA_htable_create(&hargs, sizeof(hargs));
MESA_htable_print_crtl(hier->vertex_id2ele, 0);
ret=igraph_empty(&hier->hierarchy_graph, 0, IGRAPH_DIRECTED);
assert(ret==IGRAPH_SUCCESS);
return hier;
}
void Maat_hierarchy_free(struct Maat_hierarchy* hier)
{
MESA_htable_destroy(hier->cnf_hash, NULL);
MESA_htable_destroy(hier->clause_hash, NULL);
MESA_htable_destroy(hier->literal_hash, NULL);
MESA_htable_destroy(hier->group_hash, NULL);
MESA_htable_destroy(hier->vertex_id2ele, NULL);
igraph_destroy(&hier->hierarchy_graph);
free(hier);
}
struct Maat_hierarchy_element* Maat_hierarchy_element_new(struct Maat_hierarchy* hier, enum MAAT_HIERARCHY_LEVEL lvl)
{
int ret=0;
struct Maat_hierarchy_element* ele=NULL;
ele=ALLOC(struct Maat_hierarchy_element, 1);
ele->level=lvl;
ele->vertex_id=hier->vertex_id_generator++;
assert(igraph_vcount(&hier->hierarchy_graph)==ele->vertex_id);
igraph_add_vertices(&hier->hierarchy_graph, 1, NULL); //Add 1 vertice.
ret=HASH_add_by_id(hier->vertex_id2ele, ele->vertex_id, ele);
assert(ret>0);
return ele;
}
void Maat_hierarchy_element_free(struct Maat_hierarchy_element* ele)
{
}
#define TO_CLAUSE_ID(Nth_clause, compile_id) ((long long)Nth_clause<<32|compile_id)
static long long get_Nth_clause(struct Maat_CNF* cnf, int group_id, int vt_id, int not_flag)
{
int i=0, Nth_clause=0;
if(Nth_clause==0)//compatible
{
for(i=0; i<MAX_ITEMS_PER_BOOL_EXPR; i++)
{
if(cnf->clauses.group_id==group_id &&
cnf->clauses.vt_id==vt_id &&
cnf->clauses.not_flag==not_flag)
{
Nth_clause=i+1;
break;
}
}
if(Nth_clause<1)
{
Nth_clause=cnf->clause_cnt;
cnf->clauses[Nth_clause].group_id=group_id;
cnf->clauses[Nth_clause].vt_id=vt_id;
cnf->clause_cnt++;
}
assert(cnf->clause_cnt<MAX_ITEMS_PER_BOOL_EXPR);
}
return Nth_clause;
}
#define TO_LITERAL_ID(vt_id, group_id) ((long long)vt_id<<32|group_id)
int Maat_hierarchy_add_compile(struct Maat_hierarchy* hier, int compile_id, int clause_num){}
int Maat_hierarchy_add_group_to_compile(struct Maat_hierarchy* hier, int group_id, int vt_id, int not_flag, int Nth_clause, int compile_id)
{
int ret=0;
igraph_integer_t edge_id;
struct Maat_hierarchy_element* ele_group=NULL, *ele_literal=NULL, *ele_clause=NULL;
struct Maat_CNF* cnf=NULL;
cnf=(struct Maat_CNF*)HASH_fetch_by_id(hier->cnf_hash, compile_id);
if(!cnf)
{
cnf=ALLOC(struct Maat_CNF, 1);
cnf->compile_id=compile_id;
}
if(Nth_clause==0)//for compatible
{
Nth_clause=get_Nth_clause(cnf, group_id, vt_id, not_flag);
}
cnf->clauses[Nth_clause-1].in_use=1;
cnf->clauses[Nth_clause-1].not_flag=not_flag;
ele_group=(struct Maat_hierarchy_element*)HASH_fetch_by_id(hier->group_hash, group_id);
if(!ele_group)
{
ele_group=Maat_hierarchy_element_new(hier, HIERARCHY_LVL_GROUP);
ele_group->group.group_id=group_id;
ret=HASH_add_by_id(hier->group_hash, group_id, ele_group);
assert(ret>0);
}
ele_literal=(struct Maat_hierarchy_element*)MESA_htable_search(hier->literal_hash, TO_LITERAL_ID(vt_id, group_id), sizeof(long long));
if(!ele_literal)
{
ele_literal=Maat_hierarchy_element_new(hier, HIERARCHY_LVL_LITERAL);
ele_literal->literal.group_id=group_id;
ele_literal->literal.virtual_table_id=vt_id;
MESA_htable_add(hier->literal_hash, TO_LITERAL_ID(vt_id, group_id), sizeof(long long), ele_literal);
ret=igraph_get_eid(&hier->hierarchy_graph, &edge_id, ele_group->vertex_id, ele_literal->vertex_id, IGRAPH_DIRECTED, /*error*/ 0);
assert(edge_id==0);//For new literal, the edge should not exisited.
igraph_add_edge(&hier->hierarchy_graph, ele_group->vertex_id, ele_literal->vertex_id);
ele_group->group.ref_by_compile_cnt++;
ele_group->ref_by_superior_cnt++;
ele_literal->ref_by_subordinate_cnt++;
}
else
{
ret=igraph_get_eid(&hier->hierarchy_graph, &edge_id, ele_group->vertex_id, ele_literal->vertex_id, IGRAPH_DIRECTED, /*error*/ 0);
assert(edge_id>0);//For existed literal, the edge should exisited.
}
ele_clause=(struct Maat_hierarchy_element*)MESA_htable_search(hier->clause_hash, TO_CLAUSE_ID(Nth_clause, compile_id), sizeof(long long));
if(!ele_clause)
{
ele_clause=Maat_hierarchy_element_new(hier, HIERARCHY_LVL_CLAUSE);
ele_clause->clause.compile_id=compile_id;
ele_clause->clause.Nth_clause=Nth_clause;
ele_clause->clause.not_flag=not_flag;
MESA_htable_add(hier->clause_hash, TO_CLAUSE_ID(Nth_clause, compile_id), sizeof(long long), ele_clause);
}
if(ele_clause->clause.not_flag!=not_flag)
{
return -1;
}
ret=igraph_get_eid(&hier->hierarchy_graph, &edge_id, ele_literal->vertex_id, ele_clause->vertex_id, IGRAPH_DIRECTED, /*error*/ 0);
if(edge_id>0)//The edge was found. Only one edge between a literal and a clause.
{
return -1;
}
//igraph allow add multiple edges between two vetex, igraph_delete_edges removes one edge per call.
igraph_add_edge(&hier->hierarchy_graph, ele_literal->vertex_id, ele_clause->vertex_id);
ele_literal->ref_by_superior_cnt++;
ele_clause->ref_by_subordinate_cnt++;
return 0;
}
int Maat_hierarchy_add_group_to_group(struct Maat_hierarchy* hier, int group_id, int superior_group_id)
{
int ret=0;
igraph_integer_t edge_id;
struct Maat_hierarchy_element* ele_group=NULL, *ele_superior_group=NULL;
ele_group=(struct Maat_hierarchy_element*)HASH_fetch_by_id(hier->group_hash, group_id);
if(!ele_group)
{
ele_group=Maat_hierarchy_element_new(hier, HIERARCHY_LVL_GROUP);
ele_group->group.group_id=group_id;
ret=HASH_add_by_id(hier->group_hash, group_id, ele_group);
assert(ret>0);
}
ele_superior_group=(struct Maat_hierarchy_element*)HASH_fetch_by_id(hier->group_hash, superior_group_id);
if(!ele_superior_group)
{
ele_superior_group=Maat_hierarchy_element_new(hier, HIERARCHY_LVL_GROUP);
ele_superior_group->group.group_id=superior_group_id;
ret=HASH_add_by_id(hier->group_hash, superior_group_id, ele_superior_group);
assert(ret>0);
}
ret=igraph_get_eid(&hier->hierarchy_graph, &edge_id, ele_group->vertex_id, ele_superior_group->vertex_id, IGRAPH_DIRECTED, /*error*/ 0);
if(edge_id>0)//The edge was found. Only one edge between two groups.
{
return -1;
}
igraph_add_edge(&hier->hierarchy_graph, ele_group->vertex_id, ele_superior_group->vertex_id);
ele_group->ref_by_superior_cnt++;
ele_superior_group->ref_by_subordinate_cnt++;
return 0;
}
int Maat_hierarchy_add_region(struct Maat_hierarchy* hier, int region_id, int group_id)
{
}
static int hierarchy_graph_reomve_edge(igrahp_t* graph, int from_vertex_id, int to_vertex_id)
{
igraph_es_t es;
int ret=0;
igraph_integer_t edge_num_before=0, edge_num_after=0;
edge_num_before=igraph_ecount(graph);
// The edges between the given pairs of vertices will be included in the edge selection.
//The vertex pairs must be given as the arguments of the function call, the third argument
//is the first vertex of the first edge, the fourth argument is the second vertex of the
//first edge, the fifth is the first vertex of the second edge and so on. The last element
//of the argument list must be -1 to denote the end of the argument list.
//https://igraph.org/c/doc/igraph-Iterators.html#igraph_es_pairs_small
ret=igraph_es_pairs_small(&es, IGRAPH_DIRECTED, from_vertex_id, to_vertex_id, -1);
assert(ret==IGRAPH_SUCCESS);
// ignore no such edge to abort().
igraph_set_error_handler(igraph_error_handler_ignore);
ret=igraph_delete_edges(graph, es);
edge_num_after=igraph_ecount(graph);
igraph_es_destroy(&es);
if(ret!=IGRAPH_SUCCESS||edge_num_before-edge_num_after!=1)
{
return -1;
}
else
{
return 0;
}
}
int Maat_hierarchy_remove_group_from_compile(struct Maat_hierarchy* hier, int group_id, int vt_id, int not_flag, int Nth_clause, int compile_id)
{
int ret=0;
struct Maat_CNF* cnf=NULL;
cnf=(struct Maat_CNF*)HASH_fetch_by_id(hier->cnf_hash, compile_id);
if(!cnf)
{
return -2;
}
if(Nth_clause==0)
{
Nth_clause=get_Nth_clause(cnf, group_id, vt_id, not_flag);
cnf->clauses[Nth_clause-1].
}
struct Maat_hierarchy_element* ele_group=NULL, *ele_literal=NULL, *ele_clause=NULL;
ele_group=(struct Maat_hierarchy_element*)HASH_fetch_by_id(hier->group_hash, group_id);
ele_literal=(struct Maat_hierarchy_element*)MESA_htable_search(hier->literal_hash, TO_LITERAL_ID(vt_id, group_id), sizeof(long long));
ele_clause=(struct Maat_hierarchy_element*)MESA_htable_search(hier->clause_hash, TO_CLAUSE_ID(Nth_clause, compile_id), sizeof(long long));
if(!ele_group||!ele_literal||!ele_clause)
{
return -1;
}
ret=hierarchy_graph_reomve_edge(&hier->hierarchy_graph, ele_group->vertex_id, ele_literal->vertex_id);
if(ret<0)
{
return -1;
}
ele_group->group->ref_by_compile_cnt--;
ele_group->ref_by_subordinate_cnt--;
ele_literal->ref_by_superior_cnt--;
ret=hierarchy_graph_reomve_edge(&hier->hierarchy_graph, ele_literal->vertex_id, ele_clause->vertex_id);
if(ret<0)
{
return -1;
}
ele_literal->ref_by_superior_cnt--;
ele_clause->ref_by_subordinate_cnt--;
return 0;
}
int Maat_hierarchy_remove_group_from_group(struct Maat_hierarchy* hier, int group_id, int superior_group_id)
{
int ret=0;
struct Maat_hierarchy_element* ele_group=NULL, *ele_superior_group=NULL;
ele_group=(struct Maat_hierarchy_element*)HASH_fetch_by_id(hier->group_hash, group_id);
ele_superior_group=(struct Maat_hierarchy_element*)HASH_fetch_by_id(hier->group_hash, superior_group_id);
if(!ele_group||!ele_superior_group)
{
return -1;
}
ret=hierarchy_graph_reomve_edge(&hier->hierarchy_graph, ele_group->vertex_id, ele_superior_group->vertex_id);
if(ret<0)
{
return -1;
}
ele_group->ref_by_superior_cnt--;
ele_superior_group->ref_by_subordinate_cnt--;
return 0;
}
int Maat_hierarchy_rebuild(struct Maat_hierarchy* hier)
{
}

View File

@@ -548,8 +548,8 @@ struct Maat_group_inner* create_group_rule(int group_id, int table_id, struct Ma
group->table_id=table_id; group->table_id=table_id;
group->group_name=NULL; group->group_name=NULL;
group->vertex_id=scanner->grp_vertex_id_generator++; group->vertex_id=scanner->grp_vertex_id_generator++;
assert(igraph_vcount(&scanner->group_graph)==group->vertex_id); assert(igraph_vcount(&scanner->hierarchy_graph)==group->vertex_id);
igraph_add_vertices(&scanner->group_graph, 1, NULL); //Add 1 vertice. igraph_add_vertices(&scanner->hierarchy_graph, 1, NULL); //Add 1 vertice.
ret=HASH_add_by_id(scanner->vertex_id2group, group->vertex_id, group); ret=HASH_add_by_id(scanner->vertex_id2group, group->vertex_id, group);
assert(ret>0); assert(ret>0);
ret=HASH_add_by_id(scanner->group_hash, group_id, group); ret=HASH_add_by_id(scanner->group_hash, group_id, group);
@@ -609,7 +609,7 @@ void destroy_group_rule(struct Maat_group_inner* group_rule, int by_whom, struct
HASH_delete_by_id(scanner->group_hash, group_rule->group_id); HASH_delete_by_id(scanner->group_hash, group_rule->group_id);
HASH_delete_by_id(scanner->vertex_id2group, group_rule->vertex_id); HASH_delete_by_id(scanner->vertex_id2group, group_rule->vertex_id);
igraph_vector_init(&v, 8); igraph_vector_init(&v, 8);
igraph_neighbors(&scanner->group_graph, &v, group_rule->vertex_id, IGRAPH_ALL); igraph_neighbors(&scanner->hierarchy_graph, &v, group_rule->vertex_id, IGRAPH_ALL);
if(igraph_vector_size(&v)>0) if(igraph_vector_size(&v)>0)
{ {
print_igraph_vector(&v, buff, sizeof(buff)); print_igraph_vector(&v, buff, sizeof(buff));
@@ -666,8 +666,8 @@ void walk_compile_hash(const uchar * key, uint size, void * data, void * user)
return; return;
} }
//make sure compile rule's each group has loadded. //make sure compile rule's each group has loadded.
if((compile_inner->group_cnt==compile_inner->compile->declared_grp_num if((compile_inner->group_cnt==compile_inner->compile->declared_clause_num
|| compile_inner->compile->declared_grp_num==0)//for compatible old version || compile_inner->compile->declared_clause_num==0)//for compatible old version
&& compile_inner->group_cnt>0 && compile_inner->group_cnt>0
&& compile_inner->group_cnt!=compile_inner->not_group_cnt) && compile_inner->group_cnt!=compile_inner->not_group_cnt)
{ {
@@ -751,7 +751,7 @@ struct Maat_compile_rule* create_compile_rule(struct Maat_rule_head* p_head, con
int i=0; int i=0;
struct Maat_compile_rule*p=ALLOC(struct Maat_compile_rule, 1); struct Maat_compile_rule*p=ALLOC(struct Maat_compile_rule, 1);
p->head=*p_head; p->head=*p_head;
p->declared_grp_num=declared_grp_num; p->declared_clause_num=declared_grp_num;
p->ads=ALLOC(MAAT_RULE_EX_DATA, MAX_COMPILE_EX_DATA_NUM); p->ads=ALLOC(MAAT_RULE_EX_DATA, MAX_COMPILE_EX_DATA_NUM);
//protect by feather->background_update_mutex //protect by feather->background_update_mutex
@@ -782,13 +782,13 @@ void destroy_compile_rule(struct Maat_compile_rule* compile_rule)
free(compile_rule->ads); free(compile_rule->ads);
compile_rule->is_valid=0; compile_rule->is_valid=0;
compile_rule->declared_grp_num=-1; compile_rule->declared_clause_num=-1;
free(compile_rule->service_defined); free(compile_rule->service_defined);
compile_rule->service_defined=NULL; compile_rule->service_defined=NULL;
free(compile_rule); free(compile_rule);
return; return;
} }
struct Maat_compile_inner * create_compile_group_relation(int compile_id, struct Maat_scanner *scanner) struct Maat_compile_inner * create_compile_inner(int compile_id, struct Maat_scanner *scanner)
{ {
int ret=0; int ret=0;
struct Maat_compile_inner* p=ALLOC(struct Maat_compile_inner, 1); struct Maat_compile_inner* p=ALLOC(struct Maat_compile_inner, 1);
@@ -1001,7 +1001,7 @@ struct Maat_scanner* create_maat_scanner(unsigned int version,_Maat_feather_t *f
scanner->region_hash=MESA_htable_create(&hargs, sizeof(hargs)); scanner->region_hash=MESA_htable_create(&hargs, sizeof(hargs));
MESA_htable_print_crtl(scanner->region_hash,0); MESA_htable_print_crtl(scanner->region_hash,0);
ret=igraph_empty(&scanner->group_graph, 0, IGRAPH_DIRECTED); ret=igraph_empty(&scanner->hierarchy_graph, 0, IGRAPH_DIRECTED);
assert(ret==IGRAPH_SUCCESS); assert(ret==IGRAPH_SUCCESS);
scanner->district_map=map_create(); scanner->district_map=map_create();
@@ -1087,7 +1087,7 @@ void destroy_maat_scanner(struct Maat_scanner*scanner)
Maat_table_rt_manager_destroy(scanner->table_rt_mgr); Maat_table_rt_manager_destroy(scanner->table_rt_mgr);
scanner->table_rt_mgr=NULL; scanner->table_rt_mgr=NULL;
igraph_destroy(&scanner->group_graph); igraph_destroy(&scanner->hierarchy_graph);
free(scanner); free(scanner);
return; return;
} }
@@ -1417,21 +1417,56 @@ unsigned int del_region_from_group(struct Maat_group_inner* group,int region_id,
return i; return i;
} }
int add_group_to_compile(struct Maat_compile_inner* compile_inner, struct Maat_group_inner* a_rule_group, int virual_table_id, int not_flag) int add_group_to_compile(struct Maat_compile_inner* compile_inner, struct Maat_group_inner* a_rule_group, int virual_table_id, int not_flag, int local_clause_id)
{ {
int i=0,ret=-1; int i=0,ret=-1;
int write_pos=-1; int write_pos=-1;
struct Maat_group_inner* p=NULL; struct Maat_group_inner* p=NULL;
struct Maat_CNF_clause* clause=NULL;
struct Maat_CNF_character* character=NULL;
pthread_rwlock_wrlock(&(compile_inner->rwlock)); pthread_rwlock_wrlock(&(compile_inner->rwlock));
if(compile_inner->compile!=NULL if(compile_inner->compile!=NULL
&& compile_inner->group_cnt>=compile_inner->compile->declared_grp_num && local_clause_id>MAX_ITEMS_PER_BOOL_EXPR
&& compile_inner->compile->declared_grp_num!=0) && compile_inner->clause_cnt>=compile_inner->compile->declared_clause_num
&& compile_inner->compile->declared_clause_num!=0)
{ {
ret=-1; ret=-1;
goto error_out; goto error_out;
} }
size_t i=0;
if(local_clause_id==0)
{
local_clause_id=compile_inner->clause_cnt;
compile_inner->clause_cnt++
}
clause=&(compile_inner->clause[local_clause_id-1]);
if(clause->inuse_flag==0)
{
clause->inuse_flag=1;
clause->not_flag=not_flag;
TAILQ_INIT(&clause->char_q);
}
else
{
assert(clause->not_flag==not_flag);
}
character=ALLOC(struct Maat_CNF_character, 1);
character->group_id=a_rule_group->group_id;
character->ref_group=a_rule_group;
character->virtual_table_id=virual_table_id;
TAILQ_INSERT_TAIL(&clause->char_q, character, entries);
clause->char_num++;
else
{
TAILQ_FOREACH(clause, &compile_inner->clause_q, entries)
{
if(clause->local_clause_id==local_clause_id)
{
TAILQ_FOREACH(clause, &compile_inner->clause_q, entries)
}
}
}
for(i=0;i<compile_inner->group_boundary;i++) for(i=0;i<compile_inner->group_boundary;i++)
{ {
p=(struct Maat_group_inner*)dynamic_array_read(compile_inner->groups,i); p=(struct Maat_group_inner*)dynamic_array_read(compile_inner->groups,i);
@@ -1976,14 +2011,14 @@ int del_region_rule(struct Maat_table_schema* table,int region_id,int group_id,i
} }
int add_group_rule(struct Maat_table_schema* table, struct db_group_rule_t* db_group_rule, struct Maat_scanner *scanner, void* logger) int add_group_rule(struct Maat_table_schema* table, struct db_group_rule_t* db_group_rule, struct Maat_scanner *scanner, void* logger)
{ {
struct Maat_group_inner* group_rule=NULL, *parent_group=NULL; struct Maat_group_inner* group_inner=NULL, *parent_group=NULL;
struct Maat_compile_inner*compile_rule=NULL; struct Maat_compile_inner*compile_inner=NULL;
int ret=0; int ret=0, global_clause_id=0;
igraph_integer_t edge_id; igraph_integer_t edge_id;
group_rule=(struct Maat_group_inner*)HASH_fetch_by_id(scanner->group_hash, db_group_rule->group_id); group_inner=(struct Maat_group_inner*)HASH_fetch_by_id(scanner->group_hash, db_group_rule->group_id);
if(group_rule==NULL) if(group_inner==NULL)
{ {
group_rule=create_group_rule(db_group_rule->group_id, table->table_id, scanner); group_inner=create_group_rule(db_group_rule->group_id, table->table_id, scanner);
} }
if(db_group_rule->parent_type==PARENT_TYPE_GROUP) if(db_group_rule->parent_type==PARENT_TYPE_GROUP)
@@ -1993,10 +2028,11 @@ int add_group_rule(struct Maat_table_schema* table, struct db_group_rule_t* db_g
{ {
parent_group=create_group_rule(db_group_rule->parent_id, table->table_id, scanner); parent_group=create_group_rule(db_group_rule->parent_id, table->table_id, scanner);
} }
group_rule->ref_by_parent_cnt++; group_inner->ref_by_parent_cnt++;
parent_group->ref_by_children_cnt++; parent_group->ref_by_children_cnt++;
ret=igraph_get_eid(&scanner->group_graph, &edge_id, group_rule->vertex_id, parent_group->vertex_id, IGRAPH_DIRECTED, /*error*/ 0); //if the edge was not found and error is false, then -1 will be assigned to eid.
if(edge_id>0)//if the edge was not found and error is false, then -1 will be assigned to eid. ret=igraph_get_eid(&scanner->hierarchy_graph, &edge_id, group_inner->vertex_id, parent_group->vertex_id, IGRAPH_DIRECTED, /*error*/ 0);
if(edge_id>0)//The edge was found.
{ {
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module, MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module,
"update error, add sub group: %s %d to group %d error, sub group exist.", "update error, add sub group: %s %d to group %d error, sub group exist.",
@@ -2006,17 +2042,17 @@ int add_group_rule(struct Maat_table_schema* table, struct db_group_rule_t* db_g
return -1; return -1;
} }
//igraph allow add multiple edges between two vetex, igraph_delete_edges removes one edge per call. //igraph allow add multiple edges between two vetex, igraph_delete_edges removes one edge per call.
igraph_add_edge(&scanner->group_graph, group_rule->vertex_id, parent_group->vertex_id); igraph_add_edge(&scanner->hierarchy_graph, group_inner->vertex_id, parent_group->vertex_id);
} }
else else
{ {
compile_rule=(struct Maat_compile_inner*)HASH_fetch_by_id(scanner->compile_hash, db_group_rule->parent_id); compile_inner=(struct Maat_compile_inner*)HASH_fetch_by_id(scanner->compile_hash, db_group_rule->parent_id);
if(compile_rule==NULL) if(compile_inner==NULL)
{ {
compile_rule=create_compile_group_relation(db_group_rule->parent_id, scanner); compile_inner=create_compile_inner(db_group_rule->parent_id, scanner);
} }
ret=add_group_to_compile(compile_rule, group_rule, db_group_rule->virtual_table_id, db_group_rule->not_flag); global_clause_id=add_group_to_compile(compile_inner, group_inner, db_group_rule->virtual_table_id, db_group_rule->not_flag, db_group_rule->clause_id);
if(ret<0) if(global_clause_id<0)
{ {
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module, MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module,
"update error, add group: %s %d to compile rule %d error, compile rule is full or duplicate group.", "update error, add group: %s %d to compile rule %d error, compile rule is full or duplicate group.",
@@ -2025,6 +2061,8 @@ int add_group_rule(struct Maat_table_schema* table, struct db_group_rule_t* db_g
db_group_rule->parent_id); db_group_rule->parent_id);
return -1; return -1;
} }
//add character edge to hierarchy graph
//add clause edge to hierarchy graph
} }
scanner->to_update_group_cnt++; scanner->to_update_group_cnt++;
return 1; return 1;
@@ -2060,7 +2098,7 @@ int del_group_rule(struct Maat_table_schema* table, struct db_group_rule_t* db_g
db_group_rule->parent_id); db_group_rule->parent_id);
return 0; return 0;
} }
edge_num_before=igraph_ecount(&scanner->group_graph); edge_num_before=igraph_ecount(&scanner->hierarchy_graph);
// The edges between the given pairs of vertices will be included in the edge selection. // The edges between the given pairs of vertices will be included in the edge selection.
//The vertex pairs must be given as the arguments of the function call, the third argument //The vertex pairs must be given as the arguments of the function call, the third argument
//is the first vertex of the first edge, the fourth argument is the second vertex of the //is the first vertex of the first edge, the fourth argument is the second vertex of the
@@ -2071,8 +2109,8 @@ int del_group_rule(struct Maat_table_schema* table, struct db_group_rule_t* db_g
assert(ret==IGRAPH_SUCCESS); assert(ret==IGRAPH_SUCCESS);
// ignore no such edge to abort(). // ignore no such edge to abort().
igraph_set_error_handler(igraph_error_handler_ignore); igraph_set_error_handler(igraph_error_handler_ignore);
ret=igraph_delete_edges(&scanner->group_graph, es); ret=igraph_delete_edges(&scanner->hierarchy_graph, es);
edge_num_after=igraph_ecount(&scanner->group_graph); edge_num_after=igraph_ecount(&scanner->hierarchy_graph);
if(ret!=IGRAPH_SUCCESS||edge_num_before-edge_num_after!=1) if(ret!=IGRAPH_SUCCESS||edge_num_before-edge_num_after!=1)
{ {
@@ -2125,7 +2163,7 @@ int add_compile_rule(struct Maat_table_schema* table, struct Maat_compile_rule*
cg_relation=(struct Maat_compile_inner*)HASH_fetch_by_id(scanner->compile_hash, p_maat_rule_head->config_id); cg_relation=(struct Maat_compile_inner*)HASH_fetch_by_id(scanner->compile_hash, p_maat_rule_head->config_id);
if(cg_relation==NULL) if(cg_relation==NULL)
{ {
cg_relation=create_compile_group_relation(p_maat_rule_head->config_id, scanner); cg_relation=create_compile_inner(p_maat_rule_head->config_id, scanner);
} }
else else
{ {
@@ -3110,7 +3148,7 @@ void walk_group_hash(const uchar * key, uint size, void * data, void * user)
else else
{ {
igraph_vector_t *vids=&(scanner->dfs_vids); igraph_vector_t *vids=&(scanner->dfs_vids);
igraph_dfs(&(scanner->group_graph), group_rule->vertex_id, IGRAPH_OUT, igraph_dfs(&(scanner->hierarchy_graph), group_rule->vertex_id, IGRAPH_OUT,
0, vids, NULL, NULL, NULL, NULL, NULL, NULL); 0, vids, NULL, NULL, NULL, NULL, NULL, NULL);
temp_group_ids=ALLOC(long long, effective_vertices_count(vids)); temp_group_ids=ALLOC(long long, effective_vertices_count(vids));
@@ -3148,7 +3186,7 @@ void walk_group_hash(const uchar * key, uint size, void * data, void * user)
void find_group_paths(struct Maat_scanner* scanner) void find_group_paths(struct Maat_scanner* scanner)
{ {
scanner->group_graph_vcount=igraph_vcount(&scanner->group_graph); scanner->group_graph_vcount=igraph_vcount(&scanner->hierarchy_graph);
igraph_vector_init(&(scanner->dfs_vids), scanner->group_graph_vcount); igraph_vector_init(&(scanner->dfs_vids), scanner->group_graph_vcount);
MESA_htable_iterate(scanner->group_hash, walk_group_hash, scanner); MESA_htable_iterate(scanner->group_hash, walk_group_hash, scanner);
igraph_vector_destroy(&scanner->dfs_vids); igraph_vector_destroy(&scanner->dfs_vids);
@@ -3162,7 +3200,7 @@ void do_scanner_update(struct Maat_scanner* scanner, MESA_lqueue_head garbage_q,
struct ip_matcher* old_ip_matcher=NULL; struct ip_matcher* old_ip_matcher=NULL;
int i=0, ret=0; int i=0, ret=0;
igraph_bool_t is_dag; igraph_bool_t is_dag;
igraph_is_dag(&(scanner->group_graph), &is_dag); igraph_is_dag(&(scanner->hierarchy_graph), &is_dag);
if(!is_dag) if(!is_dag)
{ {
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module, MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module,

View File

@@ -94,7 +94,7 @@ struct Maat_compile_rule
struct Maat_rule_head head;// fix len of Maat_rule_t struct Maat_rule_head head;// fix len of Maat_rule_t
char* service_defined; char* service_defined;
int is_valid; int is_valid;
int declared_grp_num; int declared_clause_num;
double evaluation_order; double evaluation_order;
const struct Maat_table_schema* ref_table; const struct Maat_table_schema* ref_table;
MAAT_RULE_EX_DATA* ads; MAAT_RULE_EX_DATA* ads;
@@ -137,6 +137,8 @@ struct Maat_region_inner
int expr_id_ub; int expr_id_ub;
enum MAAT_TABLE_TYPE table_type; enum MAAT_TABLE_TYPE table_type;
}; };
struct Maat_group_inner struct Maat_group_inner
{ {
int group_id; int group_id;
@@ -153,23 +155,16 @@ struct Maat_group_inner
dynamic_array_t *regions; dynamic_array_t *regions;
pthread_mutex_t mutex; pthread_mutex_t mutex;
}; };
#define COMPILE_INNER_MAGIC 0x1a2b3c4d
struct Maat_group_reference
{
struct Maat_group_inner* ref_group;
char not_flag;
int virtual_table_id;
int local_clause_id;
int global_clause_id;
TAILQ_ENTRY(Maat_group_reference) entries;
};
TAILQ_HEAD(ref_group_q, Maat_group_reference);
#define COMPILE_INNER_MAGIC 0x1a2b3c4d
struct Maat_compile_inner struct Maat_compile_inner
{ {
long long magic_num; long long magic_num; //shoulde be COMPILE_INNER_MAGIC
struct Maat_compile_rule *compile; struct Maat_compile_rule *compile;
struct ref_group_q ref_group_qhead;
dynamic_array_t *groups; //element is struct Maat_group_inner* dynamic_array_t *groups; //element is struct Maat_group_inner*
int virtual_table_id[MAX_ITEMS_PER_BOOL_EXPR]; int virtual_table_id[MAX_ITEMS_PER_BOOL_EXPR];
@@ -276,18 +271,19 @@ struct Maat_scanner
//Access in both UPDATE thread and SCAN thread //Access in both UPDATE thread and SCAN thread
MESA_htable_handle exprid_hash; //key: expr_id, value: int array_idx of Maat_group_inner->regions; MESA_htable_handle exprid_hash; //key: expr_id, value: int array_idx of Maat_group_inner->regions;
MESA_htable_handle compile_hash;//key: compile_id, value: struct Maat_compile_inner * MESA_htable_handle compile_hash;//key: compile_id, value: struct Maat_compile_inner *
MESA_htable_handle clause_hash; //key: global_clause_id, value: MESA_htable_handle grp_and_vt2clause_id_hash; //key: virtual_table<<32|group_id, value: struct Maat_clause_id_list*
//Access in UPDATE thread ONLY. //Access in UPDATE thread ONLY.
MESA_htable_handle region_hash; //key: region_id, value: struct region_group_relation* MESA_htable_handle region_hash; //key: region_id, value: struct region_group_relation*
MESA_htable_handle group_hash; //key: group_id, value: struct Maat_group_inner* MESA_htable_handle group_hash; //key: group_id, value: struct Maat_group_inner*
MESA_htable_handle district_map; MESA_htable_handle district_map;
MESA_htable_handle tmp_district_map; MESA_htable_handle tmp_district_map;
MESA_htable_handle vertex_id2group; MESA_htable_handle vertex_id2group;//key:vertex_id, value: struct Maat_hierarchy_element*
igraph_t group_graph; igraph_t hierarchy_graph;
igraph_integer_t group_graph_vcount; igraph_integer_t group_graph_vcount;
igraph_vector_t dfs_vids; igraph_vector_t dfs_vids;