1 /*******************************************************/
2 /* "C" Language Integrated Production System */
3 /* */
4 /* CLIPS Version 6.30 08/16/14 */
5 /* */
6 /* FACT BSAVE/BLOAD MODULE */
7 /*******************************************************/
8
9 /*************************************************************/
10 /* Purpose: Implements the binary save/load feature for the */
11 /* fact pattern network. */
12 /* */
13 /* Principal Programmer(s): */
14 /* Gary D. Riley */
15 /* */
16 /* Contributing Programmer(s): */
17 /* Brian L. Dantes */
18 /* */
19 /* Revision History: */
20 /* */
21 /* 6.30: Added support for hashed alpha memories. */
22 /* */
23 /* Changed integer type/precision. */
24 /* */
25 /*************************************************************/
26
27 #define _FACTBIN_SOURCE_
28
29 #include "setup.h"
30
31 #if DEFTEMPLATE_CONSTRUCT && (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE) && (! RUN_TIME)
32
33 #include <stdio.h>
34 #define _STDIO_INCLUDED_
35
36 #include "memalloc.h"
37 #include "tmpltdef.h"
38 #include "bload.h"
39 #include "bsave.h"
40 #include "reteutil.h"
41 #include "rulebin.h"
42 #include "moduldef.h"
43 #include "envrnmnt.h"
44
45 #include "factbin.h"
46
47 /********************************************/
48 /* INTERNAL DATA STRUCTURES AND DEFINITIONS */
49 /********************************************/
50
51 struct bsaveFactPatternNode
52 {
53 struct bsavePatternNodeHeader header;
54 unsigned short whichSlot;
55 unsigned short whichField;
56 unsigned short leaveFields;
57 long networkTest;
58 long nextLevel;
59 long lastLevel;
60 long leftNode;
61 long rightNode;
62 };
63
64 #define BSAVE_FIND 0
65 #define BSAVE_PATTERNS 1
66
67 /***************************************/
68 /* LOCAL INTERNAL FUNCTION DEFINITIONS */
69 /***************************************/
70
71 #if BLOAD_AND_BSAVE
72 static void BsaveDriver(void *,int,FILE *,struct factPatternNode *);
73 static void BsaveFind(void *);
74 static void BsaveStorage(void *,FILE *);
75 static void BsaveFactPatterns(void *,FILE *);
76 static void BsavePatternNode(void *,struct factPatternNode *,FILE *);
77 #endif
78 static void BloadStorage(void *);
79 static void BloadBinaryItem(void *);
80 static void UpdateFactPatterns(void *,void *,long);
81 static void ClearBload(void *);
82 static void DeallocateFactBloadData(void *);
83
84 /*****************************************************/
85 /* FactBinarySetup: Initializes the binary load/save */
86 /* feature for the fact pattern network. */
87 /*****************************************************/
FactBinarySetup(void * theEnv)88 globle void FactBinarySetup(
89 void *theEnv)
90 {
91 AllocateEnvironmentData(theEnv,FACTBIN_DATA,sizeof(struct factBinaryData),DeallocateFactBloadData);
92
93 #if BLOAD_AND_BSAVE
94 AddBinaryItem(theEnv,"facts",0,BsaveFind,NULL,
95 BsaveStorage,BsaveFactPatterns,
96 BloadStorage,BloadBinaryItem,
97 ClearBload);
98 #endif
99 #if BLOAD || BLOAD_ONLY
100 AddBinaryItem(theEnv,"facts",0,NULL,NULL,NULL,NULL,
101 BloadStorage,BloadBinaryItem,
102 ClearBload);
103 #endif
104 }
105
106 /****************************************************/
107 /* DeallocateFactBloadData: Deallocates environment */
108 /* data for the fact bsave functionality. */
109 /****************************************************/
DeallocateFactBloadData(void * theEnv)110 static void DeallocateFactBloadData(
111 void *theEnv)
112 {
113 size_t space;
114 int i;
115
116 for (i = 0; i < FactBinaryData(theEnv)->NumberOfPatterns; i++)
117 { DestroyAlphaMemory(theEnv,&FactBinaryData(theEnv)->FactPatternArray[i].header,FALSE); }
118
119 space = FactBinaryData(theEnv)->NumberOfPatterns * sizeof(struct factPatternNode);
120 if (space != 0) genfree(theEnv,(void *) FactBinaryData(theEnv)->FactPatternArray,space);
121 }
122
123 #if BLOAD_AND_BSAVE
124
125 /*********************************************************/
126 /* BsaveFind: Counts the number of data structures which */
127 /* must be saved in the binary image for the fact */
128 /* pattern network in the current environment. */
129 /*********************************************************/
BsaveFind(void * theEnv)130 static void BsaveFind(
131 void *theEnv)
132 {
133 struct deftemplate *theDeftemplate;
134 struct defmodule *theModule;
135
136 /*=======================================================*/
137 /* If a binary image is already loaded, then temporarily */
138 /* save the count values since these will be overwritten */
139 /* in the process of saving the binary image. */
140 /*=======================================================*/
141
142 SaveBloadCount(theEnv,FactBinaryData(theEnv)->NumberOfPatterns);
143
144 /*=======================================*/
145 /* Set the count of fact pattern network */
146 /* data structures to zero. */
147 /*=======================================*/
148
149 FactBinaryData(theEnv)->NumberOfPatterns = 0L;
150
151 /*===========================*/
152 /* Loop through each module. */
153 /*===========================*/
154
155 for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
156 theModule != NULL;
157 theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule))
158 {
159 /*===============================*/
160 /* Set the current module to the */
161 /* module being examined. */
162 /*===============================*/
163
164 EnvSetCurrentModule(theEnv,(void *) theModule);
165
166 /*=====================================================*/
167 /* Loop through each deftemplate in the current module */
168 /* and count the number of data structures which must */
169 /* be saved for its pattern network. */
170 /*=====================================================*/
171
172 for (theDeftemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,NULL);
173 theDeftemplate != NULL;
174 theDeftemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,theDeftemplate))
175 { BsaveDriver(theEnv,BSAVE_FIND,NULL,theDeftemplate->patternNetwork); }
176 }
177 }
178
179 /**********************************************************/
180 /* BsaveDriver: Binary save driver routine which handles */
181 /* both finding/marking the data structures to be saved */
182 /* and saving the data structures to a file. */
183 /**********************************************************/
BsaveDriver(void * theEnv,int action,FILE * fp,struct factPatternNode * thePattern)184 static void BsaveDriver(
185 void *theEnv,
186 int action,
187 FILE *fp,
188 struct factPatternNode *thePattern)
189 {
190 while (thePattern != NULL)
191 {
192 switch(action)
193 {
194 case BSAVE_FIND:
195 thePattern->bsaveID = FactBinaryData(theEnv)->NumberOfPatterns++;
196 break;
197
198 case BSAVE_PATTERNS:
199 BsavePatternNode(theEnv,thePattern,fp);
200 break;
201
202 default:
203 break;
204 }
205
206 if (thePattern->nextLevel == NULL)
207 {
208 while (thePattern->rightNode == NULL)
209 {
210 thePattern = thePattern->lastLevel;
211 if (thePattern == NULL) return;
212 }
213 thePattern = thePattern->rightNode;
214 }
215 else
216 { thePattern = thePattern->nextLevel; }
217 }
218 }
219
220 /*********************************************************/
221 /* BsaveStorage: Writes out storage requirements for all */
222 /* factPatternNode data structures to the binary file */
223 /*********************************************************/
BsaveStorage(void * theEnv,FILE * fp)224 static void BsaveStorage(
225 void *theEnv,
226 FILE *fp)
227 {
228 size_t space;
229
230 space = sizeof(long);
231 GenWrite(&space,sizeof(size_t),fp);
232 GenWrite(&FactBinaryData(theEnv)->NumberOfPatterns,sizeof(long int),fp);
233 }
234
235 /*****************************************************/
236 /* BsaveFactPatterns: Writes out all factPatternNode */
237 /* data structures to the binary file. */
238 /*****************************************************/
BsaveFactPatterns(void * theEnv,FILE * fp)239 static void BsaveFactPatterns(
240 void *theEnv,
241 FILE *fp)
242 {
243 size_t space;
244 struct deftemplate *theDeftemplate;
245 struct defmodule *theModule;
246
247 /*========================================*/
248 /* Write out the amount of space taken up */
249 /* by the factPatternNode data structures */
250 /* in the binary image. */
251 /*========================================*/
252
253 space = FactBinaryData(theEnv)->NumberOfPatterns * sizeof(struct bsaveFactPatternNode);
254 GenWrite(&space,sizeof(size_t),fp);
255
256 /*===========================*/
257 /* Loop through each module. */
258 /*===========================*/
259
260 for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
261 theModule != NULL;
262 theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule))
263 {
264 /*=====================================================*/
265 /* Loop through each deftemplate in the current module */
266 /* and save its fact pattern network to the file. */
267 /*=====================================================*/
268
269 EnvSetCurrentModule(theEnv,(void *) theModule);
270 for (theDeftemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,NULL);
271 theDeftemplate != NULL;
272 theDeftemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,theDeftemplate))
273 { BsaveDriver(theEnv,BSAVE_PATTERNS,fp,theDeftemplate->patternNetwork); }
274 }
275
276 /*=============================================================*/
277 /* If a binary image was already loaded when the bsave command */
278 /* was issued, then restore the counts indicating the number */
279 /* of factPatternNode data structures in the binary image */
280 /* (these were overwritten by the binary save). */
281 /*=============================================================*/
282
283 RestoreBloadCount(theEnv,&FactBinaryData(theEnv)->NumberOfPatterns);
284 }
285
286 /******************************************************/
287 /* BsavePatternNode: Writes out a single fact pattern */
288 /* node to the binary image save file. */
289 /******************************************************/
BsavePatternNode(void * theEnv,struct factPatternNode * thePattern,FILE * fp)290 static void BsavePatternNode(
291 void *theEnv,
292 struct factPatternNode *thePattern,
293 FILE *fp)
294 {
295 struct bsaveFactPatternNode tempNode;
296
297 AssignBsavePatternHeaderValues(theEnv,&tempNode.header,&thePattern->header);
298
299 tempNode.whichField = thePattern->whichField;
300 tempNode.leaveFields = thePattern->leaveFields;
301 tempNode.whichSlot = thePattern->whichSlot;
302 tempNode.networkTest = HashedExpressionIndex(theEnv,thePattern->networkTest);
303 tempNode.nextLevel = BsaveFactPatternIndex(thePattern->nextLevel);
304 tempNode.lastLevel = BsaveFactPatternIndex(thePattern->lastLevel);
305 tempNode.leftNode = BsaveFactPatternIndex(thePattern->leftNode);
306 tempNode.rightNode = BsaveFactPatternIndex(thePattern->rightNode);
307
308 GenWrite(&tempNode,(unsigned long) sizeof(struct bsaveFactPatternNode),fp);
309 }
310
311 #endif /* BLOAD_AND_BSAVE */
312
313 /*****************************************************/
314 /* BloadStorage: Allocates storage requirements for */
315 /* the factPatternNodes used by this binary image. */
316 /*****************************************************/
BloadStorage(void * theEnv)317 static void BloadStorage(
318 void *theEnv)
319 {
320 size_t space;
321
322 /*=========================================*/
323 /* Determine the number of factPatternNode */
324 /* data structures to be read. */
325 /*=========================================*/
326
327 GenReadBinary(theEnv,&space,sizeof(size_t));
328 GenReadBinary(theEnv,&FactBinaryData(theEnv)->NumberOfPatterns,sizeof(long int));
329
330 /*===================================*/
331 /* Allocate the space needed for the */
332 /* factPatternNode data structures. */
333 /*===================================*/
334
335 if (FactBinaryData(theEnv)->NumberOfPatterns == 0)
336 {
337 FactBinaryData(theEnv)->FactPatternArray = NULL;
338 return;
339 }
340
341 space = FactBinaryData(theEnv)->NumberOfPatterns * sizeof(struct factPatternNode);
342 FactBinaryData(theEnv)->FactPatternArray = (struct factPatternNode *) genalloc(theEnv,space);
343 }
344
345 /************************************************************/
346 /* BloadBinaryItem: Loads and refreshes the factPatternNode */
347 /* data structures used by this binary image. */
348 /************************************************************/
BloadBinaryItem(void * theEnv)349 static void BloadBinaryItem(
350 void *theEnv)
351 {
352 size_t space;
353 long i;
354
355 /*======================================================*/
356 /* Read in the amount of space used by the binary image */
357 /* (this is used to skip the construct in the event it */
358 /* is not available in the version being run). */
359 /*======================================================*/
360
361 GenReadBinary(theEnv,&space,sizeof(size_t));
362
363 /*=============================================*/
364 /* Read in the factPatternNode data structures */
365 /* and refresh the pointers. */
366 /*=============================================*/
367
368 BloadandRefresh(theEnv,FactBinaryData(theEnv)->NumberOfPatterns,(unsigned) sizeof(struct bsaveFactPatternNode),
369 UpdateFactPatterns);
370
371 for (i = 0; i < FactBinaryData(theEnv)->NumberOfPatterns; i++)
372 {
373 if ((FactBinaryData(theEnv)->FactPatternArray[i].lastLevel != NULL) &&
374 (FactBinaryData(theEnv)->FactPatternArray[i].lastLevel->header.selector))
375 {
376 AddHashedPatternNode(theEnv,FactBinaryData(theEnv)->FactPatternArray[i].lastLevel,
377 &FactBinaryData(theEnv)->FactPatternArray[i],
378 FactBinaryData(theEnv)->FactPatternArray[i].networkTest->type,
379 FactBinaryData(theEnv)->FactPatternArray[i].networkTest->value);
380 }
381 }
382 }
383
384 /*************************************************/
385 /* UpdateFactPatterns: Bload refresh routine for */
386 /* the factPatternNode structure. */
387 /*************************************************/
UpdateFactPatterns(void * theEnv,void * buf,long obji)388 static void UpdateFactPatterns(
389 void *theEnv,
390 void *buf,
391 long obji)
392 {
393 struct bsaveFactPatternNode *bp;
394
395 bp = (struct bsaveFactPatternNode *) buf;
396
397 UpdatePatternNodeHeader(theEnv,&FactBinaryData(theEnv)->FactPatternArray[obji].header,&bp->header);
398
399 FactBinaryData(theEnv)->FactPatternArray[obji].bsaveID = 0L;
400 FactBinaryData(theEnv)->FactPatternArray[obji].whichField = bp->whichField;
401 FactBinaryData(theEnv)->FactPatternArray[obji].leaveFields = bp->leaveFields;
402 FactBinaryData(theEnv)->FactPatternArray[obji].whichSlot = bp->whichSlot;
403
404 FactBinaryData(theEnv)->FactPatternArray[obji].networkTest = HashedExpressionPointer(bp->networkTest);
405 FactBinaryData(theEnv)->FactPatternArray[obji].rightNode = BloadFactPatternPointer(bp->rightNode);
406 FactBinaryData(theEnv)->FactPatternArray[obji].nextLevel = BloadFactPatternPointer(bp->nextLevel);
407 FactBinaryData(theEnv)->FactPatternArray[obji].lastLevel = BloadFactPatternPointer(bp->lastLevel);
408 FactBinaryData(theEnv)->FactPatternArray[obji].leftNode = BloadFactPatternPointer(bp->leftNode);
409 }
410
411 /***************************************************/
412 /* ClearBload: Fact pattern network clear routine */
413 /* when a binary load is in effect. */
414 /***************************************************/
ClearBload(void * theEnv)415 static void ClearBload(
416 void *theEnv)
417 {
418 size_t space;
419 long i;
420
421 for (i = 0; i < FactBinaryData(theEnv)->NumberOfPatterns; i++)
422 {
423 if ((FactBinaryData(theEnv)->FactPatternArray[i].lastLevel != NULL) &&
424 (FactBinaryData(theEnv)->FactPatternArray[i].lastLevel->header.selector))
425 {
426 RemoveHashedPatternNode(theEnv,FactBinaryData(theEnv)->FactPatternArray[i].lastLevel,
427 &FactBinaryData(theEnv)->FactPatternArray[i],
428 FactBinaryData(theEnv)->FactPatternArray[i].networkTest->type,
429 FactBinaryData(theEnv)->FactPatternArray[i].networkTest->value);
430 }
431 }
432
433
434 space = FactBinaryData(theEnv)->NumberOfPatterns * sizeof(struct factPatternNode);
435 if (space != 0) genfree(theEnv,(void *) FactBinaryData(theEnv)->FactPatternArray,space);
436 FactBinaryData(theEnv)->NumberOfPatterns = 0;
437 }
438
439 #endif /* DEFTEMPLATE_CONSTRUCT && (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE) && (! RUN_TIME) */
440
441
442