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 #include "xsb_config.h"
00027 #include "xsb_debug.h"
00028
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031
00032 #include "debugs/debug_tries.h"
00033
00034 #include "auxlry.h"
00035 #include "cell_xsb.h"
00036 #include "inst_xsb.h"
00037 #include "register.h"
00038 #include "error_xsb.h"
00039 #include "psc_xsb.h"
00040 #include "deref.h"
00041 #include "table_stats.h"
00042 #include "trie_internals.h"
00043 #include "tst_aux.h"
00044 #include "thread_xsb.h"
00045 #include "memory_xsb.h"
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 inline static TSINptr tsiHeadInsert(CTXTdeclc TSTHTptr ht, TSTNptr tstn) {
00092
00093 TSINptr pTSIN;
00094
00095 New_TSIN(pTSIN, tstn);
00096 TSIN_Prev(pTSIN) = NULL;
00097 TSIN_Next(pTSIN) = TSTHT_IndexHead(ht);
00098 TSIN_Prev(TSTHT_IndexHead(ht)) = pTSIN;
00099 TSTHT_IndexHead(ht) = pTSIN;
00100 return pTSIN;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 inline static TSINptr tsiOrderedInsert(CTXTdeclc TSTHTptr ht, TSTNptr tstn) {
00119
00120 TSINptr nextTSIN;
00121 TSINptr newTSIN;
00122
00123
00124 New_TSIN(newTSIN, tstn);
00125
00126
00127
00128 nextTSIN = TSTHT_IndexHead(ht);
00129 while ( IsNonNULL(nextTSIN) &&
00130 (TSIN_TimeStamp(newTSIN) < TSIN_TimeStamp(nextTSIN)) )
00131 nextTSIN = TSIN_Next(nextTSIN);
00132
00133
00134
00135
00136 if ( IsNonNULL(nextTSIN) ) {
00137 TSIN_Prev(newTSIN) = TSIN_Prev(nextTSIN);
00138 TSIN_Next(newTSIN) = nextTSIN;
00139 if ( IsTSindexHead(nextTSIN) )
00140 TSTHT_IndexHead(ht) = newTSIN;
00141 else
00142 TSIN_Next(TSIN_Prev(nextTSIN)) = newTSIN;
00143 TSIN_Prev(nextTSIN) = newTSIN;
00144 }
00145 else {
00146 TSIN_Prev(newTSIN) = TSTHT_IndexTail(ht);
00147 TSIN_Next(newTSIN) = NULL;
00148 if ( IsNULL(TSTHT_IndexHead(ht)) )
00149 TSTHT_IndexHead(ht) = newTSIN;
00150 else
00151 TSIN_Next(TSTHT_IndexTail(ht)) = newTSIN;
00152 TSTHT_IndexTail(ht) = newTSIN;
00153 }
00154
00155 return newTSIN;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165 void tsiRemoveEntry(CTXTdeclc TSTHTptr ht, TSINptr tsin) {
00166
00167
00168
00169 if ( IsTSindexHead(tsin) )
00170 TSTHT_IndexHead(ht) = TSIN_Next(tsin);
00171 else
00172 TSIN_Next(TSIN_Prev(tsin)) = TSIN_Next(tsin);
00173 if ( IsTSindexTail(tsin) )
00174 TSTHT_IndexTail(ht) = TSIN_Prev(tsin);
00175 else
00176 TSIN_Prev(TSIN_Next(tsin)) = TSIN_Prev(tsin);
00177
00178
00179
00180 SM_DeallocateStruct(smTSIN,tsin);
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 inline static void tsiPromoteEntry(TSTNptr tstn, TimeStamp ts) {
00192
00193 TSINptr tsin;
00194 TSTHTptr ht;
00195
00196 tsin = TSTN_GetTSIN(tstn);
00197 TSIN_TimeStamp(tsin) = ts;
00198 if ( IsTSindexHead(tsin) )
00199 return;
00200
00201
00202
00203 ht = TSTN_GetHashHdr(TSTN_Parent(tstn));
00204 TSIN_Next(TSIN_Prev(tsin)) = TSIN_Next(tsin);
00205 if ( IsTSindexTail(tsin) )
00206 TSTHT_IndexTail(ht) = TSIN_Prev(tsin);
00207 else
00208 TSIN_Prev(TSIN_Next(tsin)) = TSIN_Prev(tsin);
00209
00210
00211
00212 TSIN_Prev(tsin) = NULL;
00213 TSIN_Next(tsin) = TSTHT_IndexHead(ht);
00214 TSIN_Prev(TSTHT_IndexHead(ht)) = tsin;
00215 TSTHT_IndexHead(ht) = tsin;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 void tstCreateTSIs(CTXTdeclc TSTNptr pTST) {
00229
00230 TSTNptr *pBucket, tstn;
00231 TSTHTptr ht;
00232 int bucketNum;
00233
00234 if ( IsNULL(pTST) )
00235 return;
00236
00237
00238 for ( ht = TSTRoot_GetHTList(pTST); IsNonNULL(ht);
00239 ht = TSTHT_InternalLink(ht) ) {
00240
00241
00242 for ( pBucket = TSTHT_BucketArray(ht), bucketNum = 0;
00243 (unsigned int)bucketNum < TSTHT_NumBuckets(ht);
00244 pBucket++, bucketNum++ )
00245
00246
00247 for ( tstn = *pBucket; IsNonNULL(tstn); tstn = TSTN_Sibling(tstn) )
00248
00249
00250 TSTN_SetTSIN(tstn,tsiOrderedInsert(CTXTc ht,tstn));
00251 }
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 inline static
00274 void tstnHashifyChildren(CTXTdeclc TSTNptr parent, TSTNptr root, xsbBool createTSI) {
00275
00276 TSTNptr children;
00277 TSTNptr tstn;
00278 TSTHTptr ht;
00279 TSTNptr *tablebase;
00280 unsigned long hashseed;
00281
00282
00283 New_TSTHT(ht,TSTN_TrieType(root),root);
00284 children = TSTN_Child(parent);
00285 TSTN_SetHashHdr(parent,ht);
00286 tablebase = TSTHT_BucketArray(ht);
00287 hashseed = TSTHT_GetHashSeed(ht);
00288 for (tstn = children; IsNonNULL(tstn); tstn = children) {
00289 children = TSTN_Sibling(tstn);
00290 TrieHT_InsertNode(tablebase, hashseed, tstn);
00291 MakeHashedNode(tstn);
00292 if ( createTSI )
00293 TSTN_SetTSIN(tstn, tsiOrderedInsert(CTXTc ht, tstn));
00294 }
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 inline static
00314 TSTNptr tstnAddSymbol(CTXTdeclc TSTNptr parent, Cell symbol, int trieType) {
00315
00316 TSTNptr newTSTN;
00317
00318 New_TSTN(newTSTN,trieType,INTERIOR_NT,symbol,parent,NULL);
00319 TSTN_Child(parent) = newTSTN;
00320 return newTSTN;
00321 }
00322
00323
00324
00325 inline static
00326 BTNptr btnAddSymbol(CTXTdeclc BTNptr parent, Cell symbol, int trieType) {
00327
00328 BTNptr newBTN;
00329
00330 New_BTN(newBTN,trieType,INTERIOR_NT,symbol,parent,NULL);
00331 BTN_Child(parent) = newBTN;
00332 return newBTN;
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 inline static
00345 TSTNptr tstnInsertSymbol(CTXTdeclc TSTNptr parent, Cell symbol, int trieType,
00346 TSTNptr root, xsbBool createTSI) {
00347
00348 TSTNptr tstn, chain;
00349 int chain_length;
00350
00351
00352 chain = TSTN_Child(parent);
00353 New_TSTN(tstn,trieType,INTERIOR_NT,symbol,parent,chain);
00354 TSTN_Child(parent) = tstn;
00355 chain_length = 1;
00356 while ( IsNonNULL(chain) ) {
00357 chain_length++;
00358 chain = TSTN_Sibling(chain);
00359 }
00360 if ( IsLongSiblingChain(chain_length) )
00361 tstnHashifyChildren(CTXTc parent,root,createTSI);
00362 return tstn;
00363 }
00364
00365
00366
00367 inline static
00368 BTNptr btnInsertSymbol(CTXTdeclc BTNptr parent, Cell symbol, int trieType) {
00369
00370 BTNptr btn, chain;
00371 int chain_length;
00372
00373
00374 chain = BTN_Child(parent);
00375 New_BTN(btn,trieType,INTERIOR_NT,symbol,parent,chain);
00376 BTN_Child(parent) = btn;
00377 chain_length = 1;
00378 while ( IsNonNULL(chain) ) {
00379 chain_length++;
00380 chain = BTN_Sibling(chain);
00381 }
00382 if ( IsLongSiblingChain(chain_length) )
00383 hashify_children(CTXTc parent,trieType);
00384 return btn;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 inline static
00397 TSTNptr tsthtInsertSymbol(CTXTdeclc TSTNptr parent, Cell symbol, int trieType,
00398 xsbBool maintainsTSI) {
00399
00400 TSTHTptr ht;
00401 TSTNptr tstn, chain, *bucket;
00402 int chain_length;
00403
00404
00405 ht = TSTN_GetHashHdr(parent);
00406 bucket = CalculateBucketForSymbol(ht,symbol);
00407 chain = *bucket;
00408 New_TSTN(tstn,trieType,HASHED_INTERIOR_NT,symbol,parent,chain);
00409 *bucket = tstn;
00410 TSTHT_NumContents(ht)++;
00411 if ( maintainsTSI )
00412 TSTN_SetTSIN(tstn, tsiHeadInsert(CTXTc ht,tstn));
00413 chain_length = 1;
00414 while ( IsNonNULL(chain) ) {
00415 chain_length++;
00416 chain = TSTN_Sibling(chain);
00417 }
00418
00419 #ifdef SHOW_HASHTABLE_ADDITIONS
00420 xsb_dbgmsg((LOG_DEBUG,"Hash Table size is %lu and now contains %lu elements.",
00421 TSTHT_NumBuckets(ht), TSTHT_NumContents(ht)));
00422 xsb_dbgmsg((LOG_DEBUG,"Addition being made to bucket %lu; now has length %d.",
00423 TrieHash(symbol, TrieHT_GetHashSeed(ht)), chain_length));
00424 #endif
00425
00426 TrieHT_ExpansionCheck(ht,chain_length);
00427 return tstn;
00428 }
00429
00430
00431
00432 inline static BTNptr bthtInsertSymbol(CTXTdeclc BTNptr parent, Cell symbol,
00433 int trieType) {
00434
00435 BTHTptr ht;
00436 BTNptr btn, chain, *bucket;
00437 int chain_length;
00438
00439
00440 ht = BTN_GetHashHdr(parent);
00441 bucket = CalculateBucketForSymbol(ht,symbol);
00442 chain = *bucket;
00443 New_BTN(btn,trieType,HASHED_INTERIOR_NT,symbol,parent,chain);
00444 *bucket = btn;
00445 BTHT_NumContents(ht)++;
00446 chain_length = 1;
00447 while ( IsNonNULL(chain) ) {
00448 chain_length++;
00449 chain = BTN_Sibling(chain);
00450 }
00451
00452 #ifdef SHOW_HASHTABLE_ADDITIONS
00453 xsb_dbgmsg((LOG_DEBUG,"Hash Table size is %lu and now contains %lu elements.",
00454 BTHT_NumBuckets(ht), BTHT_NumContents(ht)));
00455 xsb_dbgmsg((LOG_DEBUG,"Addition being made to bucket %lu; now has length %d.",
00456 TrieHash(symbol, TrieHT_GetHashSeed(ht)), chain_length));
00457 #endif
00458
00459 TrieHT_ExpansionCheck(ht,chain_length);
00460 return btn;
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 inline static void update_timestamps(TSTNptr tstLeaf, TSTNptr tstRoot,
00475 xsbBool containsTSIs) {
00476
00477 TimeStamp tsNewAnswer;
00478
00479
00480 tsNewAnswer = TSTN_TimeStamp(tstRoot) + 1;
00481 if ( containsTSIs )
00482 do {
00483 if ( IsHashedNode(tstLeaf) )
00484 tsiPromoteEntry(tstLeaf, tsNewAnswer);
00485 else
00486 TSTN_TimeStamp(tstLeaf) = tsNewAnswer;
00487 tstLeaf = TSTN_Parent(tstLeaf);
00488 } while ( tstLeaf != tstRoot );
00489 else
00490 do {
00491 TSTN_TimeStamp(tstLeaf) = tsNewAnswer;
00492 tstLeaf = TSTN_Parent(tstLeaf);
00493 } while ( tstLeaf != tstRoot );
00494 TSTN_TimeStamp(tstRoot) = tsNewAnswer;
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 TSTNptr tst_insert(CTXTdeclc TSTNptr tstRoot, TSTNptr lastMatch, Cell firstSymbol,
00535 xsbBool maintainTSI) {
00536
00537 Cell symbol;
00538 int std_var_num,
00539 trieType;
00540
00541
00542 symbol = firstSymbol;
00543 std_var_num = Trail_NumBindings;
00544 trieType = TSTN_TrieType(tstRoot);
00545
00546
00547
00548 if ( symbol == NO_INSERT_SYMBOL )
00549 ProcessNextSubtermFromTrieStacks(symbol,std_var_num);
00550
00551 if ( IsNULL(TSTN_Child(lastMatch)) )
00552 lastMatch = tstnAddSymbol(CTXTc lastMatch,symbol,trieType);
00553 else if ( IsHashHeader(TSTN_Child(lastMatch)) )
00554 lastMatch = tsthtInsertSymbol(CTXTc lastMatch,symbol,trieType,maintainTSI);
00555 else
00556 lastMatch = tstnInsertSymbol(CTXTc lastMatch,symbol,trieType,tstRoot,
00557 maintainTSI);
00558
00559
00560
00561 while ( ! TermStack_IsEmpty ) {
00562 ProcessNextSubtermFromTrieStacks(symbol,std_var_num);
00563 lastMatch = tstnAddSymbol(CTXTc lastMatch,symbol,trieType);
00564 }
00565 update_timestamps(lastMatch,tstRoot,maintainTSI);
00566 MakeLeafNode(lastMatch);
00567 TN_UpgradeInstrTypeToSUCCESS(lastMatch,TrieSymbolType(symbol));
00568 return lastMatch;
00569 }
00570
00571
00572
00573
00574 BTNptr bt_insert(CTXTdeclc BTNptr btRoot, BTNptr lastMatch, Cell firstSymbol) {
00575
00576 Cell symbol;
00577 int std_var_num;
00578 int trieType;
00579
00580
00581 symbol = firstSymbol;
00582 std_var_num = Trail_NumBindings;
00583 trieType = BTN_TrieType(btRoot);
00584
00585
00586
00587 if ( symbol == NO_INSERT_SYMBOL )
00588 ProcessNextSubtermFromTrieStacks(symbol,std_var_num);
00589
00590 if ( IsNULL(BTN_Child(lastMatch)) )
00591 lastMatch = btnAddSymbol(CTXTc lastMatch,symbol,trieType);
00592 else if ( IsHashHeader(BTN_Child(lastMatch)) )
00593 lastMatch = bthtInsertSymbol(CTXTc lastMatch,symbol,trieType);
00594 else
00595 lastMatch = btnInsertSymbol(CTXTc lastMatch,symbol,trieType);
00596
00597
00598
00599 while ( ! TermStack_IsEmpty ) {
00600 ProcessNextSubtermFromTrieStacks(symbol,std_var_num);
00601 lastMatch = btnAddSymbol(CTXTc lastMatch,symbol,trieType);
00602 }
00603 MakeLeafNode(lastMatch);
00604 TN_UpgradeInstrTypeToSUCCESS(lastMatch,TrieSymbolType(symbol));
00605 return lastMatch;
00606 }
00607
00608