github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/src/cmd/compile/internal/gc/bv.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package gc
     6  
     7  const (
     8  	WORDBITS  = 32
     9  	WORDMASK  = WORDBITS - 1
    10  	WORDSHIFT = 5
    11  )
    12  
    13  // A bvec is a bit vector.
    14  type bvec struct {
    15  	n int32    // number of bits in vector
    16  	b []uint32 // words holding bits
    17  }
    18  
    19  func bvalloc(n int32) bvec {
    20  	nword := (n + WORDBITS - 1) / WORDBITS
    21  	return bvec{n, make([]uint32, nword)}
    22  }
    23  
    24  type bulkBvec struct {
    25  	words []uint32
    26  	nbit  int32
    27  	nword int32
    28  }
    29  
    30  func bvbulkalloc(nbit int32, count int32) bulkBvec {
    31  	nword := (nbit + WORDBITS - 1) / WORDBITS
    32  	return bulkBvec{
    33  		words: make([]uint32, nword*count),
    34  		nbit:  nbit,
    35  		nword: nword,
    36  	}
    37  }
    38  
    39  func (b *bulkBvec) next() bvec {
    40  	out := bvec{b.nbit, b.words[:b.nword]}
    41  	b.words = b.words[b.nword:]
    42  	return out
    43  }
    44  
    45  func (bv1 bvec) Eq(bv2 bvec) bool {
    46  	if bv1.n != bv2.n {
    47  		Fatalf("bvequal: lengths %d and %d are not equal", bv1.n, bv2.n)
    48  	}
    49  	for i, x := range bv1.b {
    50  		if x != bv2.b[i] {
    51  			return false
    52  		}
    53  	}
    54  	return true
    55  }
    56  
    57  func (dst bvec) Copy(src bvec) {
    58  	for i, x := range src.b {
    59  		dst.b[i] = x
    60  	}
    61  }
    62  
    63  func (bv bvec) Get(i int32) bool {
    64  	if i < 0 || i >= bv.n {
    65  		Fatalf("bvget: index %d is out of bounds with length %d\n", i, bv.n)
    66  	}
    67  	mask := uint32(1 << uint(i%WORDBITS))
    68  	return bv.b[i>>WORDSHIFT]&mask != 0
    69  }
    70  
    71  func (bv bvec) Set(i int32) {
    72  	if i < 0 || i >= bv.n {
    73  		Fatalf("bvset: index %d is out of bounds with length %d\n", i, bv.n)
    74  	}
    75  	mask := uint32(1 << uint(i%WORDBITS))
    76  	bv.b[i/WORDBITS] |= mask
    77  }
    78  
    79  // bvnext returns the smallest index >= i for which bvget(bv, i) == 1.
    80  // If there is no such index, bvnext returns -1.
    81  func (bv bvec) Next(i int32) int32 {
    82  	if i >= bv.n {
    83  		return -1
    84  	}
    85  
    86  	// Jump i ahead to next word with bits.
    87  	if bv.b[i>>WORDSHIFT]>>uint(i&WORDMASK) == 0 {
    88  		i &^= WORDMASK
    89  		i += WORDBITS
    90  		for i < bv.n && bv.b[i>>WORDSHIFT] == 0 {
    91  			i += WORDBITS
    92  		}
    93  	}
    94  
    95  	if i >= bv.n {
    96  		return -1
    97  	}
    98  
    99  	// Find 1 bit.
   100  	w := bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK)
   101  
   102  	for w&1 == 0 {
   103  		w >>= 1
   104  		i++
   105  	}
   106  
   107  	return i
   108  }
   109  
   110  func (bv bvec) IsEmpty() bool {
   111  	for i := int32(0); i < bv.n; i += WORDBITS {
   112  		if bv.b[i>>WORDSHIFT] != 0 {
   113  			return false
   114  		}
   115  	}
   116  	return true
   117  }
   118  
   119  func (bv bvec) Not() {
   120  	i := int32(0)
   121  	w := int32(0)
   122  	for ; i < bv.n; i, w = i+WORDBITS, w+1 {
   123  		bv.b[w] = ^bv.b[w]
   124  	}
   125  }
   126  
   127  // union
   128  func (dst bvec) Or(src1, src2 bvec) {
   129  	for i, x := range src1.b {
   130  		dst.b[i] = x | src2.b[i]
   131  	}
   132  }
   133  
   134  // intersection
   135  func (dst bvec) And(src1, src2 bvec) {
   136  	for i, x := range src1.b {
   137  		dst.b[i] = x & src2.b[i]
   138  	}
   139  }
   140  
   141  // difference
   142  func (dst bvec) AndNot(src1, src2 bvec) {
   143  	for i, x := range src1.b {
   144  		dst.b[i] = x &^ src2.b[i]
   145  	}
   146  }
   147  
   148  func (bv bvec) String() string {
   149  	s := make([]byte, 2+bv.n)
   150  	copy(s, "#*")
   151  	for i := int32(0); i < bv.n; i++ {
   152  		ch := byte('0')
   153  		if bv.Get(i) {
   154  			ch = '1'
   155  		}
   156  		s[2+i] = ch
   157  	}
   158  	return string(s)
   159  }
   160  
   161  func (bv bvec) Clear() {
   162  	for i := range bv.b {
   163  		bv.b[i] = 0
   164  	}
   165  }