new support for join/intersect operations

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@2086 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
ricroc
2008-02-11 17:00:23 +00:00
parent d39002c271
commit 1ac399f57b
8 changed files with 496 additions and 96 deletions

View File

@@ -28,8 +28,11 @@ static YAP_Term get_trie(TrNode node, YAP_Term *stack_list, TrNode *cur_node);
static void remove_trie(TrNode node);
static void free_child_nodes(TrNode node);
static TrNode copy_child_nodes(TrNode parent_dest, TrNode node_source);
static void traverse_tries_join(TrNode parent_dest, TrNode parent_source);
static void traverse_tries(TrNode parent_dest, TrNode parent_source);
static void traverse_tries_join(TrNode parent_dest, TrNode parent_source);
static void traverse_tries_intersect(TrNode parent_dest, TrNode parent_source);
static YAP_Int count_tries_intersect(TrNode parent1, TrNode parent2);
static YAP_Int count_trie(TrNode node);
static void traverse_trie_usage(TrNode node, YAP_Int depth);
static void traverse_trie_save(TrNode node, FILE *file, int float_block);
static void traverse_trie_load(TrNode parent, FILE *file);
@@ -50,8 +53,9 @@ static YAP_Functor FunctorComma;
static void (*DATA_SAVE_FUNCTION)(TrNode, FILE *);
static void (*DATA_LOAD_FUNCTION)(TrNode, YAP_Int, FILE *);
static void (*DATA_PRINT_FUNCTION)(TrNode);
static void (*DATA_ADD_FUNCTION)(TrNode, TrNode);
static void (*DATA_CONSTRUCT_FUNCTION)(TrNode, TrNode);
static void (*DATA_DESTRUCT_FUNCTION)(TrNode);
static void (*DATA_JOIN_FUNCTION)(TrNode, TrNode);
@@ -341,9 +345,19 @@ void trie_remove_subtree(TrEngine engine, TrNode node, void (*destruct_function)
inline
void trie_join(TrEngine engine, TrNode node_dest, TrNode node_source, void (*add_function)(TrNode, TrNode)) {
void trie_add(TrNode node_dest, TrNode node_source, void (*add_function)(TrNode, TrNode)) {
DATA_ADD_FUNCTION = add_function;
if (TrNode_child(node_dest) && TrNode_child(node_source))
traverse_tries(node_dest, node_source);
return;
}
inline
void trie_join(TrEngine engine, TrNode node_dest, TrNode node_source, void (*add_function)(TrNode, TrNode), void (*construct_function)(TrNode, TrNode)) {
CURRENT_TRIE_ENGINE = engine;
DATA_JOIN_FUNCTION = add_function;
DATA_ADD_FUNCTION = add_function;
DATA_CONSTRUCT_FUNCTION = construct_function;
if (TrNode_child(node_dest)) {
if (TrNode_child(node_source))
traverse_tries_join(node_dest, node_source);
@@ -354,14 +368,49 @@ void trie_join(TrEngine engine, TrNode node_dest, TrNode node_source, void (*add
inline
void trie_add(TrNode node_dest, TrNode node_source, void (*add_function)(TrNode, TrNode)) {
DATA_JOIN_FUNCTION = add_function;
if (TrNode_child(node_dest) && TrNode_child(node_source))
traverse_tries(node_dest, node_source);
void trie_intersect(TrEngine engine, TrNode node_dest, TrNode node_source, void (*add_function)(TrNode, TrNode), void (*destruct_function)(TrNode)) {
CURRENT_TRIE_ENGINE = engine;
DATA_ADD_FUNCTION = add_function;
DATA_DESTRUCT_FUNCTION = destruct_function;
if (TrNode_child(node_dest)) {
if (TrNode_child(node_source))
traverse_tries_intersect(node_dest, node_source);
else {
free_child_nodes(TrNode_child(node_dest));
TrNode_child(node_dest) = NULL;
}
}
return;
}
inline
YAP_Int trie_count_join(TrNode node1, TrNode node2) {
YAP_Int count = 0;
if (TrNode_child(node1)) {
count += count_trie(TrNode_child(node1));
if (TrNode_child(node2)) {
count += count_trie(TrNode_child(node2));
count -= count_tries_intersect(node1, node2);
}
} else if (TrNode_child(node2))
count += count_trie(TrNode_child(node2));
return count;
}
inline
YAP_Int trie_count_intersect(TrNode node1, TrNode node2) {
YAP_Int count = 0;
if (TrNode_child(node1))
if (TrNode_child(node2))
count = count_tries_intersect(node1, node2);
return count;
}
inline
void trie_save(TrNode node, FILE *file, void (*save_function)(TrNode, FILE *)) {
CURRENT_INDEX = -1;
@@ -813,7 +862,8 @@ TrNode copy_child_nodes(TrNode parent_dest, TrNode child_source) {
if (IS_LEAF_TRIE_NODE(child_source)) {
MARK_AS_LEAF_TRIE_NODE(child_dest);
INCREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
(*DATA_JOIN_FUNCTION)(child_dest, child_source);
if (DATA_CONSTRUCT_FUNCTION)
(*DATA_CONSTRUCT_FUNCTION)(child_dest, child_source);
} else
TrNode_child(child_dest) = copy_child_nodes(child_dest, TrNode_child(child_source));
return child_dest;
@@ -821,9 +871,10 @@ TrNode copy_child_nodes(TrNode parent_dest, TrNode child_source) {
static
void traverse_tries_join(TrNode parent_dest, TrNode parent_source){
void traverse_tries(TrNode parent_dest, TrNode parent_source) {
TrNode child_dest, child_source;
/* parent_source is not a leaf node */
child_source = TrNode_child(parent_source);
if (IS_HASH_NODE(child_source)) {
TrNode *first_bucket_source, *bucket_source;
@@ -834,20 +885,72 @@ void traverse_tries_join(TrNode parent_dest, TrNode parent_source){
do {
child_source = *--bucket_source;
while (child_source) {
/* parent_dest cannot be a leaf node */
/* parent_dest is not a leaf node */
child_dest = trie_node_check(parent_dest, TrNode_entry(child_source));
if (child_dest) {
if (IS_LEAF_TRIE_NODE(child_dest))
(*DATA_JOIN_FUNCTION)(child_dest, child_source);
else
/* child_dest is not a leaf node */
if (IS_LEAF_TRIE_NODE(child_dest)) {
/* child_source is a leaf node */
if (DATA_ADD_FUNCTION)
(*DATA_ADD_FUNCTION)(child_dest, child_source);
} else
/* child_dest and child_source are not leaf nodes */
traverse_tries(child_dest, child_source);
}
child_source = TrNode_next(child_source);
}
} while (bucket_source != first_bucket_source);
return;
}
while (child_source) {
/* parent_dest is not a leaf node */
child_dest = trie_node_check(parent_dest, TrNode_entry(child_source));
if (child_dest) {
if (IS_LEAF_TRIE_NODE(child_dest)) {
/* child_source is a leaf node */
if (DATA_ADD_FUNCTION)
(*DATA_ADD_FUNCTION)(child_dest, child_source);
} else
/* child_dest and child_source are not leaf nodes */
traverse_tries(child_dest, child_source);
}
child_source = TrNode_next(child_source);
}
return;
}
static
void traverse_tries_join(TrNode parent_dest, TrNode parent_source) {
TrNode child_dest, child_source;
/* parent_source is not a leaf node */
child_source = TrNode_child(parent_source);
if (IS_HASH_NODE(child_source)) {
TrNode *first_bucket_source, *bucket_source;
TrHash hash_source;
hash_source = (TrHash) child_source;
first_bucket_source = TrHash_buckets(hash_source);
bucket_source = first_bucket_source + TrHash_num_buckets(hash_source);
do {
child_source = *--bucket_source;
while (child_source) {
/* parent_dest is not a leaf node */
child_dest = trie_node_check(parent_dest, TrNode_entry(child_source));
if (child_dest) {
if (IS_LEAF_TRIE_NODE(child_dest)) {
/* child_source is a leaf node */
if (DATA_ADD_FUNCTION)
(*DATA_ADD_FUNCTION)(child_dest, child_source);
} else
/* child_dest and child_source are not leaf nodes */
traverse_tries_join(child_dest, child_source);
} else {
child_dest = trie_node_check_insert(parent_dest, TrNode_entry(child_source));
if (IS_LEAF_TRIE_NODE(child_source)) {
MARK_AS_LEAF_TRIE_NODE(child_dest);
INCREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
(*DATA_JOIN_FUNCTION)(child_dest, child_source);
if (DATA_ADD_FUNCTION)
(*DATA_ADD_FUNCTION)(child_dest, child_source);
} else
TrNode_child(child_dest) = copy_child_nodes(child_dest, TrNode_child(child_source));
}
@@ -857,20 +960,23 @@ void traverse_tries_join(TrNode parent_dest, TrNode parent_source){
return;
}
while (child_source) {
/* parent_dest cannot be a leaf node */
/* parent_dest is not a leaf node */
child_dest = trie_node_check(parent_dest, TrNode_entry(child_source));
if (child_dest) {
if (IS_LEAF_TRIE_NODE(child_dest))
(*DATA_JOIN_FUNCTION)(child_dest, child_source);
else
/* child_dest is not a leaf node */
if (IS_LEAF_TRIE_NODE(child_dest)) {
/* child_source is a leaf node */
if (DATA_ADD_FUNCTION)
(*DATA_ADD_FUNCTION)(child_dest, child_source);
} else
/* child_dest and child_source are not leaf nodes */
traverse_tries_join(child_dest, child_source);
} else {
child_dest = trie_node_check_insert(parent_dest, TrNode_entry(child_source));
if (IS_LEAF_TRIE_NODE(child_source)) {
MARK_AS_LEAF_TRIE_NODE(child_dest);
INCREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
(*DATA_JOIN_FUNCTION)(child_dest, child_source);
if (DATA_ADD_FUNCTION)
(*DATA_ADD_FUNCTION)(child_dest, child_source);
} else
TrNode_child(child_dest) = copy_child_nodes(child_dest, TrNode_child(child_source));
}
@@ -881,51 +987,149 @@ void traverse_tries_join(TrNode parent_dest, TrNode parent_source){
static
void traverse_tries(TrNode parent_dest, TrNode parent_source) {
TrNode child_dest, child_source;
void traverse_tries_intersect(TrNode parent_dest, TrNode parent_source) {
TrNode child_dest, child_source, child_next;
child_source = TrNode_child(parent_source);
if (IS_HASH_NODE(child_source)) {
TrNode *first_bucket_source, *bucket_source;
TrHash hash_source;
hash_source = (TrHash) child_source;
first_bucket_source = TrHash_buckets(hash_source);
bucket_source = first_bucket_source + TrHash_num_buckets(hash_source);
/* parent_dest is not a leaf node */
child_dest = TrNode_child(parent_dest);
if (IS_HASH_NODE(child_dest)) {
TrNode *first_bucket_dest, *bucket_dest;
TrHash hash_dest;
hash_dest = (TrHash) child_dest;
first_bucket_dest = TrHash_buckets(hash_dest);
bucket_dest = first_bucket_dest + TrHash_num_buckets(hash_dest);
do {
child_source = *--bucket_source;
while (child_source) {
/* parent_dest cannot be a leaf node */
child_dest = trie_node_check(parent_dest, TrNode_entry(child_source));
if (child_dest) {
child_dest = *--bucket_dest;
while (child_dest) {
child_next = TrNode_next(child_dest);
/* parent_source is not a leaf node */
child_source = trie_node_check(parent_source, TrNode_entry(child_dest));
if (child_source) {
if (IS_LEAF_TRIE_NODE(child_dest)) {
if (IS_LEAF_TRIE_NODE(child_source))
(*DATA_JOIN_FUNCTION)(child_dest, child_source);
/* child_source is a leaf node */
if (DATA_ADD_FUNCTION)
(*DATA_ADD_FUNCTION)(child_dest, child_source);
} else
/* child_dest is not a leaf node */
traverse_tries(child_dest, child_source);
/* child_dest and child_source are not leaf nodes */
traverse_tries_intersect(child_dest, child_source);
} else {
if (IS_LEAF_TRIE_NODE(child_dest)) {
if (DATA_DESTRUCT_FUNCTION)
(*DATA_DESTRUCT_FUNCTION)(child_dest);
DECREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
} else
free_child_nodes(TrNode_child(child_dest));
remove_trie(child_dest);
}
child_source = TrNode_next(child_source);
child_dest = child_next;
}
} while (bucket_source != first_bucket_source);
} while (bucket_dest != first_bucket_dest);
return;
}
while (child_source) {
/* parent_dest cannot be a leaf node */
child_dest = trie_node_check(parent_dest, TrNode_entry(child_source));
if (child_dest) {
while (child_dest) {
child_next = TrNode_next(child_dest);
/* parent_source is not a leaf node */
child_source = trie_node_check(parent_source, TrNode_entry(child_dest));
if (child_source) {
if (IS_LEAF_TRIE_NODE(child_dest)) {
if (IS_LEAF_TRIE_NODE(child_source))
(*DATA_JOIN_FUNCTION)(child_dest, child_source);
/* child_source is a leaf node */
if (DATA_ADD_FUNCTION)
(*DATA_ADD_FUNCTION)(child_dest, child_source);
} else
/* child_dest is not a leaf node */
traverse_tries(child_dest, child_source);
/* child_dest and child_source are not leaf nodes */
traverse_tries_intersect(child_dest, child_source);
} else {
if (IS_LEAF_TRIE_NODE(child_dest)) {
if (DATA_DESTRUCT_FUNCTION)
(*DATA_DESTRUCT_FUNCTION)(child_dest);
DECREMENT_ENTRIES(CURRENT_TRIE_ENGINE);
} else
free_child_nodes(TrNode_child(child_dest));
remove_trie(child_dest);
}
child_source = TrNode_next(child_source);
child_dest = child_next;
}
return;
}
static
YAP_Int count_tries_intersect(TrNode parent1, TrNode parent2) {
TrNode child1, child2;
YAP_Int count = 0;
/* parent1 is not a leaf node */
child1 = TrNode_child(parent1);
if (IS_HASH_NODE(child1)) {
TrNode *first_bucket, *bucket;
TrHash hash;
hash = (TrHash) child1;
first_bucket = TrHash_buckets(hash);
bucket = first_bucket + TrHash_num_buckets(hash);
do {
child1 = *--bucket;
while (child1) {
/* parent2 is not a leaf node */
child2 = trie_node_check(parent2, TrNode_entry(child1));
if (child2) {
if (IS_LEAF_TRIE_NODE(child1))
/* child2 is a leaf node */
count++;
else
/* child1 and child2 are not leaf nodes */
count += count_tries_intersect(child1, child2);
}
child1 = TrNode_next(child1);
}
} while (bucket != first_bucket);
return count;
}
while (child1) {
/* parent2 is not a leaf node */
child2 = trie_node_check(parent2, TrNode_entry(child1));
if (child2) {
if (IS_LEAF_TRIE_NODE(child1))
/* child2 is a leaf node */
count++;
else
/* child1 and child2 are not leaf nodes */
count += count_tries_intersect(child1, child2);
}
child1 = TrNode_next(child1);
}
return count;
}
static
YAP_Int count_trie(TrNode node) {
YAP_Int count = 0;
if (IS_HASH_NODE(node)) {
TrNode *first_bucket, *bucket;
TrHash hash;
hash = (TrHash) node;
first_bucket = TrHash_buckets(hash);
bucket = first_bucket + TrHash_num_buckets(hash);
do {
if (*--bucket) {
node = *bucket;
count += count_trie(node);
}
} while (bucket != first_bucket);
return count;
}
if (TrNode_next(node))
count += count_trie(TrNode_next(node));
if (!IS_LEAF_TRIE_NODE(node))
count += count_trie(TrNode_child(node));
else
count++;
return count;
}
static
void traverse_trie_usage(TrNode node, YAP_Int depth) {
if (IS_HASH_NODE(node)) {