Merge branch 'master' of ssh://yap.git.sourceforge.net/gitroot/yap/yap-6.3

This commit is contained in:
Vítor Santos Costa 2011-11-16 14:56:00 +00:00
commit 95b6f3a8c8
10 changed files with 746 additions and 482 deletions

View File

@ -20,13 +20,12 @@
/****************************************************************************************** /******************************************************************************************
** use shared pages memory alloc scheme for OPTYap data structures? (optional) ** ** use shared pages memory alloc scheme for OPTYap data structures? (optional) **
******************************************************************************************/ ******************************************************************************************/
/* #define USE_PAGES_MALLOC 1 */ /* #define USE_PAGES_MALLOC 1 */
/************************************************************************ /************************************************************************
** TABLING Configuration Parameters ** ** Tabling Configuration Parameters **
************************************************************************/ ************************************************************************/
/**************************** /****************************
@ -43,7 +42,7 @@
/********************************************************* /*********************************************************
** support mode directed tabling ? (optional) ** ** support mode directed tabling ? (optional) **
*********************************************************/ *********************************************************/
/* #define MODE_DIRECTED_TABLING 1 */ #define MODE_DIRECTED_TABLING 1
/**************************************************** /****************************************************
** support early completion ? (optional) ** ** support early completion ? (optional) **
@ -83,7 +82,7 @@
/************************************************************************ /************************************************************************
** YAPOR Configuration Parameters ** ** YapOr Configuration Parameters **
************************************************************************/ ************************************************************************/
/**************************** /****************************
@ -107,42 +106,57 @@
/************************************************************************ /************************************************************************
** OPTYAP Configuration Parameters ** ** OPTYap Configuration Parameters **
************************************************************************/ ************************************************************************/
/**************************** /****************************
** default sizes ** ** default sizes **
****************************/ ****************************/
#define TABLE_LOCK_BUCKETS 512
#define TG_ANSWER_SLOTS 20 #define TG_ANSWER_SLOTS 20
#define TRIE_LOCK_BUCKETS 512
/*********************************************************** /*************************************************************************
** tries locking scheme (mandatory, define one) ** ** tries locking scheme (mandatory, define one per trie type) **
************************************************************ **************************************************************************
** The TABLE_LOCK_AT_ENTRY_LEVEL scheme locks the access ** ** The (TRIE_TYPE)_LOCK_AT_ENTRY_LEVEL scheme locks the access to the **
** to the table space in the entry data structure. It ** ** table space in the entry data structure. It restricts the number of **
** restricts the number of lock operations needed to go ** ** lock operations needed to go through the table data structures. **
** through the table data structures. ** ** **
** ** ** The (TRIE_TYPE)_LOCK_AT_NODE_LEVEL scheme locks each data structure **
** The TABLE_LOCK_AT_NODE_LEVEL scheme locks each data ** ** before accessing it. It decreases concurrrency for workers accessing **
** structure before accessing it. It decreases ** ** commom parts of the table space. **
** concurrrency for workers accessing commom parts of the ** ** **
** table space. ** ** The (TRIE_TYPE)_LOCK_AT_WRITE_LEVEL scheme is an hibrid scheme, it **
** ** ** only locks a table data structure when it is going to update it. You **
** The TABLE_LOCK_AT_WRITE_LEVEL scheme is an hibrid ** ** can use (TRIE_TYPE)_ALLOC_BEFORE_CHECK with this scheme to allocate **
** scheme, it only locks a table data structure when it ** ** a node before checking if it will be necessary. **
** is going to update it. You can use ALLOC_BEFORE_CHECK ** *************************************************************************/
** with this scheme to allocate a node before checking ** /* #define SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL 1 */
** if it will be necessary. ** #define SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL 1
***********************************************************/ /* #define SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL 1 */
/* #define TABLE_LOCK_AT_ENTRY_LEVEL 1 */ /* #define SUBGOAL_TRIE_ALLOC_BEFORE_CHECK 1 */
/* #define TABLE_LOCK_AT_NODE_LEVEL 1 */
#define TABLE_LOCK_AT_WRITE_LEVEL 1
/* #define ALLOC_BEFORE_CHECK 1 */
/********************************************** /* #define ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL 1 */
** support inner cuts ? (optional) ** #define ANSWER_TRIE_LOCK_AT_NODE_LEVEL 1
**********************************************/ /* #define ANSWER_TRIE_LOCK_AT_WRITE_LEVEL 1 */
/* #define ANSWER_TRIE_ALLOC_BEFORE_CHECK 1 */
#define GLOBAL_TRIE_LOCK_AT_NODE_LEVEL 1
/* #define GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL 1 */
/* #define GLOBAL_TRIE_ALLOC_BEFORE_CHECK 1 */
/*******************************************************************
** tries locking data structure (mandatory, define one) **
********************************************************************
** Data structure to be used for locking the trie when using the **
** (TRIE_TYPE)_LOCK_AT_[NODE|WRITE]_LEVEL schemes **
*******************************************************************/
#define TRIE_LOCK_USING_NODE_FIELD 1
/* #define TRIE_LOCK_USING_GLOBAL_ARRAY 1 */
/******************************************************
** support tabling inner cuts ? (optional) **
******************************************************/
#define TABLING_INNER_CUTS 1 #define TABLING_INNER_CUTS 1
/********************************************************* /*********************************************************
@ -158,73 +172,138 @@
#ifndef USE_PAGES_MALLOC #ifndef USE_PAGES_MALLOC
#undef LIMIT_TABLING #undef LIMIT_TABLING
#endif /* !USE_PAGES_MALLOC */ #endif /* ! USE_PAGES_MALLOC */
#ifdef TABLING
#if !defined(BFZ_TRAIL_SCHEME) && !defined(BBREG_TRAIL_SCHEME)
#error Define a trail scheme
#endif
#if defined(BFZ_TRAIL_SCHEME) && defined(BBREG_TRAIL_SCHEME)
#error Do not define multiple trail schemes
#endif
#else /* ! TABLING */
#undef BFZ_TRAIL_SCHEME
#undef BBREG_TRAIL_SCHEME
#undef MODE_DIRECTED_TABLING
#undef TABLING_EARLY_COMPLETION
#undef TRIE_COMPACT_PAIRS
#undef GLOBAL_TRIE_FOR_SUBTERMS
#undef INCOMPLETE_TABLING
#undef LIMIT_TABLING
#undef DETERMINISTIC_TABLING
#undef DEBUG_TABLING
#endif /* TABLING */
#ifdef YAPOR #ifdef YAPOR
#ifdef i386 /* For i386 machines we use shared memory segments */ #ifdef i386 /* For i386 machines we use shared memory segments */
#undef MMAP_MEMORY_MAPPING_SCHEME #undef MMAP_MEMORY_MAPPING_SCHEME
#define SHM_MEMORY_MAPPING_SCHEME #define SHM_MEMORY_MAPPING_SCHEME
#endif /* i386 */ #endif
#if !defined(MMAP_MEMORY_MAPPING_SCHEME) && !defined(SHM_MEMORY_MAPPING_SCHEME) #if !defined(MMAP_MEMORY_MAPPING_SCHEME) && !defined(SHM_MEMORY_MAPPING_SCHEME)
#error Define a memory mapping scheme #error Define a memory mapping scheme
#endif /* !MMAP_MEMORY_MAPPING_SCHEME && !SHM_MEMORY_MAPPING_SCHEME */ #endif
#if defined(MMAP_MEMORY_MAPPING_SCHEME) && defined(SHM_MEMORY_MAPPING_SCHEME) #if defined(MMAP_MEMORY_MAPPING_SCHEME) && defined(SHM_MEMORY_MAPPING_SCHEME)
#error Do not define multiple memory mapping schemes #error Do not define multiple memory mapping schemes
#endif /* MMAP_MEMORY_MAPPING_SCHEME && SHM_MEMORY_MAPPING_SCHEME */ #endif
#undef LIMIT_TABLING #undef LIMIT_TABLING
#else /* ! YAPOR */
#undef MMAP_MEMORY_MAPPING_SCHEME
#undef SHM_MEMORY_MAPPING_SCHEME
#undef DEBUG_YAPOR
#endif /* YAPOR */ #endif /* YAPOR */
#ifdef TABLING
#if !defined(BFZ_TRAIL_SCHEME) && !defined(BBREG_TRAIL_SCHEME)
#error Define a trail scheme
#endif /* !BFZ_TRAIL_SCHEME && !BBREG_TRAIL_SCHEME */
#if defined(BFZ_TRAIL_SCHEME) && defined(BBREG_TRAIL_SCHEME)
#error Do not define multiple trail schemes
#endif /* BFZ_TRAIL_SCHEME && BBREG_TRAIL_SCHEME */
#endif /* TABLING */
#if defined(YAPOR) && defined(TABLING) #if defined(YAPOR) && defined(TABLING)
#if !defined(TABLE_LOCK_AT_ENTRY_LEVEL) && !defined(TABLE_LOCK_AT_NODE_LEVEL) && !defined(TABLE_LOCK_AT_WRITE_LEVEL) /* SUBGOAL_TRIE_LOCK_LEVEL */
#error Define a table lock scheme #if !defined(SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL) && !defined(SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL) && !defined(SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL)
#endif /* !TABLE_LOCK_AT_ENTRY_LEVEL && !TABLE_LOCK_AT_NODE_LEVEL && !TABLE_LOCK_AT_WRITE_LEVEL */ #error Define a subgoal trie lock scheme
#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) #endif
#if defined(TABLE_LOCK_AT_NODE_LEVEL) || defined(TABLE_LOCK_AT_WRITE_LEVEL) #if defined(SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL) && defined(SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL)
#error Do not define multiple table lock schemes #error Do not define multiple subgoal trie lock schemes
#endif /* TABLE_LOCK_AT_NODE_LEVEL || TABLE_LOCK_AT_WRITE_LEVEL */ #endif
#endif /* TABLE_LOCK_AT_ENTRY_LEVEL */ #if defined(SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL) && defined(SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL)
#if defined(TABLE_LOCK_AT_NODE_LEVEL) && defined(TABLE_LOCK_AT_WRITE_LEVEL) #error Do not define multiple subgoal trie lock schemes
#error Do not define multiple table lock schemes #endif
#endif /* TABLE_LOCK_AT_NODE_LEVEL || TABLE_LOCK_AT_WRITE_LEVEL */ #if defined(SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL) && defined(SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL)
#ifndef TABLE_LOCK_AT_WRITE_LEVEL #error Do not define multiple subgoal trie lock schemes
#undef ALLOC_BEFORE_CHECK #endif
#endif /* !TABLE_LOCK_AT_WRITE_LEVEL */ #ifndef SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL
#else #undef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
#undef TABLE_LOCK_AT_ENTRY_LEVEL #endif
#undef TABLE_LOCK_AT_NODE_LEVEL /* ANSWER_TRIE_LOCK_LEVEL */
#undef TABLE_LOCK_AT_WRITE_LEVEL #if !defined(ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL) && !defined(ANSWER_TRIE_LOCK_AT_NODE_LEVEL) && !defined(ANSWER_TRIE_LOCK_AT_WRITE_LEVEL)
#undef ALLOC_BEFORE_CHECK #error Define a answer trie lock scheme
#endif /* YAPOR && TABLING */ #endif
#if defined(ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL) && defined(ANSWER_TRIE_LOCK_AT_NODE_LEVEL)
#if !defined(TABLING) || !defined(YAPOR) #error Do not define multiple answer trie lock schemes
#endif
#if defined(ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL) && defined(ANSWER_TRIE_LOCK_AT_WRITE_LEVEL)
#error Do not define multiple answer trie lock schemes
#endif
#if defined(ANSWER_TRIE_LOCK_AT_NODE_LEVEL) && defined(ANSWER_TRIE_LOCK_AT_WRITE_LEVEL)
#error Do not define multiple answer trie lock schemes
#endif
#ifndef ANSWER_TRIE_LOCK_AT_WRITE_LEVEL
#undef ANSWER_TRIE_ALLOC_BEFORE_CHECK
#endif
/* GLOBAL_TRIE_LOCK_LEVEL */
#if !defined(GLOBAL_TRIE_LOCK_AT_NODE_LEVEL) && !defined(GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL)
#error Define a global trie lock scheme
#endif
#if defined(GLOBAL_TRIE_LOCK_AT_NODE_LEVEL) && defined(GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL)
#error Do not define multiple global trie lock schemes
#endif
#ifndef GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL
#undef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
#endif
/* TRIE_LOCK_USING_NODE_FIELD / TRIE_LOCK_USING_GLOBAL_ARRAY */
#if !defined(TRIE_LOCK_USING_NODE_FIELD) && !defined(TRIE_LOCK_USING_GLOBAL_ARRAY)
#error Define a trie lock data structure
#endif
#if defined(TRIE_LOCK_USING_NODE_FIELD) && defined(TRIE_LOCK_USING_GLOBAL_ARRAY)
#error Do not define multiple trie lock data structures
#endif
#ifdef TRIE_LOCK_USING_NODE_FIELD
#if defined(SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL) || defined(SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL)
#define SUBGOAL_TRIE_LOCK_USING_NODE_FIELD 1
#endif
#if defined(ANSWER_TRIE_LOCK_AT_NODE_LEVEL) || defined(ANSWER_TRIE_LOCK_AT_WRITE_LEVEL)
#define ANSWER_TRIE_LOCK_USING_NODE_FIELD 1
#endif
#if defined(GLOBAL_TRIE_LOCK_AT_NODE_LEVEL) || defined(GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL)
#define GLOBAL_TRIE_LOCK_USING_NODE_FIELD 1
#endif
#elif TRIE_LOCK_USING_GLOBAL_ARRAY
#if defined(SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL) || defined(SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL)
#define SUBGOAL_TRIE_LOCK_USING_GLOBAL_ARRAY 1
#endif
#if defined(ANSWER_TRIE_LOCK_AT_NODE_LEVEL) || defined(ANSWER_TRIE_LOCK_AT_WRITE_LEVEL)
#define ANSWER_TRIE_LOCK_USING_GLOBAL_ARRAY 1
#endif
#if defined(GLOBAL_TRIE_LOCK_AT_NODE_LEVEL) || defined(GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL)
#define GLOBAL_TRIE_LOCK_USING_GLOBAL_ARRAY 1
#endif
#endif
#else /* ! TABLING || ! YAPOR */
#undef SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL
#undef SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL
#undef SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL
#undef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
#undef ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL
#undef ANSWER_TRIE_LOCK_AT_NODE_LEVEL
#undef ANSWER_TRIE_LOCK_AT_WRITE_LEVEL
#undef ANSWER_TRIE_ALLOC_BEFORE_CHECK
#undef GLOBAL_TRIE_LOCK_AT_NODE_LEVEL
#undef GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL
#undef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
#undef TRIE_LOCK_USING_NODE_FIELD
#undef TRIE_LOCK_USING_GLOBAL_ARRAY
#undef TABLING_INNER_CUTS #undef TABLING_INNER_CUTS
#undef TIMESTAMP_CHECK #undef TIMESTAMP_CHECK
#endif /* !TABLING || !YAPOR */ #endif /* YAPOR && TABLING */
#ifndef YAPOR
#undef DEBUG_YAPOR
#endif /* !YAPOR */
#ifndef TABLING
#undef BFZ_TRAIL_SCHEME
#undef BBREG_TRAIL_SCHEME
#undef TABLING_EARLY_COMPLETION
#undef TRIE_COMPACT_PAIRS
#undef GLOBAL_TRIE_FOR_SUBTERMS
#undef DETERMINISTIC_TABLING
#undef LIMIT_TABLING
#undef INCOMPLETE_TABLING
#undef DEBUG_TABLING
#endif /* !TABLING */
#if defined(DEBUG_YAPOR) && defined(DEBUG_TABLING) #if defined(DEBUG_YAPOR) && defined(DEBUG_TABLING)
#define DEBUG_OPTYAP #define DEBUG_OPTYAP

View File

@ -147,10 +147,10 @@ void Yap_init_global_optyap_data(int max_table_size, int n_workers, int sch_loop
CELL *pt = GLOBAL_table_var_enumerator_addr(i); CELL *pt = GLOBAL_table_var_enumerator_addr(i);
RESET_VARIABLE(pt); RESET_VARIABLE(pt);
} }
#ifdef TABLE_LOCK_AT_WRITE_LEVEL #ifdef TRIE_LOCK_USING_GLOBAL_ARRAY
for (i = 0; i < TABLE_LOCK_BUCKETS; i++) for (i = 0; i < TRIE_LOCK_BUCKETS; i++)
INIT_LOCK(GLOBAL_table_lock(i)); INIT_LOCK(GLOBAL_trie_locks(i));
#endif /* TABLE_LOCK_AT_WRITE_LEVEL */ #endif /* TRIE_LOCK_USING_GLOBAL_ARRAY */
#endif /* TABLING */ #endif /* TABLING */
return; return;

View File

@ -255,7 +255,7 @@ static Int p_table( USES_REGS1 ) {
pos_agreg = pos_index; pos_agreg = pos_index;
pos_index = 0; pos_index = 0;
for (i = 0; i < arity; i++) { for (i = 0; i < arity; i++) {
int aux_pos; int aux_pos = 0;
if (aux_mode_directed[i] == MODE_DIRECTED_MAX) if (aux_mode_directed[i] == MODE_DIRECTED_MAX)
aux_pos = pos_agreg++; aux_pos = pos_agreg++;
else if (aux_mode_directed[i] == MODE_DIRECTED_MIN) else if (aux_mode_directed[i] == MODE_DIRECTED_MIN)

View File

@ -45,6 +45,9 @@ void finish_yapor(void);
#ifdef TABLING #ifdef TABLING
sg_fr_ptr subgoal_search(yamop *, CELL **); sg_fr_ptr subgoal_search(yamop *, CELL **);
ans_node_ptr answer_search(sg_fr_ptr, CELL *); ans_node_ptr answer_search(sg_fr_ptr, CELL *);
#ifdef MODE_DIRECTED_TABLING
ans_node_ptr mode_directed_answer_search(sg_fr_ptr, CELL *);
#endif /* MODE_DIRECTED_TABLING */
void load_answer(ans_node_ptr, CELL *); void load_answer(ans_node_ptr, CELL *);
CELL *exec_substitution(gt_node_ptr, CELL *); CELL *exec_substitution(gt_node_ptr, CELL *);
void update_answer_trie(sg_fr_ptr); void update_answer_trie(sg_fr_ptr);

View File

@ -213,9 +213,9 @@ struct global_optyap_data {
struct dependency_frame *root_dependency_frame; struct dependency_frame *root_dependency_frame;
#endif /* YAPOR */ #endif /* YAPOR */
CELL table_var_enumerator[MAX_TABLE_VARS]; CELL table_var_enumerator[MAX_TABLE_VARS];
#ifdef TABLE_LOCK_AT_WRITE_LEVEL #ifdef TRIE_LOCK_USING_GLOBAL_ARRAY
lockvar table_lock[TABLE_LOCK_BUCKETS]; lockvar trie_locks[TRIE_LOCK_BUCKETS];
#endif /* TABLE_LOCK_AT_WRITE_LEVEL */ #endif /* TRIE_LOCK_USING_GLOBAL_ARRAY */
#ifdef TIMESTAMP_CHECK #ifdef TIMESTAMP_CHECK
long timestamp; long timestamp;
#endif /* TIMESTAMP_CHECK */ #endif /* TIMESTAMP_CHECK */
@ -282,7 +282,7 @@ struct global_optyap_data {
#define GLOBAL_root_dep_fr (GLOBAL_optyap_data.root_dependency_frame) #define GLOBAL_root_dep_fr (GLOBAL_optyap_data.root_dependency_frame)
#define GLOBAL_table_var_enumerator(index) (GLOBAL_optyap_data.table_var_enumerator[index]) #define GLOBAL_table_var_enumerator(index) (GLOBAL_optyap_data.table_var_enumerator[index])
#define GLOBAL_table_var_enumerator_addr(index) (GLOBAL_optyap_data.table_var_enumerator + (index)) #define GLOBAL_table_var_enumerator_addr(index) (GLOBAL_optyap_data.table_var_enumerator + (index))
#define GLOBAL_table_lock(index) (GLOBAL_optyap_data.table_lock[index]) #define GLOBAL_trie_locks(index) (GLOBAL_optyap_data.trie_locks[index])
#define GLOBAL_timestamp (GLOBAL_optyap_data.timestamp) #define GLOBAL_timestamp (GLOBAL_optyap_data.timestamp)

View File

@ -865,19 +865,19 @@
} }
} }
#endif /* DEBUG_TABLING && !DETERMINISTIC_TABLING */ #endif /* DEBUG_TABLING && !DETERMINISTIC_TABLING */
#ifdef TABLE_LOCK_AT_ENTRY_LEVEL LOCK_ANSWER_TRIE(sg_fr);
LOCK(SgFr_lock(sg_fr));
#endif /* TABLE_LOCK_LEVEL */
ans_node = answer_search(sg_fr, subs_ptr);
#ifdef MODE_DIRECTED_TABLING #ifdef MODE_DIRECTED_TABLING
if (ans_node == NULL) /* no answer inserted */ if (SgFr_mode_directed(sg_fr)) {
goto fail; ans_node = mode_directed_answer_search(sg_fr, subs_ptr);
if (ans_node == NULL) {
/* no answer inserted */
UNLOCK_ANSWER_TRIE(sg_fr);
goto fail;
}
} else
#endif /* MODE_DIRECTED_TABLING */ #endif /* MODE_DIRECTED_TABLING */
#if defined(TABLE_LOCK_AT_NODE_LEVEL) ans_node = answer_search(sg_fr, subs_ptr);
LOCK(TrNode_lock(ans_node)); LOCK_ANSWER_NODE(ans_node);
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
LOCK_TABLE(ans_node);
#endif /* TABLE_LOCK_LEVEL */
if (! IS_ANSWER_LEAF_NODE(ans_node)) { if (! IS_ANSWER_LEAF_NODE(ans_node)) {
/* new answer */ /* new answer */
#ifdef TABLING_INNER_CUTS #ifdef TABLING_INNER_CUTS
@ -903,13 +903,8 @@
EQUAL_OR_YOUNGER_CP(Get_LOCAL_top_cp(), REMOTE_pruning_scope(i))) { EQUAL_OR_YOUNGER_CP(Get_LOCAL_top_cp(), REMOTE_pruning_scope(i))) {
leftmost_or_fr = LOCAL_top_or_fr; leftmost_or_fr = LOCAL_top_or_fr;
pending_table_new_answer: pending_table_new_answer:
#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) UNLOCK_ANSWER_NODE(ans_node);
UNLOCK(SgFr_lock(sg_fr)); UNLOCK_ANSWER_TRIE(sg_fr);
#elif defined(TABLE_LOCK_AT_NODE_LEVEL)
UNLOCK(TrNode_lock(ans_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
UNLOCK_TABLE(ans_node);
#endif /* TABLE_LOCK_LEVEL */
LOCK_OR_FRAME(leftmost_or_fr); LOCK_OR_FRAME(leftmost_or_fr);
if (Get_LOCAL_prune_request()) { if (Get_LOCAL_prune_request()) {
UNLOCK_OR_FRAME(leftmost_or_fr); UNLOCK_OR_FRAME(leftmost_or_fr);
@ -996,24 +991,16 @@
/* check for prune requests */ /* check for prune requests */
if (Get_LOCAL_prune_request()) { if (Get_LOCAL_prune_request()) {
#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) UNLOCK_ANSWER_NODE(ans_node);
UNLOCK(SgFr_lock(sg_fr)); UNLOCK_ANSWER_TRIE(sg_fr);
#elif defined(TABLE_LOCK_AT_NODE_LEVEL)
UNLOCK(TrNode_lock(ans_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
UNLOCK_TABLE(ans_node);
#endif /* TABLE_LOCK_LEVEL */
SCHEDULER_GET_WORK(); SCHEDULER_GET_WORK();
} }
#endif /* TABLING_INNER_CUTS */ #endif /* TABLING_INNER_CUTS */
TAG_AS_ANSWER_LEAF_NODE(ans_node); TAG_AS_ANSWER_LEAF_NODE(ans_node);
#if defined(TABLE_LOCK_AT_NODE_LEVEL) UNLOCK_ANSWER_NODE(ans_node);
UNLOCK(TrNode_lock(ans_node)); #ifndef ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL
LOCK(SgFr_lock(sg_fr)); LOCK(SgFr_lock(sg_fr));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL) #endif /* ! ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL */
UNLOCK_TABLE(ans_node);
LOCK(SgFr_lock(sg_fr));
#endif /* TABLE_LOCK_LEVEL */
if (SgFr_first_answer(sg_fr) == NULL) if (SgFr_first_answer(sg_fr) == NULL)
SgFr_first_answer(sg_fr) = ans_node; SgFr_first_answer(sg_fr) = ans_node;
else else
@ -1072,13 +1059,8 @@
} }
} else { } else {
/* repeated answer */ /* repeated answer */
#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) UNLOCK_ANSWER_NODE(ans_node);
UNLOCK(SgFr_lock(sg_fr)); UNLOCK_ANSWER_TRIE(sg_fr);
#elif defined(TABLE_LOCK_AT_NODE_LEVEL)
UNLOCK(TrNode_lock(ans_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
UNLOCK_TABLE(ans_node);
#endif /* TABLE_LOCK_LEVEL */
goto fail; goto fail;
} }
ENDPBOp(); ENDPBOp();
@ -1111,18 +1093,13 @@
/* unconsumed answers */ /* unconsumed answers */
#ifdef MODE_DIRECTED_TABLING #ifdef MODE_DIRECTED_TABLING
if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) { if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) {
ans_node_ptr first_ans_node, aux_ans_node; ans_node_ptr old_ans_node;
first_ans_node = ans_node; old_ans_node = ans_node;
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
do { do {
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
} while (IS_INVALID_LEAF_NODE(ans_node)); } while (IS_INVALID_LEAF_NODE(ans_node));
aux_ans_node = TrNode_child(first_ans_node); TrNode_child(old_ans_node) = ans_node;
do {
TrNode_child(first_ans_node) = ans_node;
first_ans_node = aux_ans_node;
aux_ans_node = TrNode_child(first_ans_node);
} while (aux_ans_node != ans_node);
} else } else
#endif /* MODE_DIRECTED_TABLING */ #endif /* MODE_DIRECTED_TABLING */
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
@ -1175,18 +1152,13 @@
/* dependency frame with unconsumed answers */ /* dependency frame with unconsumed answers */
#ifdef MODE_DIRECTED_TABLING #ifdef MODE_DIRECTED_TABLING
if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) { if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) {
ans_node_ptr first_ans_node, aux_ans_node; ans_node_ptr old_ans_node;
first_ans_node = ans_node; old_ans_node = ans_node;
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
do { do {
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
} while (IS_INVALID_LEAF_NODE(ans_node)); } while (IS_INVALID_LEAF_NODE(ans_node));
aux_ans_node = TrNode_child(first_ans_node); TrNode_child(old_ans_node) = ans_node;
do {
TrNode_child(first_ans_node) = ans_node;
first_ans_node = aux_ans_node;
aux_ans_node = TrNode_child(first_ans_node);
} while (aux_ans_node != ans_node);
} else } else
#endif /* MODE_DIRECTED_TABLING */ #endif /* MODE_DIRECTED_TABLING */
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
@ -1434,18 +1406,13 @@
/* dependency frame with unconsumed answers */ /* dependency frame with unconsumed answers */
#ifdef MODE_DIRECTED_TABLING #ifdef MODE_DIRECTED_TABLING
if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) { if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) {
ans_node_ptr first_ans_node, aux_ans_node; ans_node_ptr old_ans_node;
first_ans_node = ans_node; old_ans_node = ans_node;
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
do { do {
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
} while (IS_INVALID_LEAF_NODE(ans_node)); } while (IS_INVALID_LEAF_NODE(ans_node));
aux_ans_node = TrNode_child(first_ans_node); TrNode_child(old_ans_node) = ans_node;
do {
TrNode_child(first_ans_node) = ans_node;
first_ans_node = aux_ans_node;
aux_ans_node = TrNode_child(first_ans_node);
} while (aux_ans_node != ans_node);
} else } else
#endif /* MODE_DIRECTED_TABLING */ #endif /* MODE_DIRECTED_TABLING */
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
@ -1609,18 +1576,13 @@
UNLOCK_OR_FRAME(LOCAL_top_or_fr); UNLOCK_OR_FRAME(LOCAL_top_or_fr);
#ifdef MODE_DIRECTED_TABLING #ifdef MODE_DIRECTED_TABLING
if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) { if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) {
ans_node_ptr first_ans_node, aux_ans_node; ans_node_ptr old_ans_node;
first_ans_node = ans_node; old_ans_node = ans_node;
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
do { do {
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);
} while (IS_INVALID_LEAF_NODE(ans_node)); } while (IS_INVALID_LEAF_NODE(ans_node));
aux_ans_node = TrNode_child(first_ans_node); TrNode_child(old_ans_node) = ans_node;
do {
TrNode_child(first_ans_node) = ans_node;
first_ans_node = aux_ans_node;
aux_ans_node = TrNode_child(first_ans_node);
} while (aux_ans_node != ans_node);
} else } else
#endif /* MODE_DIRECTED_TABLING */ #endif /* MODE_DIRECTED_TABLING */
ans_node = TrNode_child(ans_node); ans_node = TrNode_child(ans_node);

View File

@ -135,6 +135,7 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
#define CompactPairEndList AbsPair((Term *) (2*(LowTagBits + 1))) #define CompactPairEndList AbsPair((Term *) (2*(LowTagBits + 1)))
#endif /* TRIE_COMPACT_PAIRS */ #endif /* TRIE_COMPACT_PAIRS */
/* choice points */
#define NORM_CP(CP) ((choiceptr)(CP)) #define NORM_CP(CP) ((choiceptr)(CP))
#define GEN_CP(CP) ((struct generator_choicept *)(CP)) #define GEN_CP(CP) ((struct generator_choicept *)(CP))
#define CONS_CP(CP) ((struct consumer_choicept *)(CP)) #define CONS_CP(CP) ((struct consumer_choicept *)(CP))
@ -148,6 +149,7 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
#define IS_BATCHED_GEN_CP(CP) (GEN_CP(CP)->cp_dep_fr == NULL) #define IS_BATCHED_GEN_CP(CP) (GEN_CP(CP)->cp_dep_fr == NULL)
#endif /* DETERMINISTIC_TABLING */ #endif /* DETERMINISTIC_TABLING */
/* leaf nodes */
#define TAG_AS_SUBGOAL_LEAF_NODE(NODE) TrNode_child(NODE) = (sg_node_ptr)((unsigned long int) TrNode_child(NODE) | 0x1) #define TAG_AS_SUBGOAL_LEAF_NODE(NODE) TrNode_child(NODE) = (sg_node_ptr)((unsigned long int) TrNode_child(NODE) | 0x1)
#define UNTAG_SUBGOAL_LEAF_NODE(NODE) ((sg_fr_ptr)((unsigned long int) (NODE) & ~(0x1))) #define UNTAG_SUBGOAL_LEAF_NODE(NODE) ((sg_fr_ptr)((unsigned long int) (NODE) & ~(0x1)))
#define IS_SUBGOAL_LEAF_NODE(NODE) ((unsigned long int) TrNode_child(NODE) & 0x1) #define IS_SUBGOAL_LEAF_NODE(NODE) ((unsigned long int) TrNode_child(NODE) & 0x1)
@ -157,6 +159,7 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
#define TAG_AS_INVALID_LEAF_NODE(NODE) TrNode_parent(NODE) = (ans_node_ptr)((unsigned long int) TrNode_parent(NODE) | 0x2) #define TAG_AS_INVALID_LEAF_NODE(NODE) TrNode_parent(NODE) = (ans_node_ptr)((unsigned long int) TrNode_parent(NODE) | 0x2)
#define IS_INVALID_LEAF_NODE(NODE) ((unsigned long int) TrNode_parent(NODE) & 0x2) #define IS_INVALID_LEAF_NODE(NODE) ((unsigned long int) TrNode_parent(NODE) & 0x2)
/* trie hashes */
#define MAX_NODES_PER_TRIE_LEVEL 8 #define MAX_NODES_PER_TRIE_LEVEL 8
#define MAX_NODES_PER_BUCKET (MAX_NODES_PER_TRIE_LEVEL / 2) #define MAX_NODES_PER_BUCKET (MAX_NODES_PER_TRIE_LEVEL / 2)
#define BASE_HASH_BUCKETS 64 #define BASE_HASH_BUCKETS 64
@ -167,26 +170,26 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
#define IS_ANSWER_TRIE_HASH(NODE) (TrNode_instr(NODE) == ANSWER_TRIE_HASH_MARK) #define IS_ANSWER_TRIE_HASH(NODE) (TrNode_instr(NODE) == ANSWER_TRIE_HASH_MARK)
#define GLOBAL_TRIE_HASH_MARK ((Term) MakeTableVarTerm(MAX_TABLE_VARS)) #define GLOBAL_TRIE_HASH_MARK ((Term) MakeTableVarTerm(MAX_TABLE_VARS))
#define IS_GLOBAL_TRIE_HASH(NODE) (TrNode_entry(NODE) == GLOBAL_TRIE_HASH_MARK) #define IS_GLOBAL_TRIE_HASH(NODE) (TrNode_entry(NODE) == GLOBAL_TRIE_HASH_MARK)
#define HASH_TRIE_LOCK(NODE) GLOBAL_trie_locks((((unsigned long int) (NODE)) >> 5) & (TRIE_LOCK_BUCKETS - 1))
#define HASH_TABLE_LOCK(NODE) ((((unsigned long int) (NODE)) >> 5) & (TABLE_LOCK_BUCKETS - 1)) /* auxiliary stack */
#define LOCK_TABLE(NODE) LOCK(GLOBAL_table_lock(HASH_TABLE_LOCK(NODE))) #define STACK_PUSH_UP(ITEM, STACK) *--(STACK) = (CELL)(ITEM)
#define UNLOCK_TABLE(NODE) UNLOCK(GLOBAL_table_lock(HASH_TABLE_LOCK(NODE))) #define STACK_POP_UP(STACK) *--(STACK)
#define STACK_PUSH_DOWN(ITEM, STACK) *(STACK)++ = (CELL)(ITEM)
#define STACK_PUSH_UP(ITEM, STACK) *--(STACK) = (CELL)(ITEM) #define STACK_POP_DOWN(STACK) *(STACK)++
#define STACK_POP_UP(STACK) *--(STACK) #define STACK_NOT_EMPTY(STACK, STACK_BASE) (STACK) != (STACK_BASE)
#define STACK_PUSH_DOWN(ITEM, STACK) *(STACK)++ = (CELL)(ITEM)
#define STACK_POP_DOWN(STACK) *(STACK)++
#define STACK_NOT_EMPTY(STACK, STACK_BASE) (STACK) != (STACK_BASE)
#define AUX_STACK_CHECK_EXPAND(STACK, STACK_LIMIT) if ((STACK_LIMIT) >= (STACK)) EXPAND_AUX_STACK(STACK)
#define STACK_CHECK_EXPAND(STACK, STACK_LIMIT) if ((STACK_LIMIT) >= (STACK)+4096) EXPAND_STACK(STACK)
#if defined(YAPOR_COPY) || defined(YAPOR_COW) || defined(YAPOR_SBA) #if defined(YAPOR_COPY) || defined(YAPOR_COW) || defined(YAPOR_SBA)
#define EXPAND_AUX_STACK(STACK) Yap_Error(INTERNAL_ERROR, TermNil, "stack full (AUX_STACK_CHECK_EXPAND)"); #define AUX_STACK_CHECK_EXPAND(STACK, STACK_LIMIT) \
#define EXPAND_STACK(STACK) Yap_Error(INTERNAL_ERROR, TermNil, "stack full (STACK_CHECK_EXPAND)"); if ((STACK_LIMIT) >= (STACK)) \
Yap_Error(INTERNAL_ERROR, TermNil, "stack full (AUX_STACK_CHECK_EXPAND)")
#else /* YAPOR_THREADS */ #else /* YAPOR_THREADS */
#define EXPAND_AUX_STACK(STACK) STACK = expand_auxiliary_stack(STACK) #define AUX_STACK_CHECK_EXPAND(STACK, STACK_LIMIT) \
#define EXPAND_STACK(STACK) Yap_Error(INTERNAL_ERROR, TermNil, "stack full (STACK_CHECK_EXPAND)"); if ((STACK_LIMIT) >= (STACK)) \
STACK = expand_auxiliary_stack(STACK)
#endif /* YAPOR */ #endif /* YAPOR */
#define OPTYAP_ERROR_MESSAGE(OP, COND) #define STACK_CHECK_EXPAND(STACK, STACK_LIMIT) \
if ((STACK_LIMIT) >= (STACK) + 4096) \
Yap_Error(INTERNAL_ERROR, TermNil, "stack full (STACK_CHECK_EXPAND)")
@ -270,43 +273,87 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
#define AnsHash_init_previous_field(HASH, SG_FR) #define AnsHash_init_previous_field(HASH, SG_FR)
#endif /* MODE_DIRECTED_TABLING */ #endif /* MODE_DIRECTED_TABLING */
#ifdef TABLE_LOCK_AT_ENTRY_LEVEL #ifdef SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL
#define TabEnt_init_lock_field(TAB_ENT) \ #define LOCK_SUBGOAL_TRIE(TAB_ENT) LOCK(TabEnt_lock(TAB_ENT))
INIT_LOCK(TabEnt_lock(TAB_ENT)) #define UNLOCK_SUBGOAL_TRIE(TAB_ENT) UNLOCK(TabEnt_lock(TAB_ENT))
#define SgHash_init_next_field(HASH, TAB_ENT) \ #define SgHash_init_next_field(HASH, TAB_ENT) \
Hash_next(HASH) = TabEnt_hash_chain(TAB_ENT); \ Hash_next(HASH) = TabEnt_hash_chain(TAB_ENT); \
TabEnt_hash_chain(TAB_ENT) = HASH TabEnt_hash_chain(TAB_ENT) = HASH
#define AnsHash_init_chain_fields(HASH, SG_FR) \
AnsHash_init_previous_field(HASH, SG_FR); \
Hash_next(HASH) = SgFr_hash_chain(SG_FR); \
SgFr_hash_chain(SG_FR) = HASH
#else #else
#define TabEnt_init_lock_field(TAB_ENT) #define LOCK_SUBGOAL_TRIE(TAB_ENT)
#define UNLOCK_SUBGOAL_TRIE(TAB_ENT)
#define SgHash_init_next_field(HASH, TAB_ENT) \ #define SgHash_init_next_field(HASH, TAB_ENT) \
LOCK(TabEnt_lock(TAB_ENT)); \ LOCK(TabEnt_lock(TAB_ENT)); \
Hash_next(HASH) = TabEnt_hash_chain(TAB_ENT); \ Hash_next(HASH) = TabEnt_hash_chain(TAB_ENT); \
TabEnt_hash_chain(TAB_ENT) = HASH; \ TabEnt_hash_chain(TAB_ENT) = HASH; \
UNLOCK(TabEnt_lock(TAB_ENT)) UNLOCK(TabEnt_lock(TAB_ENT))
#define AnsHash_init_chain_fields(HASH, SG_FR) \ #endif /* SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL */
LOCK(SgFr_lock(SG_FR)); \
AnsHash_init_previous_field(HASH, SG_FR); \
Hash_next(HASH) = SgFr_hash_chain(SG_FR); \
SgFr_hash_chain(SG_FR) = HASH; \
UNLOCK(SgFr_lock(SG_FR))
#endif /* TABLE_LOCK_AT_ENTRY_LEVEL */
#ifdef TABLE_LOCK_AT_NODE_LEVEL #ifdef ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL
#define TrNode_init_lock_field(NODE) \ #define LOCK_ANSWER_TRIE(SG_FR) LOCK(SgFr_lock(SG_FR))
INIT_LOCK(TrNode_lock(NODE)) #define UNLOCK_ANSWER_TRIE(SG_FR) UNLOCK(SgFr_lock(SG_FR))
#define AnsHash_init_chain_fields(HASH, SG_FR) \
AnsHash_init_previous_field(HASH, SG_FR); \
Hash_next(HASH) = SgFr_hash_chain(SG_FR); \
SgFr_hash_chain(SG_FR) = HASH
#else #else
#define TrNode_init_lock_field(NODE) #define LOCK_ANSWER_TRIE(SG_FR)
#endif /* TABLE_LOCK_AT_NODE_LEVEL */ #define UNLOCK_ANSWER_TRIE(SG_FR)
#define AnsHash_init_chain_fields(HASH, SG_FR) \
LOCK(SgFr_lock(SG_FR)); \
AnsHash_init_previous_field(HASH, SG_FR); \
Hash_next(HASH) = SgFr_hash_chain(SG_FR); \
SgFr_hash_chain(SG_FR) = HASH; \
UNLOCK(SgFr_lock(SG_FR))
#endif /* ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL */
#ifdef SUBGOAL_TRIE_LOCK_USING_NODE_FIELD
#define LOCK_SUBGOAL_NODE(NODE) LOCK(TrNode_lock(NODE))
#define UNLOCK_SUBGOAL_NODE(NODE) UNLOCK(TrNode_lock(NODE))
#define SgNode_init_lock_field(NODE) INIT_LOCK(TrNode_lock(NODE))
#elif SUBGOAL_TRIE_LOCK_USING_GLOBAL_ARRAY
#define LOCK_SUBGOAL_NODE(NODE) LOCK(HASH_TRIE_LOCK(NODE))
#define UNLOCK_SUBGOAL_NODE(NODE) UNLOCK(HASH_TRIE_LOCK(NODE))
#define SgNode_init_lock_field(NODE)
#else
#define LOCK_SUBGOAL_NODE(NODE)
#define UNLOCK_SUBGOAL_NODE(NODE)
#define SgNode_init_lock_field(NODE)
#endif /* SUBGOAL_TRIE_LOCK_LEVEL */
#ifdef ANSWER_TRIE_LOCK_USING_NODE_FIELD
#define LOCK_ANSWER_NODE(NODE) LOCK(TrNode_lock(NODE))
#define UNLOCK_ANSWER_NODE(NODE) UNLOCK(TrNode_lock(NODE))
#define AnsNode_init_lock_field(NODE) INIT_LOCK(TrNode_lock(NODE))
#elif ANSWER_TRIE_LOCK_USING_GLOBAL_ARRAY
#define LOCK_ANSWER_NODE(NODE) LOCK(HASH_TRIE_LOCK(NODE))
#define UNLOCK_ANSWER_NODE(NODE) UNLOCK(HASH_TRIE_LOCK(NODE))
#define AnsNode_init_lock_field(NODE)
#else
#define LOCK_ANSWER_NODE(NODE)
#define UNLOCK_ANSWER_NODE(NODE)
#define AnsNode_init_lock_field(NODE)
#endif /* ANSWER_TRIE_LOCK_LEVEL */
#ifdef GLOBAL_TRIE_LOCK_USING_NODE_FIELD
#define LOCK_GLOBAL_NODE(NODE) LOCK(TrNode_lock(NODE))
#define UNLOCK_GLOBAL_NODE(NODE) UNLOCK(TrNode_lock(NODE))
#define GtNode_init_lock_field(NODE) INIT_LOCK(TrNode_lock(NODE))
#elif GLOBAL_TRIE_LOCK_USING_GLOBAL_ARRAY
#define LOCK_GLOBAL_NODE(NODE) LOCK(HASH_TRIE_LOCK(NODE))
#define UNLOCK_GLOBAL_NODE(NODE) UNLOCK(HASH_TRIE_LOCK(NODE))
#define GtNode_init_lock_field(NODE)
#else
#define LOCK_GLOBAL_NODE(NODE)
#define UNLOCK_GLOBAL_NODE(NODE)
#define GtNode_init_lock_field(NODE)
#endif /* GLOBAL_TRIE_LOCK_LEVEL */
#define new_table_entry(TAB_ENT, PRED_ENTRY, ATOM, ARITY, MODE_ARRAY) \ #define new_table_entry(TAB_ENT, PRED_ENTRY, ATOM, ARITY, MODE_ARRAY) \
{ register sg_node_ptr sg_node; \ { register sg_node_ptr sg_node; \
new_subgoal_trie_node(sg_node, 0, NULL, NULL, NULL); \ new_subgoal_trie_node(sg_node, 0, NULL, NULL, NULL); \
ALLOC_TABLE_ENTRY(TAB_ENT); \ ALLOC_TABLE_ENTRY(TAB_ENT); \
TabEnt_init_lock_field(TAB_ENT); \ INIT_LOCK(TabEnt_lock(TAB_ENT)); \
TabEnt_pe(TAB_ENT) = PRED_ENTRY; \ TabEnt_pe(TAB_ENT) = PRED_ENTRY; \
TabEnt_atom(TAB_ENT) = ATOM; \ TabEnt_atom(TAB_ENT) = ATOM; \
TabEnt_arity(TAB_ENT) = ARITY; \ TabEnt_arity(TAB_ENT) = ARITY; \
@ -362,48 +409,49 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
(unsigned long int) (&TrNode_child((ans_node_ptr)DEP_FR))); \ (unsigned long int) (&TrNode_child((ans_node_ptr)DEP_FR))); \
DepFr_next(DEP_FR) = NEXT DepFr_next(DEP_FR) = NEXT
#define new_suspension_frame(SUSP_FR, TOP_OR_FR_ON_STACK, TOP_DEP, TOP_SG, \ #define new_suspension_frame(SUSP_FR, TOP_OR_FR_ON_STACK, TOP_DEP, TOP_SG, \
H_REG, B_REG, TR_REG, H_SIZE, B_SIZE, TR_SIZE) \ H_REG, B_REG, TR_REG, H_SIZE, B_SIZE, TR_SIZE) \
ALLOC_SUSPENSION_FRAME(SUSP_FR); \ ALLOC_SUSPENSION_FRAME(SUSP_FR); \
SuspFr_top_or_fr_on_stack(SUSP_FR) = TOP_OR_FR_ON_STACK; \ SuspFr_top_or_fr_on_stack(SUSP_FR) = TOP_OR_FR_ON_STACK; \
SuspFr_top_dep_fr(SUSP_FR) = TOP_DEP; \ SuspFr_top_dep_fr(SUSP_FR) = TOP_DEP; \
SuspFr_top_sg_fr(SUSP_FR) = TOP_SG; \ SuspFr_top_sg_fr(SUSP_FR) = TOP_SG; \
SuspFr_global_reg(SUSP_FR) = (void *) (H_REG); \ SuspFr_global_reg(SUSP_FR) = (void *) (H_REG); \
SuspFr_local_reg(SUSP_FR) = (void *) (B_REG); \ SuspFr_local_reg(SUSP_FR) = (void *) (B_REG); \
SuspFr_trail_reg(SUSP_FR) = (void *) (TR_REG); \ SuspFr_trail_reg(SUSP_FR) = (void *) (TR_REG); \
ALLOC_BLOCK(SuspFr_global_start(SUSP_FR), H_SIZE + B_SIZE + TR_SIZE, void *); \ ALLOC_BLOCK(SuspFr_global_start(SUSP_FR), H_SIZE + B_SIZE + TR_SIZE, void *); \
SuspFr_local_start(SUSP_FR) = SuspFr_global_start(SUSP_FR) + H_SIZE; \ SuspFr_local_start(SUSP_FR) = SuspFr_global_start(SUSP_FR) + H_SIZE; \
SuspFr_trail_start(SUSP_FR) = SuspFr_local_start(SUSP_FR) + B_SIZE; \ SuspFr_trail_start(SUSP_FR) = SuspFr_local_start(SUSP_FR) + B_SIZE; \
SuspFr_global_size(SUSP_FR) = H_SIZE; \ SuspFr_global_size(SUSP_FR) = H_SIZE; \
SuspFr_local_size(SUSP_FR) = B_SIZE; \ SuspFr_local_size(SUSP_FR) = B_SIZE; \
SuspFr_trail_size(SUSP_FR) = TR_SIZE; \ SuspFr_trail_size(SUSP_FR) = TR_SIZE; \
memcpy(SuspFr_global_start(SUSP_FR), SuspFr_global_reg(SUSP_FR), H_SIZE); \ memcpy(SuspFr_global_start(SUSP_FR), SuspFr_global_reg(SUSP_FR), H_SIZE); \
memcpy(SuspFr_local_start(SUSP_FR), SuspFr_local_reg(SUSP_FR), B_SIZE); \ memcpy(SuspFr_local_start(SUSP_FR), SuspFr_local_reg(SUSP_FR), B_SIZE); \
memcpy(SuspFr_trail_start(SUSP_FR), SuspFr_trail_reg(SUSP_FR), TR_SIZE) memcpy(SuspFr_trail_start(SUSP_FR), SuspFr_trail_reg(SUSP_FR), TR_SIZE)
#define new_subgoal_trie_node(NODE, ENTRY, CHILD, PARENT, NEXT) \ #define new_subgoal_trie_node(NODE, ENTRY, CHILD, PARENT, NEXT) \
ALLOC_SUBGOAL_TRIE_NODE(NODE); \ ALLOC_SUBGOAL_TRIE_NODE(NODE); \
TrNode_entry(NODE) = ENTRY; \ TrNode_entry(NODE) = ENTRY; \
TrNode_init_lock_field(NODE); \
TrNode_child(NODE) = CHILD; \ TrNode_child(NODE) = CHILD; \
TrNode_parent(NODE) = PARENT; \ TrNode_parent(NODE) = PARENT; \
TrNode_next(NODE) = NEXT TrNode_next(NODE) = NEXT; \
SgNode_init_lock_field(NODE)
#define new_answer_trie_node(NODE, INSTR, ENTRY, CHILD, PARENT, NEXT) \ #define new_answer_trie_node(NODE, INSTR, ENTRY, CHILD, PARENT, NEXT) \
ALLOC_ANSWER_TRIE_NODE(NODE); \ ALLOC_ANSWER_TRIE_NODE(NODE); \
TrNode_instr(NODE) = INSTR; \ TrNode_instr(NODE) = INSTR; \
TrNode_entry(NODE) = ENTRY; \ TrNode_entry(NODE) = ENTRY; \
TrNode_init_lock_field(NODE); \
TrNode_child(NODE) = CHILD; \ TrNode_child(NODE) = CHILD; \
TrNode_parent(NODE) = PARENT; \ TrNode_parent(NODE) = PARENT; \
TrNode_next(NODE) = NEXT TrNode_next(NODE) = NEXT; \
AnsNode_init_lock_field(NODE)
#define new_global_trie_node(NODE, ENTRY, CHILD, PARENT, NEXT) \ #define new_global_trie_node(NODE, ENTRY, CHILD, PARENT, NEXT) \
ALLOC_GLOBAL_TRIE_NODE(NODE); \ ALLOC_GLOBAL_TRIE_NODE(NODE); \
TrNode_entry(NODE) = ENTRY; \ TrNode_entry(NODE) = ENTRY; \
TrNode_child(NODE) = CHILD; \ TrNode_child(NODE) = CHILD; \
TrNode_parent(NODE) = PARENT; \ TrNode_parent(NODE) = PARENT; \
TrNode_next(NODE) = NEXT TrNode_next(NODE) = NEXT; \
GtNode_init_lock_field(NODE)
#define new_subgoal_trie_hash(HASH, NUM_NODES, TAB_ENT) \ #define new_subgoal_trie_hash(HASH, NUM_NODES, TAB_ENT) \
ALLOC_SUBGOAL_TRIE_HASH(HASH); \ ALLOC_SUBGOAL_TRIE_HASH(HASH); \
@ -1009,13 +1057,8 @@ static inline void CUT_validate_tg_answers(tg_sol_fr_ptr valid_solutions) {
slots = TgAnsFr_free_slot(valid_answers); slots = TgAnsFr_free_slot(valid_answers);
do { do {
ans_node = TgAnsFr_answer(valid_answers, --slots); ans_node = TgAnsFr_answer(valid_answers, --slots);
#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) LOCK_ANSWER_TRIE(sg_fr);
LOCK(SgFr_lock(sg_fr)); LOCK_ANSWER_NODE(ans_node);
#elif defined(TABLE_LOCK_AT_NODE_LEVEL)
LOCK(TrNode_lock(ans_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
LOCK_TABLE(ans_node);
#endif /* TABLE_LOCK_LEVEL */
if (! IS_ANSWER_LEAF_NODE(ans_node)) { if (! IS_ANSWER_LEAF_NODE(ans_node)) {
TAG_AS_ANSWER_LEAF_NODE(ans_node); TAG_AS_ANSWER_LEAF_NODE(ans_node);
if (first_answer == NULL) if (first_answer == NULL)
@ -1024,13 +1067,8 @@ static inline void CUT_validate_tg_answers(tg_sol_fr_ptr valid_solutions) {
TrNode_child(last_answer) = ans_node; TrNode_child(last_answer) = ans_node;
last_answer = ans_node; last_answer = ans_node;
} }
#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) UNLOCK_ANSWER_NODE(ans_node);
UNLOCK(SgFr_lock(sg_fr)); UNLOCK_ANSWER_TRIE(sg_fr);
#elif defined(TABLE_LOCK_AT_NODE_LEVEL)
UNLOCK(TrNode_lock(ans_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
UNLOCK_TABLE(ans_node);
#endif /* TABLE_LOCK_LEVEL */
} while (slots); } while (slots);
free_answer = valid_answers; free_answer = valid_answers;
valid_answers = TgAnsFr_next(valid_answers); valid_answers = TgAnsFr_next(valid_answers);

View File

@ -58,9 +58,9 @@ typedef struct subgoal_trie_node {
struct subgoal_trie_node *parent; struct subgoal_trie_node *parent;
struct subgoal_trie_node *child; struct subgoal_trie_node *child;
struct subgoal_trie_node *next; struct subgoal_trie_node *next;
#ifdef TABLE_LOCK_AT_NODE_LEVEL #ifdef SUBGOAL_TRIE_LOCK_USING_NODE_FIELD
lockvar lock; lockvar lock;
#endif /* TABLE_LOCK_AT_NODE_LEVEL */ #endif /* SUBGOAL_TRIE_LOCK_USING_NODE_FIELD */
} *sg_node_ptr; } *sg_node_ptr;
typedef struct answer_trie_node { typedef struct answer_trie_node {
@ -72,9 +72,9 @@ typedef struct answer_trie_node {
struct answer_trie_node *parent; struct answer_trie_node *parent;
struct answer_trie_node *child; struct answer_trie_node *child;
struct answer_trie_node *next; struct answer_trie_node *next;
#ifdef TABLE_LOCK_AT_NODE_LEVEL #ifdef ANSWER_TRIE_LOCK_USING_NODE_FIELD
lockvar lock; lockvar lock;
#endif /* TABLE_LOCK_AT_NODE_LEVEL */ #endif /* ANSWER_TRIE_LOCK_USING_NODE_FIELD */
} *ans_node_ptr; } *ans_node_ptr;
typedef struct global_trie_node { typedef struct global_trie_node {
@ -82,9 +82,9 @@ typedef struct global_trie_node {
struct global_trie_node *parent; struct global_trie_node *parent;
struct global_trie_node *child; struct global_trie_node *child;
struct global_trie_node *next; struct global_trie_node *next;
#ifdef TABLE_LOCK_AT_NODE_LEVEL #ifdef GLOBAL_TRIE_LOCK_USING_NODE_FIELD
lockvar lock; lockvar lock;
#endif /* TABLE_LOCK_AT_NODE_LEVEL */ #endif /* GLOBAL_TRIE_LOCK_USING_NODE_FIELD */
} *gt_node_ptr; } *gt_node_ptr;
#define TrNode_instr(X) ((X)->trie_instruction) #define TrNode_instr(X) ((X)->trie_instruction)

View File

@ -32,10 +32,6 @@ static inline gt_node_ptr global_trie_check_insert_gt_entry(gt_node_ptr, Term);
static inline sg_node_ptr subgoal_search_loop(tab_ent_ptr, sg_node_ptr, Term, int *, CELL **); static inline sg_node_ptr subgoal_search_loop(tab_ent_ptr, sg_node_ptr, Term, int *, CELL **);
static inline sg_node_ptr subgoal_search_terms_loop(tab_ent_ptr, sg_node_ptr, Term, int *, CELL **); static inline sg_node_ptr subgoal_search_terms_loop(tab_ent_ptr, sg_node_ptr, Term, int *, CELL **);
static inline ans_node_ptr answer_search_loop(sg_fr_ptr, ans_node_ptr, Term, int *); static inline ans_node_ptr answer_search_loop(sg_fr_ptr, ans_node_ptr, Term, int *);
#ifdef MODE_DIRECTED_TABLING
static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr, ans_node_ptr, Term, int);
static void invalidate_answer_trie(ans_node_ptr, sg_fr_ptr, int);
#endif /* MODE_DIRECTED_TABLING */
static inline ans_node_ptr answer_search_terms_loop(sg_fr_ptr, ans_node_ptr, Term, int *); static inline ans_node_ptr answer_search_terms_loop(sg_fr_ptr, ans_node_ptr, Term, int *);
#ifdef GLOBAL_TRIE_FOR_SUBTERMS #ifdef GLOBAL_TRIE_FOR_SUBTERMS
static inline gt_node_ptr subgoal_search_global_trie_terms_loop(Term, int *, CELL **, CELL *); static inline gt_node_ptr subgoal_search_global_trie_terms_loop(Term, int *, CELL **, CELL *);
@ -158,7 +154,7 @@ static struct trie_statistics{
#undef MODE_GLOBAL_TRIE_ENTRY #undef MODE_GLOBAL_TRIE_ENTRY
#define INCLUDE_SUBGOAL_SEARCH_LOOP /* subgoal_search_loop */ #define INCLUDE_SUBGOAL_SEARCH_LOOP /* subgoal_search_loop */
#define INCLUDE_ANSWER_SEARCH_LOOP /* answer_search_loop + answer_search_mode_directed_min_max + invalidate_answer_trie */ #define INCLUDE_ANSWER_SEARCH_LOOP /* answer_search_loop */
#define INCLUDE_LOAD_ANSWER_LOOP /* load_answer_loop */ #define INCLUDE_LOAD_ANSWER_LOOP /* load_answer_loop */
#include "tab.tries.i" #include "tab.tries.i"
#undef INCLUDE_LOAD_ANSWER_LOOP #undef INCLUDE_LOAD_ANSWER_LOOP
@ -183,6 +179,13 @@ static struct trie_statistics{
#undef INCLUDE_SUBGOAL_SEARCH_LOOP #undef INCLUDE_SUBGOAL_SEARCH_LOOP
#undef MODE_GLOBAL_TRIE_LOOP #undef MODE_GLOBAL_TRIE_LOOP
#ifdef MODE_DIRECTED_TABLING
#define INCLUDE_ANSWER_SEARCH_MODE_DIRECTED
#include "tab.tries.i" /* answer_search_min_max + invalidate_answer_trie */
#undef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED
#endif /* MODE_DIRECTED_TABLING */
static inline CELL *exec_substitution_loop(gt_node_ptr current_node, CELL **stack_vars_ptr, CELL *stack_terms) { static inline CELL *exec_substitution_loop(gt_node_ptr current_node, CELL **stack_vars_ptr, CELL *stack_terms) {
/************************************************************************ /************************************************************************
@ -991,9 +994,7 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) {
pred_arity = preg->u.Otapl.s; pred_arity = preg->u.Otapl.s;
tab_ent = preg->u.Otapl.te; tab_ent = preg->u.Otapl.te;
current_sg_node = TabEnt_subgoal_trie(tab_ent); current_sg_node = TabEnt_subgoal_trie(tab_ent);
#ifdef TABLE_LOCK_AT_ENTRY_LEVEL LOCK_SUBGOAL_TRIE(tab_ent);
LOCK(TabEnt_lock(tab_ent));
#endif /* TABLE_LOCK_LEVEL */
#ifdef MODE_DIRECTED_TABLING #ifdef MODE_DIRECTED_TABLING
mode_directed = TabEnt_mode_directed(tab_ent); mode_directed = TabEnt_mode_directed(tab_ent);
@ -1031,12 +1032,8 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) {
Term t = STACK_POP_DOWN(stack_vars); Term t = STACK_POP_DOWN(stack_vars);
RESET_VARIABLE(t); RESET_VARIABLE(t);
} }
#if defined(TABLE_LOCK_AT_NODE_LEVEL) LOCK_SUBGOAL_NODE(current_sg_node);
LOCK(TrNode_lock(current_sg_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
LOCK_TABLE(current_sg_node);
#endif /* TABLE_LOCK_LEVEL */
if (TrNode_sg_fr(current_sg_node) == NULL) { if (TrNode_sg_fr(current_sg_node) == NULL) {
/* new tabled subgoal */ /* new tabled subgoal */
#ifdef MODE_DIRECTED_TABLING #ifdef MODE_DIRECTED_TABLING
@ -1057,13 +1054,8 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) {
} }
#endif /* LIMIT_TABLING */ #endif /* LIMIT_TABLING */
} }
#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) UNLOCK_SUBGOAL_NODE(current_sg_node);
UNLOCK(TabEnt_lock(tab_ent)); UNLOCK_SUBGOAL_TRIE(tab_ent);
#elif defined(TABLE_LOCK_AT_NODE_LEVEL)
UNLOCK(TrNode_lock(current_sg_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
UNLOCK_TABLE(current_sg_node);
#endif /* TABLE_LOCK_LEVEL */
return sg_fr; return sg_fr;
} }
@ -1074,83 +1066,9 @@ ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) {
CELL *stack_vars; CELL *stack_vars;
int i, vars_arity; int i, vars_arity;
ans_node_ptr current_ans_node; ans_node_ptr current_ans_node;
#ifdef MODE_DIRECTED_TABLING
int *mode_directed;
#endif /* MODE_DIRECTED_TABLING */
vars_arity = 0; vars_arity = 0;
current_ans_node = SgFr_answer_trie(sg_fr); current_ans_node = SgFr_answer_trie(sg_fr);
#ifdef MODE_DIRECTED_TABLING
mode_directed = SgFr_mode_directed(sg_fr);
if (mode_directed) {
ans_node_ptr invalid_ans_node = NULL;
int i = subs_arity, j = 0;
while (i) {
int mode = MODE_DIRECTED_GET_MODE(mode_directed[j]);
int n_subs = MODE_DIRECTED_GET_ARG(mode_directed[j]);
do {
TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i]));
if (mode == MODE_DIRECTED_INDEX || mode == MODE_DIRECTED_ALL)
current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity);
else {
#if defined(TABLE_LOCK_AT_NODE_LEVEL)
LOCK(TrNode_lock(current_ans_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
LOCK_TABLE(current_ans_node);
#endif /* TABLE_LOCK_LEVEL */
if (TrNode_child(current_ans_node) == NULL) {
#ifdef YAPOR
struct answer_trie_node virtual_ans_node;
ans_node_ptr parent_ans_node = current_ans_node;
TrNode_init_lock_field(&virtual_ans_node);
TrNode_parent(&virtual_ans_node) = NULL;
TrNode_child(&virtual_ans_node) = NULL;
current_ans_node = answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]), &vars_arity);
TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node);
#else
current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity);
#endif /* YAPOR */
} else if (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX) {
ans_node_ptr parent_ans_node = current_ans_node;
invalid_ans_node = TrNode_child(parent_ans_node); /* by default, assume a better answer */
current_ans_node = answer_search_mode_directed_min_max(sg_fr, current_ans_node, Deref(subs_ptr[i]), mode);
if (invalid_ans_node == TrNode_child(parent_ans_node)) /* worse or equal answer */
invalid_ans_node = NULL;
} else if (mode == MODE_DIRECTED_FIRST)
current_ans_node = NULL;
else { /* mode == MODE_DIRECTED_LAST */
#ifdef YAPOR
struct answer_trie_node virtual_ans_node;
ans_node_ptr parent_ans_node = current_ans_node;
invalid_ans_node = TrNode_child(parent_ans_node);
TrNode_init_lock_field(&virtual_ans_node);
TrNode_parent(&virtual_ans_node) = NULL;
TrNode_child(&virtual_ans_node) = NULL;
current_ans_node = answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]), &vars_arity);
TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node);
#else
invalid_ans_node = TrNode_child(current_ans_node);
TrNode_child(current_ans_node) = NULL;
current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity);
#endif /* YAPOR */
}
#if defined(TABLE_LOCK_AT_NODE_LEVEL)
UNLOCK(TrNode_lock(current_ans_node));
#elif defined(TABLE_LOCK_AT_WRITE_LEVEL)
UNLOCK_TABLE(current_ans_node);
#endif /* TABLE_LOCK_LEVEL */
}
n_subs--;
i--;
} while (n_subs && current_ans_node);
if (current_ans_node == NULL) /* no answer inserted */
break;
j++;
}
if (invalid_ans_node)
invalidate_answer_trie(invalid_ans_node, sg_fr, TRAVERSE_POSITION_FIRST);
} else
#endif /* MODE_DIRECTED_TABLING */
if (IsMode_GlobalTrie(TabEnt_mode(SgFr_tab_ent(sg_fr)))) { if (IsMode_GlobalTrie(TabEnt_mode(SgFr_tab_ent(sg_fr)))) {
for (i = subs_arity; i >= 1; i--) { for (i = subs_arity; i >= 1; i--) {
TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i])); TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i]));
@ -1175,6 +1093,91 @@ ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) {
} }
#ifdef MODE_DIRECTED_TABLING
ans_node_ptr mode_directed_answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) {
#define subs_arity *subs_ptr
CACHE_REGS
CELL *stack_vars;
int i, j, vars_arity;
ans_node_ptr current_ans_node, invalid_ans_node;
int *mode_directed;
vars_arity = 0;
current_ans_node = SgFr_answer_trie(sg_fr);
invalid_ans_node = NULL;
mode_directed = SgFr_mode_directed(sg_fr);
j = 0;
i = subs_arity;
while (i) {
int mode = MODE_DIRECTED_GET_MODE(mode_directed[j]);
int n_subs = MODE_DIRECTED_GET_ARG(mode_directed[j]);
do {
TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i]));
if (mode == MODE_DIRECTED_INDEX || mode == MODE_DIRECTED_ALL) {
current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity);
} else {
LOCK_ANSWER_NODE(current_ans_node);
if (TrNode_child(current_ans_node) == NULL) {
#ifdef YAPOR
struct answer_trie_node virtual_ans_node;
ans_node_ptr parent_ans_node = current_ans_node;
TrNode_init_lock_field(&virtual_ans_node);
TrNode_parent(&virtual_ans_node) = NULL;
TrNode_child(&virtual_ans_node) = NULL;
current_ans_node = answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]), &vars_arity);
TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node);
#else
current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity);
#endif /* YAPOR */
} else if (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX) {
ans_node_ptr parent_ans_node = current_ans_node;
invalid_ans_node = TrNode_child(parent_ans_node); /* by default, assume a better answer */
current_ans_node = answer_search_min_max(sg_fr, current_ans_node, Deref(subs_ptr[i]), mode);
if (invalid_ans_node == TrNode_child(parent_ans_node)) /* worse or equal answer */
invalid_ans_node = NULL;
} else if (mode == MODE_DIRECTED_FIRST)
current_ans_node = NULL;
else { /* mode == MODE_DIRECTED_LAST */
#ifdef YAPOR
struct answer_trie_node virtual_ans_node;
ans_node_ptr parent_ans_node = current_ans_node;
invalid_ans_node = TrNode_child(parent_ans_node);
TrNode_init_lock_field(&virtual_ans_node);
TrNode_parent(&virtual_ans_node) = NULL;
TrNode_child(&virtual_ans_node) = NULL;
current_ans_node = answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]), &vars_arity);
TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node);
#else
invalid_ans_node = TrNode_child(current_ans_node);
TrNode_child(current_ans_node) = NULL;
current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity);
#endif /* YAPOR */
}
UNLOCK_ANSWER_NODE(current_ans_node);
}
n_subs--;
i--;
} while (n_subs && current_ans_node);
if (current_ans_node == NULL) /* no answer inserted */
break;
j++;
}
if (invalid_ans_node)
invalidate_answer_trie(invalid_ans_node, sg_fr, TRAVERSE_POSITION_FIRST);
/* reset variables */
stack_vars = (CELL *) TR;
while (vars_arity--) {
Term t = STACK_POP_DOWN(stack_vars);
RESET_VARIABLE(t);
}
return current_ans_node;
#undef subs_arity
}
#endif /* MODE_DIRECTED_TABLING */
void load_answer(ans_node_ptr current_ans_node, CELL *subs_ptr) { void load_answer(ans_node_ptr current_ans_node, CELL *subs_ptr) {
CACHE_REGS CACHE_REGS
#define subs_arity *subs_ptr #define subs_arity *subs_ptr

View File

@ -52,25 +52,13 @@
#endif /* MODE_GLOBAL_TRIE_LOOP */ #endif /* MODE_GLOBAL_TRIE_LOOP */
#if defined(TABLE_LOCK_AT_WRITE_LEVEL)
#define LOCK_NODE(NODE) LOCK_TABLE(NODE)
#define UNLOCK_NODE(NODE) UNLOCK_TABLE(NODE)
#elif defined(TABLE_LOCK_AT_NODE_LEVEL)
#define LOCK_NODE(NODE) LOCK(TrNode_lock(NODE))
#define UNLOCK_NODE(NODE) UNLOCK(TrNode_lock(NODE))
#else /* TABLE_LOCK_AT_ENTRY_LEVEL || ! YAPOR */
#define LOCK_NODE(NODE)
#define UNLOCK_NODE(NODE)
#endif /* TABLE_LOCK_LEVEL */
/************************************************************************ /************************************************************************
** subgoal_trie_check_insert_(gt)_entry ** ** subgoal_trie_check_insert_(gt)_entry **
************************************************************************/ ************************************************************************/
#ifdef INCLUDE_SUBGOAL_TRIE_CHECK_INSERT #ifdef INCLUDE_SUBGOAL_TRIE_CHECK_INSERT
#ifndef TABLE_LOCK_AT_WRITE_LEVEL /* TABLE_LOCK_AT_ENTRY_LEVEL || TABLE_LOCK_AT_NODE_LEVEL || ! YAPOR */ #ifndef SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL /* SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL || SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL || ! YAPOR */
#ifdef MODE_GLOBAL_TRIE_ENTRY #ifdef MODE_GLOBAL_TRIE_ENTRY
static inline sg_node_ptr subgoal_trie_check_insert_gt_entry(tab_ent_ptr tab_ent, sg_node_ptr parent_node, Term t) { static inline sg_node_ptr subgoal_trie_check_insert_gt_entry(tab_ent_ptr tab_ent, sg_node_ptr parent_node, Term t) {
#else #else
@ -78,12 +66,12 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s
#endif /* MODE_GLOBAL_TRIE_ENTRY */ #endif /* MODE_GLOBAL_TRIE_ENTRY */
sg_node_ptr child_node; sg_node_ptr child_node;
LOCK_NODE(parent_node); LOCK_SUBGOAL_NODE(parent_node);
child_node = TrNode_child(parent_node); child_node = TrNode_child(parent_node);
if (child_node == NULL) { if (child_node == NULL) {
NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL); NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL);
TrNode_child(parent_node) = child_node; TrNode_child(parent_node) = child_node;
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
return child_node; return child_node;
} }
@ -91,7 +79,7 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s
int count_nodes = 0; int count_nodes = 0;
do { do {
if (TrNode_entry(child_node) == t) { if (TrNode_entry(child_node) == t) {
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
return child_node; return child_node;
} }
count_nodes++; count_nodes++;
@ -116,7 +104,7 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s
} else { } else {
TrNode_child(parent_node) = child_node; TrNode_child(parent_node) = child_node;
} }
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
return child_node; return child_node;
} }
@ -129,7 +117,7 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s
child_node = *bucket; child_node = *bucket;
while (child_node) { while (child_node) {
if (TrNode_entry(child_node) == t) { if (TrNode_entry(child_node) == t) {
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
return child_node; return child_node;
} }
count_nodes++; count_nodes++;
@ -162,11 +150,11 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s
} while (old_bucket != first_old_bucket); } while (old_bucket != first_old_bucket);
FREE_HASH_BUCKETS(first_old_bucket); FREE_HASH_BUCKETS(first_old_bucket);
} }
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
return child_node; return child_node;
} }
} }
#else /* TABLE_LOCK_AT_WRITE_LEVEL */ #else /* SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL */
#ifdef MODE_GLOBAL_TRIE_ENTRY #ifdef MODE_GLOBAL_TRIE_ENTRY
static inline sg_node_ptr subgoal_trie_check_insert_gt_entry(tab_ent_ptr tab_ent, sg_node_ptr parent_node, Term t) { static inline sg_node_ptr subgoal_trie_check_insert_gt_entry(tab_ent_ptr tab_ent, sg_node_ptr parent_node, Term t) {
#else #else
@ -177,40 +165,40 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s
child_node = TrNode_child(parent_node); child_node = TrNode_child(parent_node);
if (child_node == NULL) { if (child_node == NULL) {
#ifdef ALLOC_BEFORE_CHECK #ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL); NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
LOCK_NODE(parent_node); LOCK_SUBGOAL_NODE(parent_node);
if (TrNode_child(parent_node)) { if (TrNode_child(parent_node)) {
sg_node_ptr chain_node = TrNode_child(parent_node); sg_node_ptr chain_node = TrNode_child(parent_node);
if (IS_SUBGOAL_TRIE_HASH(chain_node)) { if (IS_SUBGOAL_TRIE_HASH(chain_node)) {
#ifdef ALLOC_BEFORE_CHECK #ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
FREE_SUBGOAL_TRIE_NODE(child_node); FREE_SUBGOAL_TRIE_NODE(child_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
hash = (sg_hash_ptr) chain_node; hash = (sg_hash_ptr) chain_node;
goto subgoal_trie_hash; goto subgoal_trie_hash;
} }
do { do {
if (TrNode_entry(chain_node) == t) { if (TrNode_entry(chain_node) == t) {
#ifdef ALLOC_BEFORE_CHECK #ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
FREE_SUBGOAL_TRIE_NODE(child_node); FREE_SUBGOAL_TRIE_NODE(child_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
return chain_node; return chain_node;
} }
chain_node = TrNode_next(chain_node); chain_node = TrNode_next(chain_node);
} while (chain_node); } while (chain_node);
#ifdef ALLOC_BEFORE_CHECK #ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
TrNode_next(child_node) = TrNode_child(parent_node); TrNode_next(child_node) = TrNode_child(parent_node);
#else #else
NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, TrNode_child(parent_node)); NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, TrNode_child(parent_node));
} else { } else {
NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL); NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
} }
TrNode_child(parent_node) = child_node; TrNode_child(parent_node) = child_node;
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
return child_node; return child_node;
} }
@ -218,44 +206,43 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s
sg_node_ptr first_node = child_node; sg_node_ptr first_node = child_node;
int count_nodes = 0; int count_nodes = 0;
do { do {
if (TrNode_entry(child_node) == t) { if (TrNode_entry(child_node) == t)
return child_node; return child_node;
}
count_nodes++; count_nodes++;
child_node = TrNode_next(child_node); child_node = TrNode_next(child_node);
} while (child_node); } while (child_node);
#ifdef ALLOC_BEFORE_CHECK #ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
LOCK_NODE(parent_node); LOCK_SUBGOAL_NODE(parent_node);
if (first_node != TrNode_child(parent_node)) { if (first_node != TrNode_child(parent_node)) {
sg_node_ptr chain_node = TrNode_child(parent_node); sg_node_ptr chain_node = TrNode_child(parent_node);
if (IS_SUBGOAL_TRIE_HASH(chain_node)) { if (IS_SUBGOAL_TRIE_HASH(chain_node)) {
#ifdef ALLOC_BEFORE_CHECK #ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
FREE_SUBGOAL_TRIE_NODE(child_node); FREE_SUBGOAL_TRIE_NODE(child_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
hash = (sg_hash_ptr) chain_node; hash = (sg_hash_ptr) chain_node;
goto subgoal_trie_hash; goto subgoal_trie_hash;
} }
do { do {
if (TrNode_entry(chain_node) == t) { if (TrNode_entry(chain_node) == t) {
#ifdef ALLOC_BEFORE_CHECK #ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
FREE_SUBGOAL_TRIE_NODE(child_node); FREE_SUBGOAL_TRIE_NODE(child_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
return chain_node; return chain_node;
} }
count_nodes++; count_nodes++;
chain_node = TrNode_next(chain_node); chain_node = TrNode_next(chain_node);
} while (chain_node != first_node); } while (chain_node != first_node);
#ifdef ALLOC_BEFORE_CHECK #ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
TrNode_next(child_node) = TrNode_child(parent_node); TrNode_next(child_node) = TrNode_child(parent_node);
#else #else
NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, TrNode_child(parent_node)); NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, TrNode_child(parent_node));
} else { } else {
NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
} }
count_nodes++; count_nodes++;
if (count_nodes >= MAX_NODES_PER_TRIE_LEVEL) { if (count_nodes >= MAX_NODES_PER_TRIE_LEVEL) {
@ -274,7 +261,7 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s
} else { } else {
TrNode_child(parent_node) = child_node; TrNode_child(parent_node) = child_node;
} }
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
return child_node; return child_node;
} }
@ -288,44 +275,43 @@ subgoal_trie_hash:
bucket = Hash_bucket(hash, HASH_ENTRY(t, seed)); bucket = Hash_bucket(hash, HASH_ENTRY(t, seed));
first_node = child_node = *bucket; first_node = child_node = *bucket;
while (child_node) { while (child_node) {
if (TrNode_entry(child_node) == t) { if (TrNode_entry(child_node) == t)
return child_node; return child_node;
}
count_nodes++; count_nodes++;
child_node = TrNode_next(child_node); child_node = TrNode_next(child_node);
} }
#ifdef ALLOC_BEFORE_CHECK #ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
LOCK_NODE(parent_node); LOCK_SUBGOAL_NODE(parent_node);
if (seed != Hash_seed(hash)) { if (seed != Hash_seed(hash)) {
/* the hash has been expanded */ /* the hash has been expanded */
#ifdef ALLOC_BEFORE_CHECK #ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
FREE_SUBGOAL_TRIE_NODE(child_node); FREE_SUBGOAL_TRIE_NODE(child_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
goto subgoal_trie_hash; goto subgoal_trie_hash;
} }
if (first_node != *bucket) { if (first_node != *bucket) {
sg_node_ptr chain_node = *bucket; sg_node_ptr chain_node = *bucket;
do { do {
if (TrNode_entry(chain_node) == t) { if (TrNode_entry(chain_node) == t) {
#ifdef ALLOC_BEFORE_CHECK #ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
FREE_SUBGOAL_TRIE_NODE(child_node); FREE_SUBGOAL_TRIE_NODE(child_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
return chain_node; return chain_node;
} }
count_nodes++; count_nodes++;
chain_node = TrNode_next(chain_node); chain_node = TrNode_next(chain_node);
} while (chain_node != first_node); } while (chain_node != first_node);
#ifdef ALLOC_BEFORE_CHECK #ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK
TrNode_next(child_node) = *bucket; TrNode_next(child_node) = *bucket;
#else #else
NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, *bucket); NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, *bucket);
} else { } else {
NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */
} }
*bucket = child_node; *bucket = child_node;
Hash_num_nodes(hash)++; Hash_num_nodes(hash)++;
@ -352,11 +338,11 @@ subgoal_trie_hash:
} while (old_bucket != first_old_bucket); } while (old_bucket != first_old_bucket);
FREE_HASH_BUCKETS(first_old_bucket); FREE_HASH_BUCKETS(first_old_bucket);
} }
UNLOCK_NODE(parent_node); UNLOCK_SUBGOAL_NODE(parent_node);
return child_node; return child_node;
} }
} }
#endif /* TABLE_LOCK_LEVEL */ #endif /* SUBGOAL_TRIE_LOCK_LEVEL */
#endif /* INCLUDE_SUBGOAL_TRIE_CHECK_INSERT */ #endif /* INCLUDE_SUBGOAL_TRIE_CHECK_INSERT */
@ -366,7 +352,7 @@ subgoal_trie_hash:
************************************************************************/ ************************************************************************/
#ifdef INCLUDE_ANSWER_TRIE_CHECK_INSERT #ifdef INCLUDE_ANSWER_TRIE_CHECK_INSERT
#ifndef TABLE_LOCK_AT_WRITE_LEVEL /* TABLE_LOCK_AT_ENTRY_LEVEL || TABLE_LOCK_AT_NODE_LEVEL || ! YAPOR */ #ifndef ANSWER_TRIE_LOCK_AT_WRITE_LEVEL /* ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL || ANSWER_TRIE_LOCK_AT_NODE_LEVEL || ! YAPOR */
#ifdef MODE_GLOBAL_TRIE_ENTRY #ifdef MODE_GLOBAL_TRIE_ENTRY
static inline ans_node_ptr answer_trie_check_insert_gt_entry(sg_fr_ptr sg_fr, ans_node_ptr parent_node, Term t, int instr) { static inline ans_node_ptr answer_trie_check_insert_gt_entry(sg_fr_ptr sg_fr, ans_node_ptr parent_node, Term t, int instr) {
#else #else
@ -375,12 +361,12 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n
ans_node_ptr child_node; ans_node_ptr child_node;
TABLING_ERROR_CHECKING(answer_trie_check_insert_(gt)_entry, IS_ANSWER_LEAF_NODE(parent_node)); TABLING_ERROR_CHECKING(answer_trie_check_insert_(gt)_entry, IS_ANSWER_LEAF_NODE(parent_node));
LOCK_NODE(parent_node); LOCK_ANSWER_NODE(parent_node);
child_node = TrNode_child(parent_node); child_node = TrNode_child(parent_node);
if (child_node == NULL) { if (child_node == NULL) {
NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, NULL); NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, NULL);
TrNode_child(parent_node) = child_node; TrNode_child(parent_node) = child_node;
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
return child_node; return child_node;
} }
@ -388,7 +374,7 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n
int count_nodes = 0; int count_nodes = 0;
do { do {
if (TrNode_entry(child_node) == t) { if (TrNode_entry(child_node) == t) {
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
return child_node; return child_node;
} }
count_nodes++; count_nodes++;
@ -413,7 +399,7 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n
} else { } else {
TrNode_child(parent_node) = child_node; TrNode_child(parent_node) = child_node;
} }
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
return child_node; return child_node;
} }
@ -426,7 +412,7 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n
child_node = *bucket; child_node = *bucket;
while (child_node) { while (child_node) {
if (TrNode_entry(child_node) == t) { if (TrNode_entry(child_node) == t) {
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
return child_node; return child_node;
} }
count_nodes++; count_nodes++;
@ -459,11 +445,11 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n
} while (old_bucket != first_old_bucket); } while (old_bucket != first_old_bucket);
FREE_HASH_BUCKETS(first_old_bucket); FREE_HASH_BUCKETS(first_old_bucket);
} }
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
return child_node; return child_node;
} }
} }
#else #else /* ANSWER_TRIE_LOCK_AT_WRITE_LEVEL */
#ifdef MODE_GLOBAL_TRIE_ENTRY #ifdef MODE_GLOBAL_TRIE_ENTRY
static inline ans_node_ptr answer_trie_check_insert_gt_entry(sg_fr_ptr sg_fr, ans_node_ptr parent_node, Term t, int instr) { static inline ans_node_ptr answer_trie_check_insert_gt_entry(sg_fr_ptr sg_fr, ans_node_ptr parent_node, Term t, int instr) {
#else #else
@ -475,40 +461,40 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n
TABLING_ERROR_CHECKING(answer_trie_check_insert_(gt)_entry, IS_ANSWER_LEAF_NODE(parent_node)); TABLING_ERROR_CHECKING(answer_trie_check_insert_(gt)_entry, IS_ANSWER_LEAF_NODE(parent_node));
child_node = TrNode_child(parent_node); child_node = TrNode_child(parent_node);
if (child_node == NULL) { if (child_node == NULL) {
#ifdef ALLOC_BEFORE_CHECK #ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, NULL); NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, NULL);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
LOCK_NODE(parent_node); LOCK_ANSWER_NODE(parent_node);
if (TrNode_child(parent_node)) { if (TrNode_child(parent_node)) {
ans_node_ptr chain_node = TrNode_child(parent_node); ans_node_ptr chain_node = TrNode_child(parent_node);
if (IS_ANSWER_TRIE_HASH(chain_node)) { if (IS_ANSWER_TRIE_HASH(chain_node)) {
#ifdef ALLOC_BEFORE_CHECK #ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
FREE_ANSWER_TRIE_NODE(child_node); FREE_ANSWER_TRIE_NODE(child_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
hash = (ans_hash_ptr) chain_node; hash = (ans_hash_ptr) chain_node;
goto answer_trie_hash; goto answer_trie_hash;
} }
do { do {
if (TrNode_entry(chain_node) == t) { if (TrNode_entry(chain_node) == t) {
#ifdef ALLOC_BEFORE_CHECK #ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
FREE_ANSWER_TRIE_NODE(child_node); FREE_ANSWER_TRIE_NODE(child_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
return chain_node; return chain_node;
} }
chain_node = TrNode_next(chain_node); chain_node = TrNode_next(chain_node);
} while (chain_node); } while (chain_node);
#ifdef ALLOC_BEFORE_CHECK #ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
TrNode_next(child_node) = TrNode_child(parent_node); TrNode_next(child_node) = TrNode_child(parent_node);
#else #else
NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, TrNode_child(parent_node)); NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, TrNode_child(parent_node));
} else { } else {
NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, NULL); NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, NULL);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
} }
TrNode_child(parent_node) = child_node; TrNode_child(parent_node) = child_node;
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
return child_node; return child_node;
} }
@ -516,44 +502,43 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n
ans_node_ptr first_node = child_node; ans_node_ptr first_node = child_node;
int count_nodes = 0; int count_nodes = 0;
do { do {
if (TrNode_entry(child_node) == t) { if (TrNode_entry(child_node) == t)
return child_node; return child_node;
}
count_nodes++; count_nodes++;
child_node = TrNode_next(child_node); child_node = TrNode_next(child_node);
} while (child_node); } while (child_node);
#ifdef ALLOC_BEFORE_CHECK #ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, first_node); NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, first_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
LOCK_NODE(parent_node); LOCK_ANSWER_NODE(parent_node);
if (first_node != TrNode_child(parent_node)) { if (first_node != TrNode_child(parent_node)) {
ans_node_ptr chain_node = TrNode_child(parent_node); ans_node_ptr chain_node = TrNode_child(parent_node);
if (IS_ANSWER_TRIE_HASH(chain_node)) { if (IS_ANSWER_TRIE_HASH(chain_node)) {
#ifdef ALLOC_BEFORE_CHECK #ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
FREE_ANSWER_TRIE_NODE(child_node); FREE_ANSWER_TRIE_NODE(child_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
hash = (ans_hash_ptr) chain_node; hash = (ans_hash_ptr) chain_node;
goto answer_trie_hash; goto answer_trie_hash;
} }
do { do {
if (TrNode_entry(chain_node) == t) { if (TrNode_entry(chain_node) == t) {
#ifdef ALLOC_BEFORE_CHECK #ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
FREE_ANSWER_TRIE_NODE(child_node); FREE_ANSWER_TRIE_NODE(child_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
return chain_node; return chain_node;
} }
count_nodes++; count_nodes++;
chain_node = TrNode_next(chain_node); chain_node = TrNode_next(chain_node);
} while (chain_node != first_node); } while (chain_node != first_node);
#ifdef ALLOC_BEFORE_CHECK #ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
TrNode_next(child_node) = TrNode_child(parent_node); TrNode_next(child_node) = TrNode_child(parent_node);
#else #else
NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, TrNode_child(parent_node)); NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, TrNode_child(parent_node));
} else { } else {
NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, first_node); NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, first_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
} }
count_nodes++; count_nodes++;
if (count_nodes >= MAX_NODES_PER_TRIE_LEVEL) { if (count_nodes >= MAX_NODES_PER_TRIE_LEVEL) {
@ -572,7 +557,7 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n
} else { } else {
TrNode_child(parent_node) = child_node; TrNode_child(parent_node) = child_node;
} }
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
return child_node; return child_node;
} }
@ -586,44 +571,43 @@ answer_trie_hash:
bucket = Hash_bucket(hash, HASH_ENTRY(t, seed)); bucket = Hash_bucket(hash, HASH_ENTRY(t, seed));
first_node = child_node = *bucket; first_node = child_node = *bucket;
while (child_node) { while (child_node) {
if (TrNode_entry(child_node) == t) { if (TrNode_entry(child_node) == t)
return child_node; return child_node;
}
count_nodes++; count_nodes++;
child_node = TrNode_next(child_node); child_node = TrNode_next(child_node);
} }
#ifdef ALLOC_BEFORE_CHECK #ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, first_node); NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, first_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
LOCK_NODE(parent_node); LOCK_ANSWER_NODE(parent_node);
if (seed != Hash_seed(hash)) { if (seed != Hash_seed(hash)) {
/* the hash has been expanded */ /* the hash has been expanded */
#ifdef ALLOC_BEFORE_CHECK #ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
FREE_ANSWER_TRIE_NODE(child_node); FREE_ANSWER_TRIE_NODE(child_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
goto answer_trie_hash; goto answer_trie_hash;
} }
if (first_node != *bucket) { if (first_node != *bucket) {
ans_node_ptr chain_node = *bucket; ans_node_ptr chain_node = *bucket;
do { do {
if (TrNode_entry(chain_node) == t) { if (TrNode_entry(chain_node) == t) {
#ifdef ALLOC_BEFORE_CHECK #ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
FREE_ANSWER_TRIE_NODE(child_node); FREE_ANSWER_TRIE_NODE(child_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
return chain_node; return chain_node;
} }
count_nodes++; count_nodes++;
chain_node = TrNode_next(chain_node); chain_node = TrNode_next(chain_node);
} while (chain_node != first_node); } while (chain_node != first_node);
#ifdef ALLOC_BEFORE_CHECK #ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK
TrNode_next(child_node) = *bucket; TrNode_next(child_node) = *bucket;
#else #else
NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, *bucket); NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, *bucket);
} else { } else {
NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, first_node); NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, first_node);
#endif /* ALLOC_BEFORE_CHECK */ #endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */
} }
*bucket = child_node; *bucket = child_node;
Hash_num_nodes(hash)++; Hash_num_nodes(hash)++;
@ -650,11 +634,11 @@ answer_trie_hash:
} while (old_bucket != first_old_bucket); } while (old_bucket != first_old_bucket);
FREE_HASH_BUCKETS(first_old_bucket); FREE_HASH_BUCKETS(first_old_bucket);
} }
UNLOCK_NODE(parent_node); UNLOCK_ANSWER_NODE(parent_node);
return child_node; return child_node;
} }
} }
#endif /* TABLE_LOCK_LEVEL */ #endif /* ANSWER_TRIE_LOCK_LEVEL */
#endif /* INCLUDE_ANSWER_TRIE_CHECK_INSERT */ #endif /* INCLUDE_ANSWER_TRIE_CHECK_INSERT */
@ -664,6 +648,7 @@ answer_trie_hash:
************************************************************************/ ************************************************************************/
#ifdef INCLUDE_GLOBAL_TRIE_CHECK_INSERT #ifdef INCLUDE_GLOBAL_TRIE_CHECK_INSERT
#ifndef GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL /* GLOBAL_TRIE_LOCK_AT_NODE_LEVEL || ! YAPOR */
#ifdef MODE_GLOBAL_TRIE_ENTRY #ifdef MODE_GLOBAL_TRIE_ENTRY
static inline gt_node_ptr global_trie_check_insert_gt_entry(gt_node_ptr parent_node, Term t) { static inline gt_node_ptr global_trie_check_insert_gt_entry(gt_node_ptr parent_node, Term t) {
#else #else
@ -671,12 +656,12 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node
#endif /* MODE_GLOBAL_TRIE_ENTRY */ #endif /* MODE_GLOBAL_TRIE_ENTRY */
gt_node_ptr child_node; gt_node_ptr child_node;
LOCK_NODE(parent_node); LOCK_GLOBAL_NODE(parent_node);
child_node = TrNode_child(parent_node); child_node = TrNode_child(parent_node);
if (child_node == NULL) { if (child_node == NULL) {
NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL); NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL);
TrNode_child(parent_node) = child_node; TrNode_child(parent_node) = child_node;
UNLOCK_NODE(parent_node); UNLOCK_GLOBAL_NODE(parent_node);
return child_node; return child_node;
} }
@ -684,7 +669,7 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node
int count_nodes = 0; int count_nodes = 0;
do { do {
if (TrNode_entry(child_node) == t) { if (TrNode_entry(child_node) == t) {
UNLOCK_NODE(parent_node); UNLOCK_GLOBAL_NODE(parent_node);
return child_node; return child_node;
} }
count_nodes++; count_nodes++;
@ -709,7 +694,7 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node
} else { } else {
TrNode_child(parent_node) = child_node; TrNode_child(parent_node) = child_node;
} }
UNLOCK_NODE(parent_node); UNLOCK_GLOBAL_NODE(parent_node);
return child_node; return child_node;
} }
@ -722,7 +707,7 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node
child_node = *bucket; child_node = *bucket;
while (child_node) { while (child_node) {
if (TrNode_entry(child_node) == t) { if (TrNode_entry(child_node) == t) {
UNLOCK_NODE(parent_node); UNLOCK_GLOBAL_NODE(parent_node);
return child_node; return child_node;
} }
count_nodes++; count_nodes++;
@ -755,10 +740,199 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node
} while (old_bucket != first_old_bucket); } while (old_bucket != first_old_bucket);
FREE_HASH_BUCKETS(first_old_bucket); FREE_HASH_BUCKETS(first_old_bucket);
} }
UNLOCK_NODE(parent_node); UNLOCK_GLOBAL_NODE(parent_node);
return child_node; return child_node;
} }
} }
#else /* GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL */
#ifdef MODE_GLOBAL_TRIE_ENTRY
static inline gt_node_ptr global_trie_check_insert_gt_entry(gt_node_ptr parent_node, Term t) {
#else
static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node, Term t) {
#endif /* MODE_GLOBAL_TRIE_ENTRY */
gt_node_ptr child_node;
gt_hash_ptr hash;
child_node = TrNode_child(parent_node);
if (child_node == NULL) {
#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL);
#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
LOCK_GLOBAL_NODE(parent_node);
if (TrNode_child(parent_node)) {
gt_node_ptr chain_node = TrNode_child(parent_node);
if (IS_GLOBAL_TRIE_HASH(chain_node)) {
#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
FREE_GLOBAL_TRIE_NODE(child_node);
#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_GLOBAL_NODE(parent_node);
hash = (gt_hash_ptr) chain_node;
goto global_trie_hash;
}
do {
if (TrNode_entry(chain_node) == t) {
#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
FREE_GLOBAL_TRIE_NODE(child_node);
#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_GLOBAL_NODE(parent_node);
return chain_node;
}
chain_node = TrNode_next(chain_node);
} while (chain_node);
#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
TrNode_next(child_node) = TrNode_child(parent_node);
#else
NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, TrNode_child(parent_node));
} else {
NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL);
#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
}
TrNode_child(parent_node) = child_node;
UNLOCK_GLOBAL_NODE(parent_node);
return child_node;
}
if (! IS_GLOBAL_TRIE_HASH(child_node)) {
gt_node_ptr first_node = child_node;
int count_nodes = 0;
do {
if (TrNode_entry(child_node) == t)
return child_node;
count_nodes++;
child_node = TrNode_next(child_node);
} while (child_node);
#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node);
#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
LOCK_GLOBAL_NODE(parent_node);
if (first_node != TrNode_child(parent_node)) {
gt_node_ptr chain_node = TrNode_child(parent_node);
if (IS_GLOBAL_TRIE_HASH(chain_node)) {
#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
FREE_GLOBAL_TRIE_NODE(child_node);
#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_GLOBAL_NODE(parent_node);
hash = (gt_hash_ptr) chain_node;
goto global_trie_hash;
}
do {
if (TrNode_entry(chain_node) == t) {
#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
FREE_GLOBAL_TRIE_NODE(child_node);
#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_GLOBAL_NODE(parent_node);
return chain_node;
}
count_nodes++;
chain_node = TrNode_next(chain_node);
} while (chain_node != first_node);
#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
TrNode_next(child_node) = TrNode_child(parent_node);
#else
NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, TrNode_child(parent_node));
} else {
NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node);
#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
}
count_nodes++;
if (count_nodes >= MAX_NODES_PER_TRIE_LEVEL) {
/* alloc a new hash */
gt_node_ptr chain_node, next_node, *bucket;
new_answer_trie_hash(hash, count_nodes, sg_fr);
chain_node = child_node;
do {
bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS - 1));
next_node = TrNode_next(chain_node);
TrNode_next(chain_node) = *bucket;
*bucket = chain_node;
chain_node = next_node;
} while (chain_node);
TrNode_child(parent_node) = (gt_node_ptr) hash;
} else {
TrNode_child(parent_node) = child_node;
}
UNLOCK_GLOBAL_NODE(parent_node);
return child_node;
}
hash = (gt_hash_ptr) child_node;
global_trie_hash:
{ /* trie nodes with hashing */
gt_node_ptr *bucket, first_node;
int seed, count_nodes = 0;
seed = Hash_seed(hash);
bucket = Hash_bucket(hash, HASH_ENTRY(t, seed));
first_node = child_node = *bucket;
while (child_node) {
if (TrNode_entry(child_node) == t)
return child_node;
count_nodes++;
child_node = TrNode_next(child_node);
}
#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node);
#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
LOCK_GLOBAL_NODE(parent_node);
if (seed != Hash_seed(hash)) {
/* the hash has been expanded */
#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
FREE_GLOBAL_TRIE_NODE(child_node);
#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_GLOBAL_NODE(parent_node);
goto global_trie_hash;
}
if (first_node != *bucket) {
gt_node_ptr chain_node = *bucket;
do {
if (TrNode_entry(chain_node) == t) {
#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
FREE_GLOBAL_TRIE_NODE(child_node);
#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
UNLOCK_GLOBAL_NODE(parent_node);
return chain_node;
}
count_nodes++;
chain_node = TrNode_next(chain_node);
} while (chain_node != first_node);
#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK
TrNode_next(child_node) = *bucket;
#else
NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, *bucket);
} else {
NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node);
#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */
}
*bucket = child_node;
Hash_num_nodes(hash)++;
count_nodes++;
if (count_nodes >= MAX_NODES_PER_BUCKET && Hash_num_nodes(hash) > Hash_num_buckets(hash)) {
/* expand current hash */
gt_node_ptr chain_node, next_node, *first_old_bucket, *old_bucket;
first_old_bucket = Hash_buckets(hash);
old_bucket = first_old_bucket + Hash_num_buckets(hash);
Hash_num_buckets(hash) *= 2;
ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash));
seed = Hash_seed(hash);
do {
if (*--old_bucket) {
chain_node = *old_bucket;
do {
bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), seed));
next_node = TrNode_next(chain_node);
TrNode_next(chain_node) = *bucket;
*bucket = chain_node;
chain_node = next_node;
} while (chain_node);
}
} while (old_bucket != first_old_bucket);
FREE_HASH_BUCKETS(first_old_bucket);
}
UNLOCK_GLOBAL_NODE(parent_node);
return child_node;
}
}
#endif /* GLOBAL_TRIE_LOCK_LEVEL */
#endif /* INCLUDE_GLOBAL_TRIE_CHECK_INSERT */ #endif /* INCLUDE_GLOBAL_TRIE_CHECK_INSERT */
@ -1195,14 +1369,15 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
#undef in_pair #undef in_pair
#endif /* TRIE_COMPACT_PAIRS */ #endif /* TRIE_COMPACT_PAIRS */
} }
#endif /* INCLUDE_ANSWER_SEARCH_LOOP */
/**************************************************************************** /**************************************************************
** answer_search_mode_directed_min_max ** ** answer_search_min_max **
****************************************************************************/ **************************************************************/
#if defined(MODE_DIRECTED_TABLING) && ! defined(MODE_TERMS_LOOP) && ! defined(MODE_GLOBAL_TRIE_LOOP) #ifdef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED
#define ANSWER_SAFE_INSERT_ENTRY(NODE, ENTRY, INSTR) \ #define ANSWER_SAFE_INSERT_ENTRY(NODE, ENTRY, INSTR) \
{ ans_node_ptr new_node; \ { ans_node_ptr new_node; \
NEW_ANSWER_TRIE_NODE(new_node, INSTR, ENTRY, NULL, NODE, NULL); \ NEW_ANSWER_TRIE_NODE(new_node, INSTR, ENTRY, NULL, NODE, NULL); \
@ -1210,7 +1385,7 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr
NODE = new_node; \ NODE = new_node; \
} }
static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr sg_fr, ans_node_ptr current_node, Term t, int mode) { static inline ans_node_ptr answer_search_min_max(sg_fr_ptr sg_fr, ans_node_ptr current_node, Term t, int mode) {
ans_node_ptr child_node; ans_node_ptr child_node;
Term child_term; Term child_term;
Float trie_value, term_value; Float trie_value, term_value;
@ -1237,7 +1412,7 @@ static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr sg_fr,
#endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */ #endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */
trie_value = u.dbl; trie_value = u.dbl;
} else } else
Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_mode_directed_min_max: invalid arithmetic value"); Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_min_max: invalid arithmetic value");
child_node = TrNode_child(child_node); child_node = TrNode_child(child_node);
} }
@ -1251,7 +1426,7 @@ static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr sg_fr,
else if (f == FunctorDouble) else if (f == FunctorDouble)
term_value = FloatOfTerm(t); term_value = FloatOfTerm(t);
else else
Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_mode_directed_min_max: invalid arithmetic value"); Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_min_max: invalid arithmetic value");
} }
/* worse answer */ /* worse answer */
@ -1286,6 +1461,7 @@ static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr sg_fr,
} }
return current_node; return current_node;
} }
#endif /* INCLUDE_ANSWER_SEARCH_MODE_DIRECTED */
@ -1293,6 +1469,20 @@ static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr sg_fr,
** invalidate_answer_trie ** ** invalidate_answer_trie **
***************************************************************/ ***************************************************************/
#ifdef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED
#ifdef YAPOR
#define INVALIDATE_ANSWER_TRIE_NODE(NODE, SG_FR) \
TrNode_next(NODE) = SgFr_invalid_chain(SG_FR); \
SgFr_invalid_chain(SG_FR) = NODE
#else
#define INVALIDATE_ANSWER_TRIE_NODE(NODE, SG_FR) \
FREE_ANSWER_TRIE_NODE(NODE)
#endif /* YAPOR */
#define INVALIDATE_ANSWER_TRIE_LEAF_NODE(NODE, SG_FR) \
TAG_AS_INVALID_LEAF_NODE(NODE); \
TrNode_next(NODE) = SgFr_invalid_chain(SG_FR); \
SgFr_invalid_chain(SG_FR) = NODE
static void invalidate_answer_trie(ans_node_ptr current_node, sg_fr_ptr sg_fr, int position) { static void invalidate_answer_trie(ans_node_ptr current_node, sg_fr_ptr sg_fr, int position) {
if (IS_ANSWER_TRIE_HASH(current_node)) { if (IS_ANSWER_TRIE_HASH(current_node)) {
ans_hash_ptr hash; ans_hash_ptr hash;
@ -1304,15 +1494,11 @@ static void invalidate_answer_trie(ans_node_ptr current_node, sg_fr_ptr sg_fr, i
current_node = *bucket; current_node = *bucket;
if (current_node) { if (current_node) {
ans_node_ptr next_node = TrNode_next(current_node); ans_node_ptr next_node = TrNode_next(current_node);
if (! IS_ANSWER_LEAF_NODE(current_node)) { if (IS_ANSWER_LEAF_NODE(current_node)) {
invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); INVALIDATE_ANSWER_TRIE_LEAF_NODE(current_node, sg_fr);
FREE_ANSWER_TRIE_NODE(current_node);
} else { } else {
LOCK_NODE(current_ans_node); invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST);
TAG_AS_INVALID_LEAF_NODE(current_node); INVALIDATE_ANSWER_TRIE_NODE(current_node, sg_fr);
UNLOCK_NODE(current_ans_node);
TrNode_next(current_node) = SgFr_invalid_chain(sg_fr);
SgFr_invalid_chain(sg_fr) = current_node;
} }
while (next_node) { while (next_node) {
current_node = next_node; current_node = next_node;
@ -1332,13 +1518,11 @@ static void invalidate_answer_trie(ans_node_ptr current_node, sg_fr_ptr sg_fr, i
} else { } else {
if (position == TRAVERSE_POSITION_FIRST) { if (position == TRAVERSE_POSITION_FIRST) {
ans_node_ptr next_node = TrNode_next(current_node); ans_node_ptr next_node = TrNode_next(current_node);
if (! IS_ANSWER_LEAF_NODE(current_node)) { if (IS_ANSWER_LEAF_NODE(current_node)) {
invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); INVALIDATE_ANSWER_TRIE_LEAF_NODE(current_node, sg_fr);
FREE_ANSWER_TRIE_NODE(current_node);
} else { } else {
TAG_AS_INVALID_LEAF_NODE(current_node); invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST);
TrNode_next(current_node) = SgFr_invalid_chain(sg_fr); INVALIDATE_ANSWER_TRIE_NODE(current_node, sg_fr);
SgFr_invalid_chain(sg_fr) = current_node;
} }
while (next_node) { while (next_node) {
current_node = next_node; current_node = next_node;
@ -1346,20 +1530,17 @@ static void invalidate_answer_trie(ans_node_ptr current_node, sg_fr_ptr sg_fr, i
invalidate_answer_trie(current_node, sg_fr, TRAVERSE_POSITION_NEXT); invalidate_answer_trie(current_node, sg_fr, TRAVERSE_POSITION_NEXT);
} }
} else { } else {
if (! IS_ANSWER_LEAF_NODE(current_node)) { if (IS_ANSWER_LEAF_NODE(current_node)) {
invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); INVALIDATE_ANSWER_TRIE_LEAF_NODE(current_node, sg_fr);
FREE_ANSWER_TRIE_NODE(current_node);
} else { } else {
TAG_AS_INVALID_LEAF_NODE(current_node); invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST);
TrNode_next(current_node) = SgFr_invalid_chain(sg_fr); INVALIDATE_ANSWER_TRIE_NODE(current_node, sg_fr);
SgFr_invalid_chain(sg_fr) = current_node;
} }
} }
} }
return; return;
} }
#endif /* MODE_DIRECTED_TABLING && ! MODE_TERMS_LOOP && ! MODE_GLOBAL_TRIE_LOOP */ #endif /* INCLUDE_ANSWER_SEARCH_MODE_DIRECTED */
#endif /* INCLUDE_ANSWER_SEARCH_LOOP */
@ -1526,5 +1707,3 @@ static inline CELL *load_answer_loop(ans_node_ptr current_node) {
#undef NEW_GLOBAL_TRIE_NODE #undef NEW_GLOBAL_TRIE_NODE
#undef SUBGOAL_CHECK_INSERT_ENTRY #undef SUBGOAL_CHECK_INSERT_ENTRY
#undef ANSWER_CHECK_INSERT_ENTRY #undef ANSWER_CHECK_INSERT_ENTRY
#undef LOCK_NODE
#undef UNLOCK_NODE