/ Check-in [c5ed5ebd]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Change the (machine-generated) keywordhash.h file to increase the scope of the tables used for keyword matching, so that the tables are accessible to functions other then keywordCode().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: c5ed5ebdf660501fde7cc8aefaaaeae2a68e5899a64ac93f26684842a235281d
User & Date: drh 2017-07-06 16:33:14
Context
2017-07-06
22:43
Small adjustment to main.mk that facilitates giving non-standard compile-time options to the shell. check-in: 7c7d53a9 user: drh tags: trunk
17:36
Initial implementation of a highly experimental interface for listing all keywords and symbolic names for an SQLite database connection. check-in: 04ef6783 user: drh tags: experimental-namelist
16:33
Change the (machine-generated) keywordhash.h file to increase the scope of the tables used for keyword matching, so that the tables are accessible to functions other then keywordCode(). check-in: c5ed5ebd user: drh tags: trunk
13:51
More compact implementation of the typeof() SQL function. check-in: efb4aab0 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to tool/mkkeywordhash.c.

   332    332   */
   333    333   int main(int argc, char **argv){
   334    334     int i, j, k, h;
   335    335     int bestSize, bestCount;
   336    336     int count;
   337    337     int nChar;
   338    338     int totalLen = 0;
   339         -  int aHash[1000];  /* 1000 is much bigger than nKeyword */
   340         -  char zText[2000];
          339  +  int aKWHash[1000];  /* 1000 is much bigger than nKeyword */
          340  +  char zKWText[2000];
   341    341   
   342    342     /* Remove entries from the list of keywords that have mask==0 */
   343    343     for(i=j=0; i<nKeyword; i++){
   344    344       if( aKeywordTable[i].mask==0 ) continue;
   345    345       if( j<i ){
   346    346         aKeywordTable[j] = aKeywordTable[i];
   347    347       }
................................................................................
   437    437     qsort(aKeywordTable, nKeyword, sizeof(aKeywordTable[0]), keywordCompare3);
   438    438   
   439    439     /* Figure out how big to make the hash table in order to minimize the
   440    440     ** number of collisions */
   441    441     bestSize = nKeyword;
   442    442     bestCount = nKeyword*nKeyword;
   443    443     for(i=nKeyword/2; i<=2*nKeyword; i++){
   444         -    for(j=0; j<i; j++) aHash[j] = 0;
          444  +    for(j=0; j<i; j++) aKWHash[j] = 0;
   445    445       for(j=0; j<nKeyword; j++){
   446    446         h = aKeywordTable[j].hash % i;
   447         -      aHash[h] *= 2;
   448         -      aHash[h]++;
          447  +      aKWHash[h] *= 2;
          448  +      aKWHash[h]++;
   449    449       }
   450         -    for(j=count=0; j<i; j++) count += aHash[j];
          450  +    for(j=count=0; j<i; j++) count += aKWHash[j];
   451    451       if( count<bestCount ){
   452    452         bestCount = count;
   453    453         bestSize = i;
   454    454       }
   455    455     }
   456    456   
   457    457     /* Compute the hash */
   458         -  for(i=0; i<bestSize; i++) aHash[i] = 0;
          458  +  for(i=0; i<bestSize; i++) aKWHash[i] = 0;
   459    459     for(i=0; i<nKeyword; i++){
   460    460       h = aKeywordTable[i].hash % bestSize;
   461         -    aKeywordTable[i].iNext = aHash[h];
   462         -    aHash[h] = i+1;
          461  +    aKeywordTable[i].iNext = aKWHash[h];
          462  +    aKWHash[h] = i+1;
   463    463     }
   464    464   
   465    465     /* Begin generating code */
   466    466     printf("%s", zHdr);
   467    467     printf("/* Hash score: %d */\n", bestCount);
   468         -  printf("static int keywordCode(const char *z, int n, int *pType){\n");
   469         -  printf("  /* zText[] encodes %d bytes of keywords in %d bytes */\n",
          468  +  printf("/* zKWText[] encodes %d bytes of keyword text in %d bytes */\n",
   470    469             totalLen + nKeyword, nChar+1 );
   471    470     for(i=j=k=0; i<nKeyword; i++){
   472    471       Keyword *p = &aKeywordTable[i];
   473    472       if( p->substrId ) continue;
   474         -    memcpy(&zText[k], p->zName, p->len);
          473  +    memcpy(&zKWText[k], p->zName, p->len);
   475    474       k += p->len;
   476    475       if( j+p->len>70 ){
   477    476         printf("%*s */\n", 74-j, "");
   478    477         j = 0;
   479    478       }
   480    479       if( j==0 ){
   481         -      printf("  /*   ");
          480  +      printf("/*   ");
   482    481         j = 8;
   483    482       }
   484    483       printf("%s", p->zName);
   485    484       j += p->len;
   486    485     }
   487    486     if( j>0 ){
   488    487       printf("%*s */\n", 74-j, "");
   489    488     }
   490         -  printf("  static const char zText[%d] = {\n", nChar);
   491         -  zText[nChar] = 0;
          489  +  printf("static const char zKWText[%d] = {\n", nChar);
          490  +  zKWText[nChar] = 0;
   492    491     for(i=j=0; i<k; i++){
   493    492       if( j==0 ){
   494         -      printf("    ");
          493  +      printf("  ");
   495    494       }
   496         -    if( zText[i]==0 ){
          495  +    if( zKWText[i]==0 ){
   497    496         printf("0");
   498    497       }else{
   499         -      printf("'%c',", zText[i]);
          498  +      printf("'%c',", zKWText[i]);
   500    499       }
   501    500       j += 4;
   502    501       if( j>68 ){
   503    502         printf("\n");
   504    503         j = 0;
   505    504       }
   506    505     }
   507    506     if( j>0 ) printf("\n");
   508         -  printf("  };\n");
          507  +  printf("};\n");
   509    508   
   510         -  printf("  static const unsigned char aHash[%d] = {\n", bestSize);
          509  +  printf("/* aKWHash[i] is the hash value for the i-th keyword */\n");
          510  +  printf("static const unsigned char aKWHash[%d] = {\n", bestSize);
   511    511     for(i=j=0; i<bestSize; i++){
   512         -    if( j==0 ) printf("    ");
   513         -    printf(" %3d,", aHash[i]);
          512  +    if( j==0 ) printf("  ");
          513  +    printf(" %3d,", aKWHash[i]);
   514    514       j++;
   515    515       if( j>12 ){
   516    516         printf("\n");
   517    517         j = 0;
   518    518       }
   519    519     }
   520         -  printf("%s  };\n", j==0 ? "" : "\n");    
          520  +  printf("%s};\n", j==0 ? "" : "\n");    
   521    521   
   522         -  printf("  static const unsigned char aNext[%d] = {\n", nKeyword);
          522  +  printf("/* aKWNext[] forms the hash collision chain.  If aKWHash[i]==0\n");
          523  +  printf("** then the i-th keyword has no more hash collisions.  Otherwise,\n");
          524  +  printf("** the next keyword with the same hash is aKWHash[i]-1. */\n");
          525  +  printf("static const unsigned char aKWNext[%d] = {\n", nKeyword);
   523    526     for(i=j=0; i<nKeyword; i++){
   524         -    if( j==0 ) printf("    ");
          527  +    if( j==0 ) printf("  ");
   525    528       printf(" %3d,", aKeywordTable[i].iNext);
   526    529       j++;
   527    530       if( j>12 ){
   528    531         printf("\n");
   529    532         j = 0;
   530    533       }
   531    534     }
   532         -  printf("%s  };\n", j==0 ? "" : "\n");    
          535  +  printf("%s};\n", j==0 ? "" : "\n");    
   533    536   
   534         -  printf("  static const unsigned char aLen[%d] = {\n", nKeyword);
          537  +  printf("/* aKWLen[i] is the length (in bytes) of the i-th keyword */\n");
          538  +  printf("static const unsigned char aKWLen[%d] = {\n", nKeyword);
   535    539     for(i=j=0; i<nKeyword; i++){
   536         -    if( j==0 ) printf("    ");
          540  +    if( j==0 ) printf("  ");
   537    541       printf(" %3d,", aKeywordTable[i].len+aKeywordTable[i].prefix);
   538    542       j++;
   539    543       if( j>12 ){
   540    544         printf("\n");
   541    545         j = 0;
   542    546       }
   543    547     }
   544         -  printf("%s  };\n", j==0 ? "" : "\n");    
          548  +  printf("%s};\n", j==0 ? "" : "\n");    
   545    549   
   546         -  printf("  static const unsigned short int aOffset[%d] = {\n", nKeyword);
          550  +  printf("/* aKWOffset[i] is the index into zKWText[] of the start of\n");
          551  +  printf("** the text for the i-th keyword. */\n");
          552  +  printf("static const unsigned short int aKWOffset[%d] = {\n", nKeyword);
   547    553     for(i=j=0; i<nKeyword; i++){
   548         -    if( j==0 ) printf("    ");
          554  +    if( j==0 ) printf("  ");
   549    555       printf(" %3d,", aKeywordTable[i].offset);
   550    556       j++;
   551    557       if( j>12 ){
   552    558         printf("\n");
   553    559         j = 0;
   554    560       }
   555    561     }
   556         -  printf("%s  };\n", j==0 ? "" : "\n");
          562  +  printf("%s};\n", j==0 ? "" : "\n");
   557    563   
   558         -  printf("  static const unsigned char aCode[%d] = {\n", nKeyword);
          564  +  printf("/* aKWCode[i] is the parser symbol code for the i-th keyword */\n");
          565  +  printf("static const unsigned char aKWCode[%d] = {\n", nKeyword);
   559    566     for(i=j=0; i<nKeyword; i++){
   560    567       char *zToken = aKeywordTable[i].zTokenType;
   561         -    if( j==0 ) printf("    ");
          568  +    if( j==0 ) printf("  ");
   562    569       printf("%s,%*s", zToken, (int)(14-strlen(zToken)), "");
   563    570       j++;
   564    571       if( j>=5 ){
   565    572         printf("\n");
   566    573         j = 0;
   567    574       }
   568    575     }
   569         -  printf("%s  };\n", j==0 ? "" : "\n");
   570         -
          576  +  printf("%s};\n", j==0 ? "" : "\n");
          577  +  printf("/* Check to see if z[0..n-1] is a keyword. If it is, write the\n");
          578  +  printf("** parser symbol code for that keyword into *pType.  Always\n");
          579  +  printf("** return the integer n (the length of the token). */\n");
          580  +  printf("static int keywordCode(const char *z, int n, int *pType){\n");
   571    581     printf("  int i, j;\n");
   572    582     printf("  const char *zKW;\n");
   573    583     printf("  if( n>=2 ){\n");
   574    584     printf("    i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) %% %d;\n",
   575    585             bestSize);
   576         -  printf("    for(i=((int)aHash[i])-1; i>=0; i=((int)aNext[i])-1){\n");
   577         -  printf("      if( aLen[i]!=n ) continue;\n");
          586  +  printf("    for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){\n");
          587  +  printf("      if( aKWLen[i]!=n ) continue;\n");
   578    588     printf("      j = 0;\n");
   579         -  printf("      zKW = &zText[aOffset[i]];\n");
          589  +  printf("      zKW = &zKWText[aKWOffset[i]];\n");
   580    590     printf("#ifdef SQLITE_ASCII\n");
   581    591     printf("      while( j<n && (z[j]&~0x20)==zKW[j] ){ j++; }\n");
   582    592     printf("#endif\n");
   583    593     printf("#ifdef SQLITE_EBCDIC\n");
   584    594     printf("      while( j<n && toupper(z[j])==zKW[j] ){ j++; }\n");
   585    595     printf("#endif\n");
   586    596     printf("      if( j<n ) continue;\n");
   587    597     for(i=0; i<nKeyword; i++){
   588    598       printf("      testcase( i==%d ); /* %s */\n",
   589    599              i, aKeywordTable[i].zOrigName);
   590    600     }
   591         -  printf("      *pType = aCode[i];\n");
          601  +  printf("      *pType = aKWCode[i];\n");
   592    602     printf("      break;\n");
   593    603     printf("    }\n");
   594    604     printf("  }\n");
   595    605     printf("  return n;\n");
   596    606     printf("}\n");
   597    607     printf("int sqlite3KeywordCode(const unsigned char *z, int n){\n");
   598    608     printf("  int id = TK_ID;\n");