- #include <stdio.h> 
- #include <stdlib.h> 
-   
- #include "mhmt-types.h" 
- #include "mhmt-globals.h" 
- #include "mhmt-tb.h" 
-   
- // entry for twobyters search and add 
- struct tb_chain * tb_entry[65536]; 
-   
- struct tb_chain * tb_free; // linked list of freed tb_chain entries - NULL at the beginning 
-   
- struct tb_bunch * tb_bunches; // all allocated bunches as linked list 
-   
-   
-   
-   
- void init_tb(void) 
- { 
-         ULONG i; 
-   
-         tb_free=NULL;    // init linked list of free tb_chain elements 
-         tb_bunches=NULL; // no bunches already allocated 
-   
-         for(i=0;i<65536;i++) // init array of 2-byte match pointers 
-         { 
-                 tb_entry[i]=NULL; 
-         } 
- } 
-   
-   
- void free_tb(void) 
- { 
-         // free all allocated bunches 
-   
-         struct tb_bunch * tbtmp; 
-   
-         while( tb_bunches ) 
-         { 
-                 tbtmp=tb_bunches; 
-                 tb_bunches=tb_bunches->next; 
-         } 
- } 
-   
- // addw new twobyter: 
- // index=(prev<<8)+curr - index into tb_entry, 
- // position - position in input file for 'curr' byte 
- // returns zero if any error (cant allocate mem), otherwise 1 
- ULONG add_tb(UWORD index, OFFSET position) 
- { 
-         struct tb_chain * newtb; 
-   
-         newtb=get_free_tb(); 
-         if( !newtb ) 
-         { // no free elements 
-   
-                 if( (OFFSET)(position+wrk.prelen) > (OFFSET)wrk.maxwin ) // if there could be enough tbs to try to flush 
-                 { 
-                         // try to flush current chain 
-                         cutoff_tb_chain(index,position); 
-                 } 
-   
-                 newtb=get_free_tb(); 
-                 if( !newtb ) 
-                 { // nothing free - allocate new bunch 
-                         if( !add_bunch_of_tb() ) 
-                         { 
-                                 return 0; 
-                         } 
-   
-                         newtb=get_free_tb(); // here is no chance to fail!... hopefully... 
-                 } 
-   
-         } 
-   
-   
-   
-         newtb->pos=position-1; // points to the first byte of given two bytes 
-         newtb->next=tb_entry[index]; 
-         tb_entry[index]=newtb; 
-   
-   
-         return 1; 
- } 
-   
-   
- // shorten given twobyter chain to have only actual (<wrk.maxwin old) elements, giving some free elements to reuse 
- void cutoff_tb_chain(UWORD index,OFFSET position) 
- { 
-         struct tb_chain * curr, * prev; 
-   
-   
-         curr=tb_entry[index]; 
-         if( !curr ) return; // if nothing to remove 
-   
-   
-         // see if we should delete some elements after first element in the given chain 
-         prev=curr; 
-         curr=curr->next; 
-   
-         while( curr ) 
-         { 
-                 if( (position-(curr->pos)) > (OFFSET)wrk.maxwin ) // found some old element: delete rest of chain along with it 
-                 { 
-                         // find end of chain 
-                         while( curr->next ) 
-                         { 
-                                 curr = curr->next; 
-                         } 
-   
-                         // now curr - last chain element, prev->next - beginning of orphaned chain 
-                         // add orphaned chain to free list 
-                         curr->next = tb_free; 
-                         tb_free = prev->next; 
-   
-                         prev->next = NULL; // cut off chain 
-   
-                         break; 
-                 } 
-                 else 
-                 { 
-                         prev=curr; 
-                         curr=curr->next; 
-                 } 
-         } 
-   
-         // delete first (entry) element in chain if needed (in this case, all subsequent els are already deleted) 
-         curr=tb_entry[index]; 
-         if( (position-(curr->pos)) > (OFFSET)wrk.maxwin ) 
-         { 
-                 tb_entry[index] = NULL; 
-   
-                 curr->next=tb_free; // element goes to free list 
-                 tb_free=curr; 
-         } 
- } 
-   
-   
- // adds new bunch of TBs when needed 
- // zero - error 
- ULONG add_bunch_of_tb(void) 
- { 
-         ULONG i; 
-         struct tb_bunch * newbunch; 
-   
-         // alloc new bunch 
-         newbunch =(struct-  tb_bunch  *)malloc( sizeof(struct-  tb_bunch ) );
-         if( !newbunch ) return 0; 
-   
-         // link every twobyter into one list 
-         for(i=0;i<(BUNCHSIZE-1);i++) 
-         { 
-                 newbunch->bunch[i].next=&(newbunch->bunch[i+1]); 
-         } 
-   
-         // add this list to the free list 
-         newbunch->bunch[BUNCHSIZE-1].next=tb_free; 
-         tb_free=&(newbunch->bunch[0]); 
-   
-         // add bunch to bunches list 
-         newbunch->next=tb_bunches; 
-         tb_bunches=newbunch; 
-   
-         return 1; 
- } 
-   
-   
- // find free tb, if any, otherwise NULL 
- struct tb_chain * get_free_tb(void) 
- { 
-         struct tb_chain * newtb; 
-   
-         if( tb_free ) 
-         { 
-                 newtb=tb_free; 
-                 tb_free=tb_free->next; 
-   
-                 return newtb; 
-         } 
-         else 
-         { 
-                 return NULL; 
-         } 
- } 
-   
-