/[bison]/bison/lib/lbitset.c
ViewVC logotype

Diff of /bison/lib/lbitset.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.11 by eggert, Sat May 24 19:16:02 2003 UTC revision 1.12 by eggert, Tue Jun 17 07:24:40 2003 UTC
# Line 26  Line 26 
26  #include <stddef.h>  #include <stddef.h>
27  #include <stdlib.h>  #include <stdlib.h>
28  #include <stdio.h>  #include <stdio.h>
29    #include <string.h>
30    
31  /* This file implements linked-list bitsets.  These bitsets can be of  /* This file implements linked-list bitsets.  These bitsets can be of
32     arbitrary length and are more efficient than arrays of bits for     arbitrary length and are more efficient than arrays of bits for
# Line 40  Line 41 
41  /* Number of words to use for each element.  The larger the value the  /* Number of words to use for each element.  The larger the value the
42     greater the size of the cache and the shorter the time to find a given bit     greater the size of the cache and the shorter the time to find a given bit
43     but the more memory wasted for sparse bitsets and the longer the time     but the more memory wasted for sparse bitsets and the longer the time
44     to search for set bits.  */     to search for set bits.
45    
46       The routines that dominate timing profiles are lbitset_elt_find
47       and lbitset_elt_link, especially when accessing the bits randomly.  */
48    
49  #define LBITSET_ELT_WORDS 2  #define LBITSET_ELT_WORDS 2
50    
# Line 502  lbitset_copy_cmp (bitset dst, bitset src Line 506  lbitset_copy_cmp (bitset dst, bitset src
506  }  }
507    
508    
 /* Return size in bits of bitset SRC.  */  
509  static bitset_bindex  static bitset_bindex
510  lbitset_size (bitset src)  lbitset_resize (bitset src, bitset_bindex size)
511  {  {
512    lbitset_elt *elt;      BITSET_NBITS_ (src) = size;
   
   elt = LBITSET_TAIL (src);  
   if (!elt)  
     return 0;  
513    
514    /* Return current size of bitset in bits.  */      /* Need to prune any excess bits.  FIXME.  */
515    return (elt->index + LBITSET_ELT_WORDS) * BITSET_WORD_BITS;      return size;
516  }  }
517    
   
518  /* Set bit BITNO in bitset DST.  */  /* Set bit BITNO in bitset DST.  */
519  static void  static void
520  lbitset_set (bitset dst, bitset_bindex bitno)  lbitset_set (bitset dst, bitset_bindex bitno)
# Line 867  lbitset_list (bitset bset, bitset_bindex Line 865  lbitset_list (bitset bset, bitset_bindex
865  static bool  static bool
866  lbitset_empty_p (bitset dst)  lbitset_empty_p (bitset dst)
867  {  {
868    lbitset_weed (dst);    lbitset_elt *elt;
869    return !LBITSET_HEAD (dst);    lbitset_elt *next;
870    
871      for (elt = LBITSET_HEAD (dst); elt; elt = next)
872        {
873          next = elt->next;
874          if (!lbitset_elt_zero_p (elt))
875            return 0;
876          /* Weed as we go.  */
877          lbitset_elt_unlink (dst, elt);
878        }
879    
880      return 1;
881    }
882    
883    
884    /* Ensure that any unused bits within the last element are clear.  */
885    static inline void
886    lbitset_unused_clear (bitset dst)
887    {
888      unsigned int last_bit;
889      bitset_bindex n_bits;
890    
891      n_bits = BITSET_SIZE_ (dst);
892      last_bit = n_bits % LBITSET_ELT_BITS;
893      
894      if (last_bit)
895        {
896          lbitset_elt *elt;
897          bitset_windex windex;
898          bitset_word *srcp;
899          
900          elt = LBITSET_TAIL (dst);
901          srcp = elt->words;
902          windex = n_bits / BITSET_WORD_BITS;
903      
904          srcp[windex - elt->index] &= ((bitset_word) 1 << last_bit) - 1;    
905          windex++;
906    
907          for (; (windex - elt->index) < LBITSET_ELT_WORDS; windex++)
908            srcp[windex - elt->index] = 0;
909        }
910  }  }
911    
912    
# Line 883  lbitset_ones (bitset dst) Line 921  lbitset_ones (bitset dst)
921        bitset!  It makes a sparse bitset become dense.  An alternative        bitset!  It makes a sparse bitset become dense.  An alternative
922        is to have a flag that indicates that the bitset stores the        is to have a flag that indicates that the bitset stores the
923        complement of what it indicates.  */        complement of what it indicates.  */
   elt = LBITSET_TAIL (dst);  
   /* Ignore empty set.  */  
   if (!elt)  
     return;  
924    
925    windex = elt->index;    windex = (BITSET_SIZE_ (dst) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS;
926    
927    for (i = 0; i < windex; i += LBITSET_ELT_WORDS)    for (i = 0; i < windex; i += LBITSET_ELT_WORDS)
928      {      {
929        /* Create new elements if they cannot be found.  */        /* Create new elements if they cannot be found.  */
930        elt = lbitset_elt_find (dst, i, LBITSET_CREATE);        elt = lbitset_elt_find (dst, i, LBITSET_CREATE);
931        memset (elt->words, -1, sizeof (elt->words));        memset (elt->words, -1, sizeof (elt->words));
932      }      }
933    
934      lbitset_unused_clear (dst);
935  }  }
936    
937    
# Line 911  lbitset_not (bitset dst, bitset src) Line 948  lbitset_not (bitset dst, bitset src)
948    /* This is another unfriendly operation for a linked list    /* This is another unfriendly operation for a linked list
949       bitset!  */       bitset!  */
950    elt = LBITSET_TAIL (dst);    elt = LBITSET_TAIL (dst);
   /* Ignore empty set.  */  
   if (!elt)  
     return;  
951    
952    windex = elt->index;    windex = (BITSET_SIZE_ (dst) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS;
953    
954    for (i = 0; i < windex; i += LBITSET_ELT_WORDS)    for (i = 0; i < windex; i += LBITSET_ELT_WORDS)
955      {      {
956        /* Create new elements for dst if they cannot be found        /* Create new elements for dst if they cannot be found
# Line 926  lbitset_not (bitset dst, bitset src) Line 961  lbitset_not (bitset dst, bitset src)
961        for (j = 0; j < LBITSET_ELT_WORDS; j++)        for (j = 0; j < LBITSET_ELT_WORDS; j++)
962          delt->words[j] = ~selt->words[j];          delt->words[j] = ~selt->words[j];
963      }      }
964      lbitset_unused_clear (dst);
965    lbitset_weed (dst);    lbitset_weed (dst);
966    return;    return;
967  }  }
# Line 1280  struct bitset_vtable lbitset_vtable = { Line 1316  struct bitset_vtable lbitset_vtable = {
1316    lbitset_reset,    lbitset_reset,
1317    bitset_toggle_,    bitset_toggle_,
1318    lbitset_test,    lbitset_test,
1319    lbitset_size,    lbitset_resize,
1320      bitset_size_,
1321    bitset_count_,    bitset_count_,
1322    lbitset_empty_p,    lbitset_empty_p,
1323    lbitset_ones,    lbitset_ones,
# Line 1323  lbitset_bytes (bitset_bindex n_bits ATTR Line 1360  lbitset_bytes (bitset_bindex n_bits ATTR
1360  bitset  bitset
1361  lbitset_init (bitset bset, bitset_bindex n_bits ATTRIBUTE_UNUSED)  lbitset_init (bitset bset, bitset_bindex n_bits ATTRIBUTE_UNUSED)
1362  {  {
1363      BITSET_NBITS_ (bset) = n_bits;
1364    bset->b.vtable = &lbitset_vtable;    bset->b.vtable = &lbitset_vtable;
1365    return bset;    return bset;
1366  }  }

Legend:
Removed from v.1.11  
changed lines
  Added in v.1.12

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26