2015-02-13 14:40:36 -05:00
|
|
|
// Copyright 2013 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package gc
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
WORDBITS = 32
|
|
|
|
|
WORDMASK = WORDBITS - 1
|
|
|
|
|
WORDSHIFT = 5
|
|
|
|
|
)
|
|
|
|
|
|
2016-04-29 14:17:04 +10:00
|
|
|
// A bvec is a bit vector.
|
|
|
|
|
type bvec struct {
|
2015-03-02 21:25:33 -05:00
|
|
|
n int32 // number of bits in vector
|
|
|
|
|
b []uint32 // words holding bits
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-29 14:17:04 +10:00
|
|
|
func bvalloc(n int32) bvec {
|
|
|
|
|
nword := (n + WORDBITS - 1) / WORDBITS
|
|
|
|
|
return bvec{n, make([]uint32, nword)}
|
2015-03-02 21:25:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type bulkBvec struct {
|
|
|
|
|
words []uint32
|
|
|
|
|
nbit int32
|
|
|
|
|
nword int32
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func bvbulkalloc(nbit int32, count int32) bulkBvec {
|
|
|
|
|
nword := (nbit + WORDBITS - 1) / WORDBITS
|
|
|
|
|
return bulkBvec{
|
|
|
|
|
words: make([]uint32, nword*count),
|
|
|
|
|
nbit: nbit,
|
|
|
|
|
nword: nword,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-29 14:17:04 +10:00
|
|
|
func (b *bulkBvec) next() bvec {
|
|
|
|
|
out := bvec{b.nbit, b.words[:b.nword]}
|
2015-03-02 21:25:33 -05:00
|
|
|
b.words = b.words[b.nword:]
|
|
|
|
|
return out
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-10-04 15:57:24 -07:00
|
|
|
func (bv1 bvec) Eq(bv2 bvec) bool {
|
2015-02-13 14:40:36 -05:00
|
|
|
if bv1.n != bv2.n {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("bvequal: lengths %d and %d are not equal", bv1.n, bv2.n)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
for i, x := range bv1.b {
|
|
|
|
|
if x != bv2.b[i] {
|
2016-03-15 17:03:10 +11:00
|
|
|
return false
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
2016-03-15 17:03:10 +11:00
|
|
|
return true
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-10-04 15:57:24 -07:00
|
|
|
func (dst bvec) Copy(src bvec) {
|
2017-01-14 23:43:26 -08:00
|
|
|
copy(dst.b, src.b)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-10-04 15:57:24 -07:00
|
|
|
func (bv bvec) Get(i int32) bool {
|
2015-02-13 14:40:36 -05:00
|
|
|
if i < 0 || i >= bv.n {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("bvget: index %d is out of bounds with length %d\n", i, bv.n)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-10-04 15:57:24 -07:00
|
|
|
mask := uint32(1 << uint(i%WORDBITS))
|
|
|
|
|
return bv.b[i>>WORDSHIFT]&mask != 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (bv bvec) Set(i int32) {
|
|
|
|
|
if i < 0 || i >= bv.n {
|
|
|
|
|
Fatalf("bvset: index %d is out of bounds with length %d\n", i, bv.n)
|
|
|
|
|
}
|
|
|
|
|
mask := uint32(1 << uint(i%WORDBITS))
|
|
|
|
|
bv.b[i/WORDBITS] |= mask
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2017-01-14 23:43:26 -08:00
|
|
|
func (bv bvec) Unset(i int32) {
|
|
|
|
|
if i < 0 || i >= bv.n {
|
|
|
|
|
Fatalf("bvunset: index %d is out of bounds with length %d\n", i, bv.n)
|
|
|
|
|
}
|
|
|
|
|
mask := uint32(1 << uint(i%WORDBITS))
|
|
|
|
|
bv.b[i/WORDBITS] &^= mask
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
// bvnext returns the smallest index >= i for which bvget(bv, i) == 1.
|
|
|
|
|
// If there is no such index, bvnext returns -1.
|
2016-10-04 15:57:24 -07:00
|
|
|
func (bv bvec) Next(i int32) int32 {
|
2015-02-13 14:40:36 -05:00
|
|
|
if i >= bv.n {
|
|
|
|
|
return -1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Jump i ahead to next word with bits.
|
|
|
|
|
if bv.b[i>>WORDSHIFT]>>uint(i&WORDMASK) == 0 {
|
|
|
|
|
i &^= WORDMASK
|
|
|
|
|
i += WORDBITS
|
|
|
|
|
for i < bv.n && bv.b[i>>WORDSHIFT] == 0 {
|
|
|
|
|
i += WORDBITS
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if i >= bv.n {
|
|
|
|
|
return -1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Find 1 bit.
|
2015-02-23 16:07:24 -05:00
|
|
|
w := bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
for w&1 == 0 {
|
|
|
|
|
w >>= 1
|
|
|
|
|
i++
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-13 10:23:18 +09:00
|
|
|
return i
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-10-04 15:57:24 -07:00
|
|
|
func (bv bvec) IsEmpty() bool {
|
2015-02-23 16:07:24 -05:00
|
|
|
for i := int32(0); i < bv.n; i += WORDBITS {
|
2015-02-13 14:40:36 -05:00
|
|
|
if bv.b[i>>WORDSHIFT] != 0 {
|
2015-02-17 22:13:49 -05:00
|
|
|
return false
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
2015-02-17 22:13:49 -05:00
|
|
|
return true
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-10-04 15:57:24 -07:00
|
|
|
func (bv bvec) Not() {
|
2015-03-12 18:45:30 -04:00
|
|
|
i := int32(0)
|
|
|
|
|
w := int32(0)
|
2015-03-09 00:31:13 -04:00
|
|
|
for ; i < bv.n; i, w = i+WORDBITS, w+1 {
|
2015-02-13 14:40:36 -05:00
|
|
|
bv.b[w] = ^bv.b[w]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// union
|
2016-10-04 15:57:24 -07:00
|
|
|
func (dst bvec) Or(src1, src2 bvec) {
|
2015-03-12 18:45:30 -04:00
|
|
|
for i, x := range src1.b {
|
|
|
|
|
dst.b[i] = x | src2.b[i]
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// intersection
|
2016-10-04 15:57:24 -07:00
|
|
|
func (dst bvec) And(src1, src2 bvec) {
|
2015-03-12 18:45:30 -04:00
|
|
|
for i, x := range src1.b {
|
|
|
|
|
dst.b[i] = x & src2.b[i]
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-04 15:57:24 -07:00
|
|
|
// difference
|
|
|
|
|
func (dst bvec) AndNot(src1, src2 bvec) {
|
|
|
|
|
for i, x := range src1.b {
|
|
|
|
|
dst.b[i] = x &^ src2.b[i]
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-04 15:57:24 -07:00
|
|
|
func (bv bvec) String() string {
|
|
|
|
|
s := make([]byte, 2+bv.n)
|
|
|
|
|
copy(s, "#*")
|
|
|
|
|
for i := int32(0); i < bv.n; i++ {
|
|
|
|
|
ch := byte('0')
|
|
|
|
|
if bv.Get(i) {
|
|
|
|
|
ch = '1'
|
|
|
|
|
}
|
|
|
|
|
s[2+i] = ch
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-10-04 15:57:24 -07:00
|
|
|
return string(s)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-10-04 15:57:24 -07:00
|
|
|
func (bv bvec) Clear() {
|
|
|
|
|
for i := range bv.b {
|
|
|
|
|
bv.b[i] = 0
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|