Exemple #1
0
static inline bool
tbitset_equal_p (bitset dst, bitset src)
{
  if (src == dst)
    return true;

  tbitset_weed (dst);
  tbitset_weed (src);

  if (EBITSET_SIZE (src) != EBITSET_SIZE (dst))
    return false;

  tbitset_elts *selts = EBITSET_ELTS (src);
  tbitset_elts *delts = EBITSET_ELTS (dst);

  for (bitset_windex j = 0; j < EBITSET_SIZE (src); j++)
    {
      tbitset_elt *selt = selts[j];
      tbitset_elt *delt = delts[j];

      if (!selt && !delt)
        continue;
      if ((selt && !delt) || (!selt && delt))
        return false;

      for (unsigned i = 0; i < EBITSET_ELT_WORDS; i++)
        if (EBITSET_WORDS (selt)[i] != EBITSET_WORDS (delt)[i])
          return false;
    }
  return true;
}
Exemple #2
0
/* Copy bits from bitset SRC to bitset DST.  */
static inline void
tbitset_copy_ (bitset dst, bitset src)
{
  if (src == dst)
    return;

  tbitset_zero (dst);

  if (BITSET_NBITS_ (dst) != BITSET_NBITS_ (src))
    tbitset_resize (dst, BITSET_NBITS_ (src));

  tbitset_elts *selts = EBITSET_ELTS (src);
  tbitset_elts *delts = EBITSET_ELTS (dst);
  for (bitset_windex j = 0; j < EBITSET_SIZE (src); j++)
    {
      tbitset_elt *selt = selts[j];
      if (selt)
        {
          tbitset_elt *tmp = tbitset_elt_alloc ();
          delts[j] = tmp;
          memcpy (EBITSET_WORDS (tmp), EBITSET_WORDS (selt),
                  sizeof (EBITSET_WORDS (selt)));
        }
    }
  EBITSET_NONZERO_SET (dst);
}
Exemple #3
0
static bitset_bindex
ebitset_resize (bitset src, bitset_bindex n_bits)
{
  bitset_windex oldsize;
  bitset_windex newsize;

  if (n_bits == BITSET_NBITS_ (src))
    return n_bits;

  oldsize = EBITSET_SIZE (src);
  newsize = EBITSET_N_ELTS (n_bits);

  if (oldsize < newsize)
    {
      bitset_windex size;

      /* The bitset needs to grow.  If we already have enough memory
         allocated, then just zero what we need.  */
      if (newsize > EBITSET_ASIZE (src))
        {
          /* We need to allocate more memory.  When oldsize is
             non-zero this means that we are changing the size, so
             grow the bitset 25% larger than requested to reduce
             number of reallocations.  */

          if (oldsize == 0)
            size = newsize;
          else
            size = newsize + newsize / 4;

          EBITSET_ELTS (src)
            = realloc (EBITSET_ELTS (src), size * sizeof (ebitset_elt *));
          EBITSET_ASIZE (src) = size;
        }

      memset (EBITSET_ELTS (src) + oldsize, 0,
              (newsize - oldsize) * sizeof (ebitset_elt *));
    }
  else
    {
      /* The bitset needs to shrink.  There's no point deallocating
         the memory unless it is shrinking by a reasonable amount.  */
      if ((oldsize - newsize) >= oldsize / 2)
        {
          EBITSET_ELTS (src)
            = realloc (EBITSET_ELTS (src), newsize * sizeof (ebitset_elt *));
          EBITSET_ASIZE (src) = newsize;
        }

      /* Need to prune any excess bits.  FIXME.  */
    }

  BITSET_NBITS_ (src) = n_bits;
  return n_bits;
}
Exemple #4
0
/* Add ELT into elts at index EINDEX of bitset BSET.  */
static inline void
tbitset_elt_add (bitset bset, tbitset_elt *elt, bitset_windex eindex)
{
  tbitset_elts *elts = EBITSET_ELTS (bset);
  /* Assume that the elts entry not allocated.  */
  elts[eindex] = elt;
}
Exemple #5
0
/* Find list of up to NUM bits set in BSET starting from and including
 *NEXT and store in array LIST.  Return with actual number of bits
 found and with *NEXT indicating where search stopped.  */
static bitset_bindex
ebitset_list (bitset bset, bitset_bindex *list,
              bitset_bindex num, bitset_bindex *next)
{
  bitset_bindex bitno;
  bitset_windex windex;
  bitset_windex eindex;
  bitset_bindex count;
  bitset_windex size;
  ebitset_elt *elt;
  bitset_word word;
  ebitset_elts *elts;

  if (EBITSET_ZERO_P (bset))
    return 0;

  bitno = *next;
  count = 0;

  elts = EBITSET_ELTS (bset);
  size = EBITSET_SIZE (bset);
  eindex = bitno / EBITSET_ELT_BITS;

  if (bitno % EBITSET_ELT_BITS)
    {
      /* We need to start within an element.  This is not very common.  */

      elt = elts[eindex];
      if (elt)
        {
          bitset_windex woffset;
          bitset_word *srcp = EBITSET_WORDS (elt);

          windex = bitno / BITSET_WORD_BITS;
          woffset = eindex * EBITSET_ELT_WORDS;

          for (; (windex - woffset) < EBITSET_ELT_WORDS; windex++)
            {
              word = srcp[windex - woffset] >> (bitno % BITSET_WORD_BITS);

              for (; word; bitno++)
                {
                  if (word & 1)
                    {
                      list[count++] = bitno;
                      if (count >= num)
                        {
                          *next = bitno + 1;
                          return count;
                        }
                    }
                  word >>= 1;
                }
              bitno = (windex + 1) * BITSET_WORD_BITS;
            }
        }

      /* Skip to next element.  */
      eindex++;
    }
Exemple #6
0
/* Remove element with index EINDEX from bitset BSET.  */
static inline void
tbitset_elt_remove (bitset bset, bitset_windex eindex)
{
  tbitset_elts *elts = EBITSET_ELTS (bset);
  tbitset_elt *elt = elts[eindex];

  elts[eindex] = 0;
  tbitset_elt_free (elt);
}
Exemple #7
0
static ebitset_elt *
ebitset_elt_find (bitset bset, bitset_bindex bindex,
                  enum ebitset_find_mode mode)
{
  ebitset_elt *elt;
  bitset_windex size;
  bitset_windex eindex;
  ebitset_elts *elts;

  eindex = bindex / EBITSET_ELT_BITS;

  elts = EBITSET_ELTS (bset);
  size = EBITSET_SIZE (bset);

  if (eindex < size)
    {
      if ((elt = elts[eindex]))
        {
          if (EBITSET_WORDS (elt) == bset->b.cdata)
            return elt;

          EBITSET_CACHE_SET (bset, eindex);
          return elt;
        }
    }

  /* The element could not be found.  */

  switch (mode)
    {
    default:
      abort ();

    case EBITSET_FIND:
      return 0;

    case EBITSET_CREATE:
      if (eindex >= size)
        ebitset_resize (bset, bindex);

      /* Create a new element.  */
      elt = ebitset_elt_calloc ();
      ebitset_elt_add (bset, elt, eindex);
      EBITSET_CACHE_SET (bset, eindex);
      return elt;

    case EBITSET_SUBST:
      return &ebitset_zero_elts[0];
    }
}
Exemple #8
0
/* Set all bits in the bitset to zero.  */
static inline void
tbitset_zero (bitset bset)
{
  if (EBITSET_ZERO_P (bset))
    return;

  tbitset_elts *elts = EBITSET_ELTS (bset);
  for (bitset_windex j = 0; j < EBITSET_SIZE (bset); j++)
    {
      tbitset_elt *elt = elts[j];
      if (elt)
        tbitset_elt_remove (bset, j);
    }

  /* All the bits are zero.  We could shrink the elts.
     For now just mark BSET as known to be zero.  */
  EBITSET_ZERO_SET (bset);
}
Exemple #9
0
/* Weed out the zero elements from the elts.  */
static inline bitset_windex
ebitset_weed (bitset bset)
{
  ebitset_elts *elts;
  bitset_windex j;
  bitset_windex count;

  if (EBITSET_ZERO_P (bset))
    return 0;

  elts = EBITSET_ELTS (bset);
  count = 0;
  for (j = 0; j < EBITSET_SIZE (bset); j++)
    {
      ebitset_elt *elt = elts[j];

      if (elt)
        {
          if (ebitset_elt_zero_p (elt))
            {
              ebitset_elt_remove (bset, j);
              count++;
            }
        }
      else
        count++;
    }

  count = j - count;
  if (!count)
    {
      /* All the bits are zero.  We could shrink the elts.
         For now just mark BSET as known to be zero.  */
      EBITSET_ZERO_SET (bset);
    }
  else
    EBITSET_NONZERO_SET (bset);

  return count;
}
Exemple #10
0
/* Find list of up to NUM bits set in BSET starting from and including
 *NEXT and store in array LIST.  Return with actual number of bits
 found and with *NEXT indicating where search stopped.  */
static bitset_bindex
tbitset_list_reverse (bitset bset, bitset_bindex *list,
                      bitset_bindex num, bitset_bindex *next)
{
  if (EBITSET_ZERO_P (bset))
    return 0;

  bitset_windex size = EBITSET_SIZE (bset);
  bitset_bindex n_bits = size * EBITSET_ELT_BITS;
  bitset_bindex rbitno = *next;

  if (rbitno >= n_bits)
    return 0;

  tbitset_elts *elts = EBITSET_ELTS (bset);

  bitset_bindex bitno = n_bits - (rbitno + 1);

  bitset_windex windex = bitno / BITSET_WORD_BITS;
  bitset_windex eindex = bitno / EBITSET_ELT_BITS;
  bitset_windex woffset = windex - eindex * EBITSET_ELT_WORDS;

  /* If num is 1, we could speed things up with a binary search
     of the word of interest.  */
  bitset_bindex count = 0;
  unsigned bcount = bitno % BITSET_WORD_BITS;
  bitset_bindex boffset = windex * BITSET_WORD_BITS;

  do
    {
      tbitset_elt *elt = elts[eindex];
      if (elt)
        {
          bitset_word *srcp = EBITSET_WORDS (elt);

          do
            {
              for (bitset_word word = srcp[woffset] << (BITSET_WORD_BITS - 1 - bcount);
                   word; bcount--)
                {
                  if (word & BITSET_MSB)
                    {
                      list[count++] = boffset + bcount;
                      if (count >= num)
                        {
                          *next = n_bits - (boffset + bcount);
                          return count;
                        }
                    }
                  word <<= 1;
                }
              boffset -= BITSET_WORD_BITS;
              bcount = BITSET_WORD_BITS - 1;
            }
          while (woffset--);
        }

      woffset = EBITSET_ELT_WORDS - 1;
      boffset = eindex * EBITSET_ELT_BITS - BITSET_WORD_BITS;
    }
  while (eindex--);

  *next = n_bits - (boffset + 1);
  return count;
}
Exemple #11
0
static void
tbitset_free (bitset bset)
{
  tbitset_zero (bset);
  free (EBITSET_ELTS (bset));
}