00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #define _FACTHSH_SOURCE_
00028
00029 #include <stdio.h>
00030 #define _STDIO_INCLUDED_
00031 #include <stdlib.h>
00032
00033 #include "setup.h"
00034
00035 #if DEFTEMPLATE_CONSTRUCT
00036
00037 #include "constant.h"
00038 #include "memalloc.h"
00039 #include "router.h"
00040 #include "sysdep.h"
00041 #include "envrnmnt.h"
00042
00043 #if DEFRULE_CONSTRUCT
00044 #include "lgcldpnd.h"
00045 #endif
00046
00047 #include "facthsh.h"
00048
00049
00050
00051
00052
00053 static struct fact *FactExists(void *,struct fact *,unsigned long);
00054 static struct factHashEntry **CreateFactHashTable(void *,unsigned long);
00055 static void ResizeFactHashTable(void *);
00056 static void ResetFactHashTable(void *);
00057
00058
00059
00060
00061 unsigned long HashFact(
00062 struct fact *theFact)
00063 {
00064 unsigned long count = 0;
00065
00066
00067
00068
00069
00070 count += (unsigned long) theFact->whichDeftemplate->header.name->bucket * 73981;
00071
00072
00073
00074
00075
00076 count += HashMultifield(&theFact->theProposition,0);
00077
00078
00079
00080
00081
00082
00083 theFact->hashValue = count;
00084
00085
00086
00087
00088
00089 return(count);
00090 }
00091
00092
00093
00094
00095
00096 static struct fact *FactExists(
00097 void *theEnv,
00098 struct fact *theFact,
00099 unsigned long hashValue)
00100 {
00101 struct factHashEntry *theFactHash;
00102
00103 hashValue = (hashValue % FactData(theEnv)->FactHashTableSize);
00104
00105 for (theFactHash = FactData(theEnv)->FactHashTable[hashValue];
00106 theFactHash != NULL;
00107 theFactHash = theFactHash->next)
00108 {
00109 if (theFact->hashValue != theFactHash->theFact->hashValue)
00110 { continue; }
00111
00112 if ((theFact->whichDeftemplate == theFactHash->theFact->whichDeftemplate) ?
00113 MultifieldsEqual(&theFact->theProposition,
00114 &theFactHash->theFact->theProposition) : FALSE)
00115 { return(theFactHash->theFact); }
00116 }
00117
00118 return(NULL);
00119 }
00120
00121
00122
00123
00124 globle void AddHashedFact(
00125 void *theEnv,
00126 struct fact *theFact,
00127 unsigned long hashValue)
00128 {
00129 struct factHashEntry *newhash, *temp;
00130
00131 if (FactData(theEnv)->NumberOfFacts > FactData(theEnv)->FactHashTableSize)
00132 { ResizeFactHashTable(theEnv); }
00133
00134 newhash = get_struct(theEnv,factHashEntry);
00135 newhash->theFact = theFact;
00136
00137 hashValue = (hashValue % FactData(theEnv)->FactHashTableSize);
00138
00139 temp = FactData(theEnv)->FactHashTable[hashValue];
00140 FactData(theEnv)->FactHashTable[hashValue] = newhash;
00141 newhash->next = temp;
00142 }
00143
00144
00145
00146
00147
00148 globle intBool RemoveHashedFact(
00149 void *theEnv,
00150 struct fact *theFact)
00151 {
00152 unsigned long hashValue;
00153 struct factHashEntry *hptr, *prev;
00154
00155 hashValue = HashFact(theFact);
00156 hashValue = (hashValue % FactData(theEnv)->FactHashTableSize);
00157
00158 for (hptr = FactData(theEnv)->FactHashTable[hashValue], prev = NULL;
00159 hptr != NULL;
00160 hptr = hptr->next)
00161 {
00162 if (hptr->theFact == theFact)
00163 {
00164 if (prev == NULL)
00165 {
00166 FactData(theEnv)->FactHashTable[hashValue] = hptr->next;
00167 rtn_struct(theEnv,factHashEntry,hptr);
00168 if (FactData(theEnv)->NumberOfFacts == 1)
00169 { ResetFactHashTable(theEnv); }
00170 return(1);
00171 }
00172 else
00173 {
00174 prev->next = hptr->next;
00175 rtn_struct(theEnv,factHashEntry,hptr);
00176 if (FactData(theEnv)->NumberOfFacts == 1)
00177 { ResetFactHashTable(theEnv); }
00178 return(1);
00179 }
00180 }
00181 prev = hptr;
00182 }
00183
00184 return(0);
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 globle unsigned long HandleFactDuplication(
00194 void *theEnv,
00195 void *theFact,
00196 intBool *duplicate)
00197 {
00198 struct fact *tempPtr;
00199 unsigned long hashValue;
00200 *duplicate = FALSE;
00201
00202 hashValue = HashFact((struct fact *) theFact);
00203
00204 if (FactData(theEnv)->FactDuplication) return(hashValue);
00205
00206 tempPtr = FactExists(theEnv,(struct fact *) theFact,hashValue);
00207 if (tempPtr == NULL) return(hashValue);
00208
00209 ReturnFact(theEnv,(struct fact *) theFact);
00210 #if DEFRULE_CONSTRUCT
00211 AddLogicalDependencies(theEnv,(struct patternEntity *) tempPtr,TRUE);
00212 #endif
00213 *duplicate = TRUE;
00214 return(0);
00215 }
00216
00217
00218
00219
00220
00221 globle intBool EnvGetFactDuplication(
00222 void *theEnv)
00223 {
00224 return(FactData(theEnv)->FactDuplication);
00225 }
00226
00227
00228
00229
00230
00231 globle intBool EnvSetFactDuplication(
00232 void *theEnv,
00233 int value)
00234 {
00235 int ov;
00236
00237 ov = FactData(theEnv)->FactDuplication;
00238 FactData(theEnv)->FactDuplication = value;
00239 return(ov);
00240 }
00241
00242
00243
00244
00245
00246 globle void InitializeFactHashTable(
00247 void *theEnv)
00248 {
00249 FactData(theEnv)->FactHashTable = CreateFactHashTable(theEnv,SIZE_FACT_HASH);
00250 FactData(theEnv)->FactHashTableSize = SIZE_FACT_HASH;
00251 }
00252
00253
00254
00255
00256 static struct factHashEntry **CreateFactHashTable(
00257 void *theEnv,
00258 unsigned long tableSize)
00259 {
00260 unsigned long i;
00261 struct factHashEntry **theTable;
00262
00263 theTable = (struct factHashEntry **)
00264 gm3(theEnv,sizeof (struct factHashEntry *) * tableSize);
00265
00266 if (theTable == NULL) EnvExitRouter(theEnv,EXIT_FAILURE);
00267
00268 for (i = 0; i < tableSize; i++) theTable[i] = NULL;
00269
00270 return(theTable);
00271 }
00272
00273
00274
00275
00276 static void ResizeFactHashTable(
00277 void *theEnv)
00278 {
00279 unsigned long i, newSize, newLocation;
00280 struct factHashEntry **theTable, **newTable;
00281 struct factHashEntry *theEntry, *nextEntry;
00282
00283 theTable = FactData(theEnv)->FactHashTable;
00284
00285 newSize = (FactData(theEnv)->FactHashTableSize * 2) + 1;
00286 newTable = CreateFactHashTable(theEnv,newSize);
00287
00288
00289
00290
00291
00292 for (i = 0; i < FactData(theEnv)->FactHashTableSize; i++)
00293 {
00294 theEntry = theTable[i];
00295 while (theEntry != NULL)
00296 {
00297 nextEntry = theEntry->next;
00298
00299 newLocation = theEntry->theFact->hashValue % newSize;
00300 theEntry->next = newTable[newLocation];
00301 newTable[newLocation] = theEntry;
00302
00303 theEntry = nextEntry;
00304 }
00305 }
00306
00307
00308
00309
00310
00311 rm3(theEnv,theTable,sizeof(struct factHashEntry *) * FactData(theEnv)->FactHashTableSize);
00312 FactData(theEnv)->FactHashTableSize = newSize;
00313 FactData(theEnv)->FactHashTable = newTable;
00314 }
00315
00316
00317
00318
00319 static void ResetFactHashTable(
00320 void *theEnv)
00321 {
00322 struct factHashEntry **newTable;
00323
00324
00325
00326
00327
00328
00329 if (FactData(theEnv)->FactHashTableSize == SIZE_FACT_HASH)
00330 { return; }
00331
00332
00333
00334
00335
00336 newTable = CreateFactHashTable(theEnv,SIZE_FACT_HASH);
00337
00338
00339
00340
00341
00342 rm3(theEnv,FactData(theEnv)->FactHashTable,sizeof(struct factHashEntry *) * FactData(theEnv)->FactHashTableSize);
00343 FactData(theEnv)->FactHashTableSize = SIZE_FACT_HASH;
00344 FactData(theEnv)->FactHashTable = newTable;
00345 }
00346
00347 #if DEVELOPER
00348
00349
00350
00351
00352
00353 globle void ShowFactHashTable(
00354 void *theEnv)
00355 {
00356 int i, count;
00357 struct factHashEntry *theEntry;
00358 char buffer[20];
00359
00360 for (i = 0; i < FactData(theEnv)->FactHashTableSize; i++)
00361 {
00362 for (theEntry = FactData(theEnv)->FactHashTable[i], count = 0;
00363 theEntry != NULL;
00364 theEntry = theEntry->next)
00365 { count++; }
00366
00367 if (count != 0)
00368 {
00369 gensprintf(buffer,"%4d: %4d\n",i,count);
00370 EnvPrintRouter(theEnv,WDISPLAY,buffer);
00371 }
00372 }
00373 }
00374
00375 #endif
00376
00377 #endif
00378