/[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.5 by eggert, Mon Aug 12 14:22:08 2002 UTC revision 1.6 by akim, Mon Sep 30 12:50:49 2002 UTC
# Line 24  Line 24 
24  #include "lbitset.h"  #include "lbitset.h"
25  #include "obstack.h"  #include "obstack.h"
26  #include <stdlib.h>  #include <stdlib.h>
27    #include <stdio.h>
28    
29  /* This file implements linked-list bitsets.  These bitsets can be of  /* This file implements linked-list bitsets.  These bitsets can be of
30     arbitrary length and are more efficient than arrays of bits for     arbitrary length and are more efficient than arrays of bits for
# Line 78  struct bitset_struct Line 79  struct bitset_struct
79  };  };
80    
81    
82    typedef void(*PFV)();
83    
84    
85  enum lbitset_find_mode  enum lbitset_find_mode
86    { LBITSET_FIND, LBITSET_CREATE, LBITSET_SUBST };    { LBITSET_FIND, LBITSET_CREATE, LBITSET_SUBST };
87    
# Line 102  static void lbitset_weed PARAMS ((bitset Line 106  static void lbitset_weed PARAMS ((bitset
106  static void lbitset_zero PARAMS ((bitset));  static void lbitset_zero PARAMS ((bitset));
107  static int lbitset_equal_p PARAMS ((bitset, bitset));  static int lbitset_equal_p PARAMS ((bitset, bitset));
108  static void lbitset_copy PARAMS ((bitset, bitset));  static void lbitset_copy PARAMS ((bitset, bitset));
109  static int lbitset_copy_compare PARAMS ((bitset, bitset));  static int lbitset_copy_cmp PARAMS ((bitset, bitset));
110  static void lbitset_set PARAMS ((bitset, bitset_bindex));  static void lbitset_set PARAMS ((bitset, bitset_bindex));
111  static void lbitset_reset PARAMS ((bitset, bitset_bindex));  static void lbitset_reset PARAMS ((bitset, bitset_bindex));
112  static int lbitset_test PARAMS ((bitset, bitset_bindex));  static int lbitset_test PARAMS ((bitset, bitset_bindex));
113  static int lbitset_size PARAMS ((bitset));  static int lbitset_size PARAMS ((bitset));
114  static int lbitset_op1 PARAMS ((bitset, enum bitset_ops));  static int lbitset_op3_cmp PARAMS ((bitset, bitset, bitset, enum bitset_ops));
 static int lbitset_op2 PARAMS ((bitset, bitset, enum bitset_ops));  
 static int lbitset_op3 PARAMS ((bitset, bitset, bitset, enum bitset_ops));  
115  static int lbitset_list PARAMS ((bitset, bitset_bindex *, bitset_bindex,  static int lbitset_list PARAMS ((bitset, bitset_bindex *, bitset_bindex,
116                                   bitset_bindex *));                                   bitset_bindex *));
117  static int lbitset_reverse_list  static int lbitset_list_reverse
118  PARAMS ((bitset, bitset_bindex *, bitset_bindex, bitset_bindex *));  PARAMS ((bitset, bitset_bindex *, bitset_bindex, bitset_bindex *));
119  static void lbitset_free PARAMS ((bitset));  static void lbitset_free PARAMS ((bitset));
120    
# Line 398  lbitset_elt_find (bset, windex, mode) Line 400  lbitset_elt_find (bset, windex, mode)
400              continue;              continue;
401          }          }
402    
403        /* `element' is the nearest to the one we want.  If it's not the one        /* ELT is the nearest to the one we want.  If it's not the one
404           we want, the one we want does not exist.  */           we want, the one we want does not exist.  */
405        if (elt && (windex - elt->index) < LBITSET_ELT_WORDS)        if (elt && (windex - elt->index) < LBITSET_ELT_WORDS)
406          {          {
# Line 449  lbitset_weed (bset) Line 451  lbitset_weed (bset)
451    
452    
453  /* Set all bits in the bitset to zero.  */  /* Set all bits in the bitset to zero.  */
454  static inline void  static void
455  lbitset_zero (bset)  lbitset_zero (bset)
456       bitset bset;       bitset bset;
457  {  {
# Line 464  lbitset_zero (bset) Line 466  lbitset_zero (bset)
466  }  }
467    
468    
469    /* Return 1 if DST == SRC.  */
470  static inline int  static inline int
471  lbitset_equal_p (dst, src)  lbitset_equal_p (dst, src)
472       bitset dst;       bitset dst;
# Line 538  lbitset_copy (dst, src) Line 541  lbitset_copy (dst, src)
541  /* Copy bits from bitset SRC to bitset DST.  Return non-zero if  /* Copy bits from bitset SRC to bitset DST.  Return non-zero if
542     bitsets different.  */     bitsets different.  */
543  static inline int  static inline int
544  lbitset_copy_compare (dst, src)  lbitset_copy_cmp (dst, src)
545       bitset dst;       bitset dst;
546       bitset src;       bitset src;
547  {  {
# Line 636  lbitset_free (bset) Line 639  lbitset_free (bset)
639   *NEXT and store in array LIST.  Return with actual number of bits   *NEXT and store in array LIST.  Return with actual number of bits
640   found and with *NEXT indicating where search stopped.  */   found and with *NEXT indicating where search stopped.  */
641  static int  static int
642  lbitset_reverse_list (bset, list, num, next)  lbitset_list_reverse (bset, list, num, next)
643       bitset bset;       bitset bset;
644       bitset_bindex *list;       bitset_bindex *list;
645       bitset_bindex num;       bitset_bindex num;
# Line 673  lbitset_reverse_list (bset, list, num, n Line 676  lbitset_reverse_list (bset, list, num, n
676    if (!elt)    if (!elt)
677      return 0;      return 0;
678    
679    /* If num is 1, we could speed things up with a binary search    if (windex >= elt->index + LBITSET_ELT_WORDS)
680       of the word of interest.  */      {
681          /* We are trying to start in no-mans land so start
682             at end of current elt.  */
683          bcount = BITSET_WORD_BITS - 1;
684          windex = elt->index + LBITSET_ELT_WORDS - 1;
685        }
686      else
687        {
688          bcount = bitno % BITSET_WORD_BITS;
689        }
690    
691    count = 0;    count = 0;
   bcount = bitno % BITSET_WORD_BITS;  
692    boffset = windex * BITSET_WORD_BITS;    boffset = windex * BITSET_WORD_BITS;
693    
694      /* If num is 1, we could speed things up with a binary search
695         of the word of interest.  */
696    
697    while (elt)    while (elt)
698      {      {
699        bitset_word *srcp = elt->words;        bitset_word *srcp = elt->words;
# Line 926  lbitset_list (bset, list, num, next) Line 940  lbitset_list (bset, list, num, next)
940    
941    
942  static int  static int
943  lbitset_op1 (dst, op)  lbitset_empty_p (dst)
944         bitset dst;
945    {
946      lbitset_weed (dst);
947      if (LBITSET_HEAD (dst))
948          return 0;
949      return 1;
950    }
951    
952    
953    static void
954    lbitset_ones (dst)
955       bitset dst;       bitset dst;
      enum bitset_ops op;  
956  {  {
957    unsigned int i;    unsigned int i;
958    bitset_windex windex;    bitset_windex windex;
959    lbitset_elt *elt;    lbitset_elt *elt;
960    
961    switch (op)    /* This is a decidedly unfriendly operation for a linked list
962      {        bitset!  It makes a sparse bitset become dense.  An alternative
963      case BITSET_OP_ZERO:        is to have a flag that indicates that the bitset stores the
964        lbitset_zero (dst);        complement of what it indicates.  */
965        break;    elt = LBITSET_TAIL (dst);
966      /* Ignore empty set.  */
967      case BITSET_OP_ONES:    if (!elt)
968        /* This is a decidedly unfriendly operation for a linked list      return;
969           bitset!   */    
970        elt = LBITSET_TAIL (dst);    windex = elt->index;
971        /* Ignore empty set.  */    for (i = 0; i < windex; i += LBITSET_ELT_WORDS)
972        if (!elt)      {
973          return 0;        /* Create new elements if they cannot be found.  */
974          elt = lbitset_elt_find (dst, i, LBITSET_CREATE);
975        windex = elt->index;        memset (elt->words, -1, sizeof (elt->words));
       for (i = 0; i < windex; i += LBITSET_ELT_WORDS)  
         {  
           /* Create new elements if they cannot be found.  */  
           elt = lbitset_elt_find (dst, i, LBITSET_CREATE);  
           memset (elt->words, -1, sizeof (elt->words));  
         }  
       break;  
   
     case BITSET_OP_EMPTY_P:  
       lbitset_weed (dst);  
       if (LBITSET_HEAD (dst))  
         return 0;  
       break;  
   
     default:  
       abort ();  
976      }      }
   
   return 1;  
977  }  }
978    
979    
980  static int  static void
981  lbitset_op2 (dst, src, op)  lbitset_not (dst, src)
982       bitset dst;       bitset dst;
983       bitset src;       bitset src;
      enum bitset_ops op;  
984  {  {
985    lbitset_elt *elt;    lbitset_elt *elt;
986    lbitset_elt *selt;    lbitset_elt *selt;
# Line 984  lbitset_op2 (dst, src, op) Line 989  lbitset_op2 (dst, src, op)
989    unsigned int j;    unsigned int j;
990    bitset_windex windex;    bitset_windex windex;
991    
992    switch (op)    /* This is another unfriendly operation for a linked list
993      {       bitset!  */
994      case BITSET_OP_COPY:    elt = LBITSET_TAIL (dst);
995        lbitset_copy (dst, src);    /* Ignore empty set.  */
996        break;    if (!elt)
997        return;
998      case BITSET_OP_NOT:    
999        /* This is another unfriendly operation for a linked list    windex = elt->index;
1000           bitset!  */    for (i = 0; i < windex; i += LBITSET_ELT_WORDS)
1001        elt = LBITSET_TAIL (dst);      {
1002        /* Ignore empty set.  */        /* Create new elements for dst if they cannot be found
1003        if (!elt)           or substitute zero elements if src elements not found.  */
1004          return 0;        selt = lbitset_elt_find (src, i, LBITSET_SUBST);
1005          delt = lbitset_elt_find (dst, i, LBITSET_CREATE);
1006          
1007          for (j = 0; j < LBITSET_ELT_WORDS; j++)
1008            delt->words[j] = ~selt->words[j];
1009        }
1010      lbitset_weed (dst);
1011      return;
1012    }
1013    
       windex = elt->index;  
       for (i = 0; i < windex; i += LBITSET_ELT_WORDS)  
         {  
           /* Create new elements for dst if they cannot be found  
              or substitute zero elements if src elements not found.  */  
           selt = lbitset_elt_find (dst, i, LBITSET_SUBST);  
           delt = lbitset_elt_find (dst, i, LBITSET_CREATE);  
1014    
1015            for (j = 0; j < LBITSET_ELT_WORDS; j++)  /* Return 1 if DST == DST | SRC.  */
1016              delt->words[j] = ~selt->words[j];  static int
1017          }  lbitset_subset_p (dst, src)
1018        lbitset_weed (dst);       bitset dst;
1019        break;       bitset src;
1020    {
1021      lbitset_elt *selt;
1022      lbitset_elt *delt;
1023      unsigned int j;
1024    
1025        /* Return 1 if DST == SRC.  */    for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst);
1026      case BITSET_OP_EQUAL_P:         selt || delt; selt = selt->next, delt = delt->next)
1027        return lbitset_equal_p (dst, src);      {
1028        break;        if (!selt)
1029            selt = &lbitset_zero_elts[0];
1030        /* Return 1 if DST == DST | SRC.  */        else if (!delt)
1031      case BITSET_OP_SUBSET_P:          delt = &lbitset_zero_elts[0];
1032        for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst);        else if (selt->index != delt->index)
1033             selt || delt; selt = selt->next, delt = delt->next)          {
1034          {            if (selt->index < delt->index)
           if (!selt)  
             selt = &lbitset_zero_elts[0];  
           else if (!delt)  
             delt = &lbitset_zero_elts[0];  
           else if (selt->index != delt->index)  
1035              {              {
1036                if (selt->index < delt->index)                lbitset_zero_elts[2].next = delt;
1037                  {                delt = &lbitset_zero_elts[2];
                   lbitset_zero_elts[2].next = delt;  
                   delt = &lbitset_zero_elts[2];  
                 }  
               else  
                 {  
                   lbitset_zero_elts[1].next = selt;  
                   selt = &lbitset_zero_elts[1];  
                 }  
1038              }              }
1039              else
1040                {
1041                  lbitset_zero_elts[1].next = selt;
1042                  selt = &lbitset_zero_elts[1];
1043                }
1044            }
1045          
1046          for (j = 0; j < LBITSET_ELT_WORDS; j++)
1047            if (delt->words[j] != (selt->words[j] | delt->words[j]))
1048              return 0;
1049        }
1050      return 1;
1051    }
1052    
1053            for (j = 0; j < LBITSET_ELT_WORDS; j++)  
1054              if (delt->words[j] != (selt->words[j] | delt->words[j]))  /* Return 1 if DST & SRC == 0.  */
1055                return 0;  static int
1056          }  lbitset_disjoint_p (dst, src)
1057        break;       bitset dst;
1058         bitset src;
1059        /* Return 1 if DST & SRC == 0.  */  {
1060      case BITSET_OP_DISJOINT_P:    lbitset_elt *selt;
1061        for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst);    lbitset_elt *delt;
1062             selt && delt; selt = selt->next, delt = delt->next)    unsigned int j;
1063    
1064      for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst);
1065           selt && delt; selt = selt->next, delt = delt->next)
1066        {
1067          if (selt->index != delt->index)
1068          {          {
1069            if (selt->index != delt->index)            if (selt->index < delt->index)
1070              {              {
1071                if (selt->index < delt->index)                lbitset_zero_elts[2].next = delt;
1072                  {                delt = &lbitset_zero_elts[2];
                   lbitset_zero_elts[2].next = delt;  
                   delt = &lbitset_zero_elts[2];  
                 }  
               else  
                 {  
                   lbitset_zero_elts[1].next = selt;  
                   selt = &lbitset_zero_elts[1];  
                 }  
               /* Since the elements are different, there is no  
                  intersection of these elements.  */  
               continue;  
1073              }              }
1074              else
1075            for (j = 0; j < LBITSET_ELT_WORDS; j++)              {
1076              if (selt->words[j] & delt->words[j])                lbitset_zero_elts[1].next = selt;
1077                return 0;                selt = &lbitset_zero_elts[1];
1078                }
1079              /* Since the elements are different, there is no
1080                 intersection of these elements.  */
1081              continue;
1082          }          }
1083        break;        
1084          for (j = 0; j < LBITSET_ELT_WORDS; j++)
1085      default:          if (selt->words[j] & delt->words[j])
1086        abort ();            return 0;
1087      }      }
   
1088    return 1;    return 1;
1089  }  }
1090    
1091    
1092  static int  static int
1093  lbitset_op3 (dst, src1, src2, op)  lbitset_op3_cmp (dst, src1, src2, op)
1094       bitset dst;       bitset dst;
1095       bitset src1;       bitset src1;
1096       bitset src2;       bitset src2;
# Line 1104  lbitset_op3 (dst, src1, src2, op) Line 1111  lbitset_op3 (dst, src1, src2, op)
1111    int changed = 0;    int changed = 0;
1112    unsigned int i;    unsigned int i;
1113    
   /* Fast track common, simple cases.  */  
   if (!selt2)  
     {  
       if (op == BITSET_OP_AND)  
         {  
           lbitset_weed (dst);  
           changed = !LBITSET_HEAD (dst);  
           lbitset_zero (dst);  
           return changed;  
         }  
       else if (op == BITSET_OP_ANDN || op == BITSET_OP_OR  
                || op == BITSET_OP_XOR)  
         {  
           return lbitset_copy_compare (dst, src1);  
         }  
     }  
   else if (!selt1)  
     {  
       if (op == BITSET_OP_AND || op == BITSET_OP_ANDN)  
         {  
           lbitset_weed (dst);  
           changed = !LBITSET_HEAD (dst);  
           lbitset_zero (dst);  
           return changed;  
         }  
       else if (op == BITSET_OP_OR || op == BITSET_OP_XOR)  
         {  
           return lbitset_copy_compare (dst, src2);  
         }  
     }  
   
1114    LBITSET_HEAD (dst) = 0;    LBITSET_HEAD (dst) = 0;
1115    dst->b.csize = 0;    dst->b.csize = 0;
1116    
# Line 1275  lbitset_op3 (dst, src1, src2, op) Line 1251  lbitset_op3 (dst, src1, src2, op)
1251  }  }
1252    
1253    
1254    static int
1255    lbitset_and_cmp (dst, src1, src2)
1256         bitset dst;
1257         bitset src1;
1258         bitset src2;
1259    {
1260      lbitset_elt *selt1 = LBITSET_HEAD (src1);
1261      lbitset_elt *selt2 = LBITSET_HEAD (src2);
1262      int changed;
1263    
1264      if (!selt2)
1265        {
1266          lbitset_weed (dst);
1267          changed = !LBITSET_HEAD (dst);
1268          lbitset_zero (dst);
1269          return changed;
1270        }
1271      else if (!selt1)
1272        {
1273          lbitset_weed (dst);
1274          changed = !LBITSET_HEAD (dst);
1275          lbitset_zero (dst);
1276          return changed;
1277        }
1278      return lbitset_op3_cmp (dst, src1, src2, BITSET_OP_AND);
1279    }
1280    
1281    
1282    static int
1283    lbitset_andn_cmp (dst, src1, src2)
1284         bitset dst;
1285         bitset src1;
1286         bitset src2;
1287    {
1288      lbitset_elt *selt1 = LBITSET_HEAD (src1);
1289      lbitset_elt *selt2 = LBITSET_HEAD (src2);
1290      int changed;
1291    
1292      if (!selt2)
1293        {
1294          return lbitset_copy_cmp (dst, src1);
1295        }
1296      else if (!selt1)
1297        {
1298          lbitset_weed (dst);
1299          changed = !LBITSET_HEAD (dst);
1300          lbitset_zero (dst);
1301          return changed;
1302        }
1303      return lbitset_op3_cmp (dst, src1, src2, BITSET_OP_ANDN);
1304    }
1305    
1306    
1307    static int
1308    lbitset_or_cmp (dst, src1, src2)
1309         bitset dst;
1310         bitset src1;
1311         bitset src2;
1312    {
1313      lbitset_elt *selt1 = LBITSET_HEAD (src1);
1314      lbitset_elt *selt2 = LBITSET_HEAD (src2);
1315    
1316      if (!selt2)
1317        {
1318          return lbitset_copy_cmp (dst, src1);
1319        }
1320      else if (!selt1)
1321        {
1322          return lbitset_copy_cmp (dst, src2);
1323        }
1324      return lbitset_op3_cmp (dst, src1, src2, BITSET_OP_OR);
1325    }
1326    
1327    
1328    static int
1329    lbitset_xor_cmp (dst, src1, src2)
1330         bitset dst;
1331         bitset src1;
1332         bitset src2;
1333    {
1334      lbitset_elt *selt1 = LBITSET_HEAD (src1);
1335      lbitset_elt *selt2 = LBITSET_HEAD (src2);
1336    
1337      if (!selt2)
1338        {
1339          return lbitset_copy_cmp (dst, src1);
1340        }
1341      else if (!selt1)
1342        {
1343          return lbitset_copy_cmp (dst, src2);
1344        }
1345      return lbitset_op3_cmp (dst, src1, src2, BITSET_OP_XOR);
1346    }
1347    
1348    
1349    
1350  /* Vector of operations for linked-list bitsets.  */  /* Vector of operations for linked-list bitsets.  */
1351  struct bitset_ops_struct lbitset_ops = {  struct bitset_vtable lbitset_vtable = {
1352    lbitset_set,    lbitset_set,
1353    lbitset_reset,    lbitset_reset,
1354      bitset_toggle_,
1355    lbitset_test,    lbitset_test,
1356    lbitset_size,    lbitset_size,
1357    lbitset_op1,    bitset_count_,
1358    lbitset_op2,    lbitset_empty_p,
1359    lbitset_op3,    lbitset_ones,
1360    bitset_op4,    lbitset_zero,
1361      lbitset_copy,
1362      lbitset_disjoint_p,
1363      lbitset_equal_p,
1364      lbitset_not,
1365      lbitset_subset_p,
1366      (PFV) lbitset_and_cmp,
1367      lbitset_and_cmp,
1368      (PFV) lbitset_andn_cmp,
1369      lbitset_andn_cmp,
1370      (PFV) lbitset_or_cmp,
1371      lbitset_or_cmp,
1372      (PFV) lbitset_xor_cmp,
1373      lbitset_xor_cmp,
1374      (PFV) bitset_and_or_cmp_,
1375      bitset_and_or_cmp_,
1376      (PFV) bitset_andn_or_cmp_,
1377      bitset_andn_or_cmp_,
1378      (PFV) bitset_or_and_cmp_,
1379      bitset_or_and_cmp_,
1380    lbitset_list,    lbitset_list,
1381    lbitset_reverse_list,    lbitset_list_reverse,
1382    lbitset_free,    lbitset_free,
1383    BITSET_LIST    BITSET_LIST
1384  };  };
# Line 1302  lbitset_bytes (n_bits) Line 1394  lbitset_bytes (n_bits)
1394    
1395    
1396  /* Initialize a bitset.  */  /* Initialize a bitset.  */
   
1397  bitset  bitset
1398  lbitset_init (bset, n_bits)  lbitset_init (bset, n_bits)
1399       bitset bset;       bitset bset;
1400       bitset_bindex n_bits ATTRIBUTE_UNUSED;       bitset_bindex n_bits ATTRIBUTE_UNUSED;
1401  {  {
1402    bset->b.ops = &lbitset_ops;    bset->b.vtable = &lbitset_vtable;
1403    return bset;    return bset;
1404  }  }
1405    
# Line 1323  lbitset_release_memory () Line 1414  lbitset_release_memory ()
1414        obstack_free (&lbitset_obstack, NULL);        obstack_free (&lbitset_obstack, NULL);
1415      }      }
1416  }  }
1417    
1418    
1419    /* Function to be called from debugger to debug lbitset.  */
1420    void
1421    debug_lbitset (bset)
1422         bitset bset;
1423    {
1424      lbitset_elt *elt;
1425      unsigned int i;
1426    
1427      if (!bset)
1428        return;
1429      
1430      for (elt = LBITSET_HEAD (bset); elt; elt = elt->next)
1431        {
1432          fprintf (stderr, "Elt %d\n", elt->index);
1433          for (i = 0; i < LBITSET_ELT_WORDS; i++)
1434            {
1435              unsigned int j;
1436              bitset_word word;
1437              
1438              word = elt->words[i];
1439              
1440              fprintf (stderr, "  Word %d:", i);
1441              for (j = 0; j < LBITSET_WORD_BITS; j++)
1442                if ((word & (1 << j)))
1443                  fprintf (stderr, " %d", j);
1444              fprintf (stderr, "\n");
1445            }
1446        }
1447    }

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

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