improve bb routines to use the DB efficiently

change interface between DB and BB.


git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1318 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
vsc 2005-06-01 13:53:46 +00:00
parent d19cf8bef8
commit f3fe74cb9f
6 changed files with 176 additions and 102 deletions

139
C/bb.c
View File

@ -19,8 +19,7 @@ static char SccsId[] = "%W% %G%";
#endif
#include "Yap.h"
#include "Yatom.h"
#include "Heap.h"
#include "clause.h"
#ifndef NULL
#define NULL (void *)0
#endif
@ -47,7 +46,7 @@ PutBBProp(AtomEntry *ae, Term mod) /* get BBentry for at; */
p->NextOfPE = ae->PropsOfAE;
ae->PropsOfAE = AbsBBProp(p);
p->ModuleOfBB = mod;
p->Element = NULL;
p->Element = 0L;
p->KeyOfBB = AbsAtom(ae);
p->KindOfPE = BBProperty;
INIT_RWLOCK(p->BBRWLock);
@ -94,7 +93,7 @@ PutIntBBProp(Int key, Term mod) /* get BBentry for at; */
return(NULL);
}
p->ModuleOfBB = mod;
p->Element = NULL;
p->Element = 0L;
p->KeyOfBB = (Atom)key;
p->KindOfPE = BBProperty;
p->NextOfPE = INT_BB_KEYS[hash_key];
@ -246,20 +245,53 @@ FetchBBProp(Term t1, char *msg, Term mod)
return(p);
}
static Term
BBPut(Term t0, Term t2)
{
if (!IsVarTerm(t0) && IsApplTerm(t0)) {
Yap_ErLogUpdCl((LogUpdClause *)DBRefOfTerm(t0));
}
if (IsVarTerm(t2) || IsAtomOrIntTerm(t2)) {
return t2;
} else {
LogUpdClause *cl = Yap_new_ludbe(t2, NULL, 0);
if (cl == NULL) {
return 0L;
}
return MkDBRefTerm((DBRef)cl);
}
}
static Int
p_bb_put(void)
{
Term t1 = Deref(ARG1);
BBProp p = AddBBProp(t1, "bb_put/2", CurrentModule);
if (p == NULL)
if (p == NULL) {
return(FALSE);
WRITE_LOCK(p->BBRWLock);
if (p->Element != NULL) {
Yap_ReleaseTermFromDB(p->Element);
}
p->Element = Yap_StoreTermInDB(Deref(ARG2),2);
WRITE_LOCK(p->BBRWLock);
/*
if (p->Element)
fprintf(stderr,"putting %p, size %d\n", p, p->Element->NOfCells);
*/
p->Element = BBPut(p->Element, Deref(ARG2));
WRITE_UNLOCK(p->BBRWLock);
return(p->Element != NULL);
return (p->Element != 0L);
}
static Term
BBGet(Term t, UInt arity)
{
if (IsVarTerm(t)) {
return MkVarTerm();
} else if (IsAtomOrIntTerm(t)) {
return t;
} else {
return Yap_LUInstance((LogUpdClause *)DBRefOfTerm(t), arity);
}
}
static Int
@ -267,27 +299,18 @@ p_bb_get(void)
{
Term t1 = Deref(ARG1);
BBProp p = FetchBBProp(t1, "bb_get/2", CurrentModule);
Term out;
if (p == NULL || p->Element == NULL)
Term out, t0;
if (p == NULL || p->Element == 0L)
return(FALSE);
READ_LOCK(p->BBRWLock);
while ((out = Yap_FetchTermFromDB(p->Element)) == 0L) {
if (Yap_Error_TYPE == OUT_OF_ATTVARS_ERROR) {
Yap_Error_TYPE = YAP_NO_ERROR;
if (!Yap_growglobal(NULL)) {
Yap_Error(OUT_OF_ATTVARS_ERROR, TermNil, Yap_ErrorMessage);
return TermNil;
}
} else {
Yap_Error_TYPE = YAP_NO_ERROR;
if (!Yap_gc(2, ENV, P)) {
Yap_Error(OUT_OF_STACK_ERROR, TermNil, Yap_ErrorMessage);
return TermNil;
}
}
}
READ_UNLOCK(p->BBRWLock);
return(Yap_unify(ARG2,out));
/*
if (p->Element)
fprintf(stderr,"getting %p, size %d\n", p, p->Element->NOfCells);
*/
t0 = p->Element;
READ_UNLOCK(p->BBRWLock);
out = BBGet(t0, 2);
return Yap_unify(ARG2,out);
}
static Int
@ -298,28 +321,16 @@ p_bb_delete(void)
Term out;
p = FetchBBProp(t1, "bb_delete/2", CurrentModule);
if (p == NULL || p->Element == NULL)
if (p == NULL || p->Element == 0L)
return(FALSE);
while ((out = Yap_FetchTermFromDB(p->Element)) == 0L) {
if (Yap_Error_TYPE == OUT_OF_ATTVARS_ERROR) {
Yap_Error_TYPE = YAP_NO_ERROR;
if (!Yap_growglobal(NULL)) {
Yap_Error(OUT_OF_ATTVARS_ERROR, TermNil, Yap_ErrorMessage);
return TermNil;
}
} else {
Yap_Error_TYPE = YAP_NO_ERROR;
if (!Yap_gc(2, ENV, P)) {
Yap_Error(OUT_OF_STACK_ERROR, TermNil, Yap_ErrorMessage);
return TermNil;
}
}
}
WRITE_LOCK(p->BBRWLock);
Yap_ReleaseTermFromDB(p->Element);
p->Element = NULL;
out = BBGet(p->Element,2);
if (!IsVarTerm(p->Element) && IsApplTerm(p->Element)) {
Yap_ErLogUpdCl((LogUpdClause *)DBRefOfTerm(p->Element));
}
p->Element = 0L;
WRITE_UNLOCK(p->BBRWLock);
return(Yap_unify(ARG2,out));
return Yap_unify(ARG2,out);
}
static Int
@ -330,33 +341,17 @@ p_bb_update(void)
Term out;
p = FetchBBProp(t1, "bb_update/3", CurrentModule);
if (p == NULL || p->Element == NULL)
return(FALSE);
if (p == NULL || p->Element == 0L)
return FALSE;
WRITE_LOCK(p->BBRWLock);
while ((out = Yap_FetchTermFromDB(p->Element)) == 0L) {
if (Yap_Error_TYPE == OUT_OF_ATTVARS_ERROR) {
Yap_Error_TYPE = YAP_NO_ERROR;
if (!Yap_growglobal(NULL)) {
Yap_Error(OUT_OF_ATTVARS_ERROR, TermNil, Yap_ErrorMessage);
return TermNil;
}
} else {
Yap_Error_TYPE = YAP_NO_ERROR;
if (!Yap_gc(3, ENV, P)) {
Yap_Error(OUT_OF_STACK_ERROR, TermNil, Yap_ErrorMessage);
return TermNil;
}
}
out = BBGet(p->Element, 3);
if (!Yap_unify(out,ARG2)) {
WRITE_UNLOCK(p->BBRWLock);
return FALSE;
}
if (!Yap_unify(ARG2,out)) {
WRITE_UNLOCK(p->BBRWLock);
return(FALSE);
}
Yap_ReleaseTermFromDB(p->Element);
p->Element = Yap_StoreTermInDB(Deref(ARG3),3);
p->Element = BBPut(p->Element, Deref(ARG3));
WRITE_UNLOCK(p->BBRWLock);
return(p->Element != NULL);
return (p->Element != 0L);
}
static Int

102
C/dbase.c
View File

@ -1900,6 +1900,27 @@ new_lu_db_entry(Term t, PredEntry *pe)
}
LogUpdClause *
Yap_new_ludbe(Term t, PredEntry *pe, UInt nargs)
{
LogUpdClause *x;
Yap_Error_Size = 0;
while ((x = new_lu_db_entry(t, pe)) == NULL) {
if (Yap_Error_TYPE == YAP_NO_ERROR) {
break;
} else {
XREGS[nargs+1] = t;
if (recover_from_record_error(nargs+1)) {
t = Deref(XREGS[nargs+1]);
} else {
return FALSE;
}
}
}
return x;
}
static LogUpdClause *
record_lu(PredEntry *pe, Term t, int position)
{
@ -4069,21 +4090,23 @@ EraseLogUpdCl(LogUpdClause *clau)
UNLOCK(clau->ClPrev->ClLock);
}
UNLOCK(clau->ClLock);
if (clau->ClCode == ap->cs.p_code.FirstClause) {
if (clau->ClNext == NULL) {
ap->cs.p_code.FirstClause = NULL;
} else {
ap->cs.p_code.FirstClause = clau->ClNext->ClCode;
if (ap) {
if (clau->ClCode == ap->cs.p_code.FirstClause) {
if (clau->ClNext == NULL) {
ap->cs.p_code.FirstClause = NULL;
} else {
ap->cs.p_code.FirstClause = clau->ClNext->ClCode;
}
}
}
if (clau->ClCode == ap->cs.p_code.LastClause) {
if (clau->ClPrev == NULL) {
ap->cs.p_code.LastClause = NULL;
} else {
ap->cs.p_code.LastClause = clau->ClPrev->ClCode;
if (clau->ClCode == ap->cs.p_code.LastClause) {
if (clau->ClPrev == NULL) {
ap->cs.p_code.LastClause = NULL;
} else {
ap->cs.p_code.LastClause = clau->ClPrev->ClCode;
}
}
ap->cs.p_code.NOfClauses--;
}
ap->cs.p_code.NOfClauses--;
clau->ClFlags |= ErasedMask;
#ifdef DEBUG
#ifndef THREADS
@ -4102,10 +4125,12 @@ EraseLogUpdCl(LogUpdClause *clau)
#endif
/* we are holding a reference to the clause */
clau->ClRefCount++;
UNLOCK(clau->ClLock);
Yap_RemoveClauseFromIndex(ap, clau->ClCode);
/* release the extra reference */
LOCK(clau->ClLock);
if (ap) {
UNLOCK(clau->ClLock);
Yap_RemoveClauseFromIndex(ap, clau->ClCode);
/* release the extra reference */
LOCK(clau->ClLock);
}
clau->ClRefCount--;
#if defined(YAPOR) || defined(THREADS)
if (WPP != ap || i_locked) {
@ -4669,6 +4694,51 @@ p_instance(void)
}
}
Term
Yap_LUInstance(LogUpdClause *cl, UInt arity)
{
Term TermDB;
op_numbers opc = Yap_op_from_opcode(cl->ClCode->opc);
LOCK(cl->ClLock);
if (opc == _unify_idb_term) {
TermDB = cl->ClSource->Entry;
} else {
while ((TermDB = GetDBTerm(cl->ClSource)) == 0L) {
/* oops, we are in trouble, not enough stack space */
if (Yap_Error_TYPE == OUT_OF_ATTVARS_ERROR) {
UNLOCK(cl->ClLock);
Yap_Error_TYPE = YAP_NO_ERROR;
if (!Yap_growglobal(NULL)) {
Yap_Error(OUT_OF_ATTVARS_ERROR, TermNil, Yap_ErrorMessage);
return 0L;
}
LOCK(cl->ClLock);
} else {
UNLOCK(cl->ClLock);
Yap_Error_TYPE = YAP_NO_ERROR;
if (!Yap_gcl(Yap_Error_Size, arity, ENV, P)) {
Yap_Error(OUT_OF_STACK_ERROR, TermNil, Yap_ErrorMessage);
return 0L;
}
LOCK(cl->ClLock);
}
}
}
#if defined(YAPOR) || defined(THREADS)
cl->ClRefCount++;
TRAIL_CLREF(cl); /* So that fail will erase it */
#else
if (!(cl->ClFlags & InUseMask)) {
cl->ClFlags |= InUseMask;
TRAIL_CLREF(cl);
}
#endif
UNLOCK(cl->ClLock);
return TermDB;
}
/* instance(+Ref,?Term) */
static Int
p_instance_module(void)

View File

@ -2764,7 +2764,7 @@ update_relocation_chain(CELL_PTR current, CELL_PTR dest)
}
#endif
}
#else /* TAGS_FAST_OPS */
#else /* !TAGS_FAST_OPS */
while (RMARKED(current)) {
CELL current_tag;
next = GET_NEXT(ccur);

View File

@ -863,7 +863,7 @@ typedef struct
Prop NextOfPE; /* used to chain properties */
PropFlags KindOfPE; /* kind of property */
Atom KeyOfBB; /* functor for this property */
DBTerm *Element; /* blackboard element */
Term Element; /* blackboard element */
#if defined(YAPOR) || defined(THREADS)
rwlock_t BBRWLock; /* a read-write lock to protect the entry */
#endif

View File

@ -311,6 +311,10 @@ typedef enum {
Int STD_PROTO(Yap_PredForCode,(yamop *, find_pred_type, Atom *, UInt *, Term *));
#ifdef DEBUG
void STD_PROTO(Yap_bug_location,(yamop *));
LogUpdClause *STD_PROTO(Yap_new_ludbe,(Term, PredEntry *, UInt));
Term STD_PROTO(Yap_LUInstance,(LogUpdClause *, UInt));
#endif

View File

@ -11,8 +11,11 @@
* File: rheap.h *
* comments: walk through heap code *
* *
* Last rev: $Date: 2005-05-30 03:26:37 $,$Author: vsc $ *
* Last rev: $Date: 2005-06-01 13:53:46 $,$Author: vsc $ *
* $Log: not supported by cvs2svn $
* Revision 1.49 2005/05/30 03:26:37 vsc
* add some atom gc fixes
*
* Revision 1.48 2005/01/04 02:50:21 vsc
* - allow MegaClauses with blobs
* - change Diffs to be thread specific
@ -584,17 +587,6 @@ RestoreDB(DBEntry *pp)
}
}
/* Restores a DB structure, as it was saved in the heap */
static void
RestoreBB(BlackBoardEntry *pp)
{
if (pp->Element) {
pp->Element = DBTermAdjust(pp->Element);
RestoreDBTerm(pp->Element);
}
pp->KeyOfBB = AtomAdjust(pp->KeyOfBB);
}
#include "rclause.h"
/* Restores a prolog clause, in its compiled form */
@ -747,6 +739,19 @@ CleanSIndex(StaticIndex *idx)
}
/* Restores a DB structure, as it was saved in the heap */
static void
RestoreBB(BlackBoardEntry *pp)
{
Term t = pp->Element;
if (t) {
if (!IsVarTerm(t) && !IsAtomicTerm(t)) {
RestoreLUClause((LogUpdClause *)DBRefOfTerm(t),NULL);
}
}
pp->KeyOfBB = AtomAdjust(pp->KeyOfBB);
}
static void
restore_static_array(StaticArrayEntry *ae)
{