liter.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:11k
源码类别:

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  liter.c - library for literal processing of GNU SQL compiler
  3.  *
  4.  *  This file is a part of GNU SQL Server
  5.  *
  6.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  7.  *  Developed at the Institute of System Programming
  8.  *  This file is written by Michael Kimelman
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23.  *
  24.  *  Contact: gss@ispras.ru
  25.  *
  26.  */
  27. /* $Id: liter.c,v 1.245 1997/03/31 03:46:38 kml Exp $ */
  28. #include "liter.h"
  29. #include "trlinter.h"
  30. #include "xmem.h"
  31. #define HASH_SECTION_SIZE  64
  32. typedef struct hash_elem{
  33.   LTRLREF ptr;
  34.   word    code;
  35.   i2_t   next;
  36.   word    leng;
  37. } HE;
  38. typedef struct hash_sect {
  39.   TXTREF            next_sect;
  40.   i4_t               sect_num;
  41.   HE                sect[HASH_SECTION_SIZE];
  42. } *HASH;
  43. #define HASHTBL *Root_ptr(Hash_Tbl)
  44. static  LTRLREF lptr   =0;
  45. static  i4_t     l_hcode=-1;
  46. /* hash statistics - needed for smart hashing - right now it looks far from it */
  47. static  i4_t    *h_stat = NULL;  
  48. static  LTRLREF add_ltr __P((char *liter));
  49. static  TXTREF  new_sect __P((i4_t sn));
  50. static  word    hashcode __P((char *liter));
  51. static  LTRLREF hash __P((char *string));
  52. static  LTRLREF Hash(char *string,byte *new); /* new is return code */
  53. /* 1 - new literal    */
  54. /* 0 - old literal    */
  55. static void
  56. seg_switch(i4_t to_tree)
  57. {
  58.   static VADR hold_seg=TNULL;
  59.   if ( (to_tree && hold_seg) || (to_tree==0 && hold_seg==TNULL))
  60.     return;
  61.   if ( to_tree )
  62.     {
  63.       hold_seg = GET_CURRENT_SEGMENT_ID;
  64.       switch_to_segment( *Root_ptr(Current_Tree_Segment) );
  65.     }
  66.   else
  67.     {
  68.       switch_to_segment( hold_seg );
  69.       hold_seg = TNULL;
  70.     }
  71. }
  72. static LTRLREF 
  73. hash(char *string)
  74. {
  75.   byte new;
  76.   return  Hash(string,&new);
  77. }
  78. static LTRLREF 
  79. Hash(char *string,byte *new)
  80. {
  81.   HASH ptrc,ptr0=NULL;
  82.   word indc,ind0=0;
  83.   word  l,code;
  84.   HE e;
  85.   *new=0;
  86.   if (lptr)
  87.     {
  88.       l = strlen(STRING(lptr));
  89.       code = l_hcode;
  90.     }
  91.   else
  92.     {
  93.       if(string==NULL)
  94.         {
  95.           yyerror("Internal error in hash.c: NULL literal");
  96.           return TNULL;
  97.         }
  98.       l=strlen(string);
  99.       if(l==0)
  100.         {
  101.           yyerror("Internal error in hash.c: dummy literal");
  102.           return TNULL;
  103.         }
  104.       code=(lptr?l_hcode:hashcode(string));
  105.     }
  106.   
  107.   indc=code;
  108.   if( (HASHTBL) == TNULL)
  109.     HASHTBL=new_sect(0);
  110.   ptrc=(HASH)vpointer(HASHTBL);
  111.   while( (ptrc->sect[indc].ptr!=TNULL)
  112.    && (ptrc->sect[indc].code!=code)
  113.     )
  114.     {
  115.       indc=++indc % HASH_SECTION_SIZE;
  116.       if(indc==code)
  117.         {
  118.           if(ptrc->next_sect==TNULL)
  119.             ptrc->next_sect=new_sect(ptrc->sect_num+1);
  120.           ptrc=(HASH)vpointer(ptrc->next_sect);
  121.         }
  122.     }
  123.   while(1)
  124.     {
  125.       e=ptrc->sect[indc];
  126.       if(e.ptr==TNULL)    /* free hole */
  127.         {
  128.           if(lptr)
  129.             e.ptr=lptr;
  130.           else  
  131.             e.ptr=add_ltr(string);
  132.           e.leng=l;
  133.           e.code=code;
  134.   e.next=-1;
  135.           *new=1;
  136.           h_stat[code]++;
  137.           if(ptr0)
  138.             ptr0->sect[ind0].next=indc+ptrc->sect_num*HASH_SECTION_SIZE;
  139.           ptrc->sect[indc]=e;
  140.           return e.ptr;
  141.         }
  142.       if(lptr)
  143.         {
  144.           if(e.ptr==lptr)
  145.             return e.ptr;
  146.         }
  147.       else
  148.         if(e.leng==l)
  149.           if(0==strcmp(STRING(e.ptr),string))
  150.             return e.ptr;
  151.       ind0=indc;
  152.       ptr0=ptrc;
  153.       if(e.next >= 0 )
  154.         { /* test next literal with same code */
  155.           indc=e.next-HASH_SECTION_SIZE*ptrc->sect_num;
  156.           while(indc>HASH_SECTION_SIZE)
  157.             {
  158.               indc-=HASH_SECTION_SIZE;
  159.               ptrc=(HASH)vpointer(ptrc->next_sect);
  160.             }
  161.         }
  162.       else
  163.         {        /* find free space */
  164.           while(ptrc->next_sect)
  165.     ptrc=(HASH)vpointer(ptrc->next_sect);
  166.           indc=code;
  167.           while( ptrc->sect[indc].ptr!=TNULL)
  168.             {
  169.               indc=++indc % HASH_SECTION_SIZE;
  170.               if(indc==code)
  171. {
  172.   ptrc->next_sect=new_sect(ptrc->sect_num+1);
  173.   ptrc=(HASH)vpointer(ptrc->next_sect);
  174. }
  175.             }
  176.         } /* else */
  177.     } /* while(1) */
  178.   /* unreached    */
  179.   /* return NULL; */
  180. }
  181. static int
  182. restruct_hash(i4_t rc)
  183. {
  184.   struct {
  185.     LTRLREF l;
  186.     i4_t     c;
  187.   }  sv[HASH_SECTION_SIZE];
  188.   
  189.   HASH ptrc = NULL;
  190.   word indc = 0;
  191.   LTRLREF l = lptr;
  192.   
  193.   if(!rc)
  194.     return 0;
  195.   
  196.   for ( ptrc=(HASH)vpointer(HASHTBL); ptrc; ptrc = (HASH)vpointer(ptrc->next_sect))
  197.     {
  198.       for( indc = 0 ; indc < HASH_SECTION_SIZE; indc ++)
  199.         {
  200.           sv[indc].l = ptrc->sect[indc].ptr;
  201.           sv[indc].c = ptrc->sect[indc].code;
  202.           ptrc->sect[indc].ptr = TNULL;
  203.         }
  204.       for( indc = 0 ; indc < HASH_SECTION_SIZE; indc ++)
  205.         if(sv[indc].l)
  206.           {
  207.             lptr    = sv[indc].l;
  208.             l_hcode = sv[indc].c;
  209.             hash(STRING(lptr));
  210.             lptr    = l;
  211.           }
  212.     }
  213.   return 0;
  214. }
  215. static word
  216. hashcode(char *s)
  217. {
  218.   typedef struct hc {
  219.     i4_t        l_pos;
  220.     i4_t        shift;
  221.     struct hc *next;
  222.   } hc_t;
  223.   static byte  hcode=0;
  224.   static byte  code[256];
  225.   static hc_t *h_rule = NULL;
  226.   static i4_t   h_wight = 0;
  227.   
  228.   word  rc=0;
  229.   i4_t   p;
  230.   hc_t *hc_c;
  231.   
  232.   if(hcode==0)
  233.     {
  234.       i4_t   wight,i;
  235.       hc_t *ch;
  236.       
  237.       for(i=256;i--;)code[i]=0;
  238.       code['_']=++hcode;
  239.       for(i='0';i<='9';i++) code[i]=++hcode;
  240.       for(i='A';i<='Z';i++) code[i]=++hcode;
  241.       for(i='a';i<='z';i++) code[i]=++hcode;
  242.       /* hcode==61 ~~ 6 bit */
  243.       for(i=0;hcode>(1<<i);i++);
  244.       hcode=i;
  245.       h_rule = (hc_t*)xmalloc(sizeof(hc_t));
  246.       wight = 1<<hcode;
  247.       while (wight > HASH_SECTION_SIZE)
  248.         {
  249.           h_rule->shift --;
  250.           wight >>=1;
  251.         }
  252.       while (2*wight < HASH_SECTION_SIZE)
  253.         {
  254.           h_rule->shift ++;
  255.           wight <<=1;
  256.         }
  257.       for(ch = h_rule; ch->shift > hcode ; ch = ch->next)
  258.         {
  259.           ch->next = (hc_t*)xmalloc(sizeof(hc_t));
  260.           ch->next->l_pos = ch->l_pos + 1;
  261.           ch->next->shift = ch->shift - hcode;
  262.         }
  263.       if (h_wight!=wight)
  264.         {
  265.           if(h_wight==0)
  266.             h_stat = (i4_t*)xmalloc(wight*sizeof(i4_t));
  267.           else
  268.             h_stat = (i4_t*)xrealloc((void*)h_stat,wight*sizeof(i4_t));
  269.           h_wight = wight;
  270.         }
  271.     }
  272.   while(s==0) /* request for check hash althorithm effectiveness */
  273.     {
  274.       i4_t imax,i;
  275.       float avg, d2,d, maxx;
  276.       hc_t *ch;
  277.       
  278.       for (avg = i = 0 ; i < h_wight; i++)
  279.         avg += h_stat[i];
  280.       avg /= h_wight;
  281.       for (d2 = i = 0 ; i < h_wight; i++)
  282.         { d = (h_stat[i] - avg)/avg; d2 = d*d; }
  283.       d2 /= h_wight;
  284.       if ( d2 < 0.04 ) /* if fluctuation is ok - just exit  */
  285.         return restruct_hash(rc);
  286.       if (rc > 10)
  287.         {
  288.           yyerror("cycle in hash beautification process");
  289.           return restruct_hash(rc);
  290.         }
  291.       rc ++; /* we begin hash althorithm modification */
  292.       /* fluctuation in hashing is too much - we shall to do intellectual correctness  */
  293.       /* because 'intellectual' is too difficult  - let's do anything */
  294.       /* weighted strengh */
  295.       for(maxx = imax = i = 0; i < h_wight; i ++)
  296.         {
  297.           i4_t j;
  298.           if (i != imax)
  299.             for(j = 256; i--; )
  300.               if (code[j] == (i>>h_rule->shift))
  301.                 code[j] = imax;
  302.           maxx += h_stat[i]/avg;
  303.           imax = maxx + 0.5;
  304.         }
  305.       if(d2 > 0.1) /* if dispersion is huge */
  306.         { /* let's try one more way */
  307.           if ( !h_rule->next || h_rule->next->l_pos > h_rule->l_pos+1)
  308.             { /* let's compute value by pair of symbol */
  309.               hc_t *cch = (hc_t*)xmalloc(sizeof(hc_t));
  310.               cch->next = h_rule;
  311.               cch->l_pos = h_rule->l_pos;
  312.               h_rule->l_pos++;
  313.               h_rule->shift --;
  314.               cch->shift = h_rule->shift;
  315.               h_rule = cch;
  316.             }
  317.           else
  318.             for(ch = h_rule; ch; ch = ch->next) 
  319.               ch->l_pos++;
  320.         }
  321.       for ( i  = 0; i < h_wight; i++)
  322.         h_stat[i] = 0;
  323.       {
  324.         HASH ptrc = NULL;
  325.         word indc = 0;
  326.         for ( ptrc=(HASH)vpointer(HASHTBL); ptrc; ptrc = (HASH)vpointer(ptrc->next_sect))
  327.           for( indc = 0 ; indc < HASH_SECTION_SIZE; indc ++)
  328.             if (ptrc->sect[indc].ptr!=TNULL)
  329.               h_stat [ptrc->sect[indc].code=hashcode(STRING(ptrc->sect[indc].ptr))]++;
  330.       }
  331.     }
  332.   
  333.   for(p=0,hc_c = h_rule; hc_c; hc_c = hc_c->next)
  334.     {
  335.       while (p<hc_c->l_pos && s[p]) p++;
  336.       if (p < hc_c->l_pos && p>0)
  337.         p--;
  338.       rc += code[(byte)(s[p])] << hc_c->shift;
  339.     }
  340.   
  341.   return rc % h_wight;
  342. }
  343. static TXTREF
  344. new_sect(i4_t sn)
  345. {
  346.   word   size = sizeof(struct hash_sect);
  347.   i4_t    i;
  348.   TXTREF new_sect;
  349.   
  350.   seg_switch(1);
  351.   new_sect = vmalloc(size)+ GET_CURRENT_SEGMENT_ID;
  352.   ((HASH)vpointer(new_sect))->sect_num=sn;
  353.   register_relocation_address(new_sect); /* next_sect */
  354.   for(i=0;i<HASH_SECTION_SIZE;i++)
  355.     register_relocation_address(new_sect + sizeof(TXTREF) + sizeof(i4_t) +
  356.                                 i*sizeof (HE) );
  357.   seg_switch(0);
  358.   return new_sect;
  359. }
  360. void
  361. free_hash(void)
  362. {
  363.   TXTREF h;
  364.   i4_t  i;
  365.   seg_switch(1);
  366.   while(HASHTBL)
  367.     {
  368.       h=HASHTBL;
  369.       HASHTBL=((HASH)vpointer(h))->next_sect;
  370.       for(i=0;i<HASH_SECTION_SIZE;i++)
  371.           vmfree(((HASH)vpointer(h))->sect[i].ptr);
  372.       vmfree(h);
  373.     }
  374.   seg_switch(0);
  375. }
  376. int
  377. load_hash(LTRLREF l)                         /* load LITERAL to hash */
  378. {                                            /* table                */
  379.   lptr=l;
  380.   if(l != hash(STRING(l)) )
  381.     {
  382.       fprintf(stderr,
  383.               "n%s:%d: Internal error in call function load_hash(%s)n",
  384.               __FILE__,__LINE__,STRING(l));
  385.       yyfatal("Abort");
  386.     }
  387.   lptr=0;
  388.   return 0;
  389. }
  390. LTRLREF
  391. ltr_rec(char *liter)
  392. {
  393.   return hash(liter);
  394. }
  395. static LTRLREF
  396. add_ltr(char *liter)
  397. {
  398.   VADR p;
  399.   seg_switch(1);
  400.   p=vm_ob_alloc(strlen(liter)+1,1)+GET_CURRENT_SEGMENT_ID;
  401.   seg_switch(0);
  402.   strcpy((char*)vpointer(p),liter);
  403.   return (LTRLREF)p;
  404. }
  405. char *
  406. ltrlref_to_string(register LTRLREF l)
  407. {
  408.   char *ptr;
  409.   ptr = (char*)vpointer(l);
  410.   if(!ptr)
  411.     return "";
  412.   return ptr;
  413. }