Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
3.6 KiB
163 lines
3.6 KiB
package roaring |
|
|
|
import ( |
|
"fmt" |
|
) |
|
|
|
// common to rle32.go and rle16.go |
|
|
|
// rleVerbose controls whether p() prints show up. |
|
// The testing package sets this based on |
|
// testing.Verbose(). |
|
var rleVerbose bool |
|
|
|
// p is a shorthand for fmt.Printf with beginning and |
|
// trailing newlines. p() makes it easy |
|
// to add diagnostic print statements. |
|
func p(format string, args ...interface{}) { |
|
if rleVerbose { |
|
fmt.Printf("\n"+format+"\n", args...) |
|
} |
|
} |
|
|
|
// MaxUint32 is the largest uint32 value. |
|
const MaxUint32 = 4294967295 |
|
|
|
// MaxUint16 is the largest 16 bit unsigned int. |
|
// This is the largest value an interval16 can store. |
|
const MaxUint16 = 65535 |
|
|
|
// searchOptions allows us to accelerate runContainer32.search with |
|
// prior knowledge of (mostly lower) bounds. This is used by Union |
|
// and Intersect. |
|
type searchOptions struct { |
|
// start here instead of at 0 |
|
startIndex int64 |
|
|
|
// upper bound instead of len(rc.iv); |
|
// endxIndex == 0 means ignore the bound and use |
|
// endxIndex == n ==len(rc.iv) which is also |
|
// naturally the default for search() |
|
// when opt = nil. |
|
endxIndex int64 |
|
} |
|
|
|
// And finds the intersection of rc and b. |
|
func (rc *runContainer32) And(b *Bitmap) *Bitmap { |
|
out := NewBitmap() |
|
for _, p := range rc.iv { |
|
for i := p.start; i <= p.last; i++ { |
|
if b.Contains(i) { |
|
out.Add(i) |
|
} |
|
} |
|
} |
|
return out |
|
} |
|
|
|
// Xor returns the exclusive-or of rc and b. |
|
func (rc *runContainer32) Xor(b *Bitmap) *Bitmap { |
|
out := b.Clone() |
|
for _, p := range rc.iv { |
|
for v := p.start; v <= p.last; v++ { |
|
if out.Contains(v) { |
|
out.RemoveRange(uint64(v), uint64(v+1)) |
|
} else { |
|
out.Add(v) |
|
} |
|
} |
|
} |
|
return out |
|
} |
|
|
|
// Or returns the union of rc and b. |
|
func (rc *runContainer32) Or(b *Bitmap) *Bitmap { |
|
out := b.Clone() |
|
for _, p := range rc.iv { |
|
for v := p.start; v <= p.last; v++ { |
|
out.Add(v) |
|
} |
|
} |
|
return out |
|
} |
|
|
|
// trial is used in the randomized testing of runContainers |
|
type trial struct { |
|
n int |
|
percentFill float64 |
|
ntrial int |
|
|
|
// only in the union test |
|
// only subtract test |
|
percentDelete float64 |
|
|
|
// only in 067 randomized operations |
|
// we do this + 1 passes |
|
numRandomOpsPass int |
|
|
|
// allow sampling range control |
|
// only recent tests respect this. |
|
srang *interval16 |
|
} |
|
|
|
// And finds the intersection of rc and b. |
|
func (rc *runContainer16) And(b *Bitmap) *Bitmap { |
|
out := NewBitmap() |
|
for _, p := range rc.iv { |
|
plast := p.last() |
|
for i := p.start; i <= plast; i++ { |
|
if b.Contains(uint32(i)) { |
|
out.Add(uint32(i)) |
|
} |
|
} |
|
} |
|
return out |
|
} |
|
|
|
// Xor returns the exclusive-or of rc and b. |
|
func (rc *runContainer16) Xor(b *Bitmap) *Bitmap { |
|
out := b.Clone() |
|
for _, p := range rc.iv { |
|
plast := p.last() |
|
for v := p.start; v <= plast; v++ { |
|
w := uint32(v) |
|
if out.Contains(w) { |
|
out.RemoveRange(uint64(w), uint64(w+1)) |
|
} else { |
|
out.Add(w) |
|
} |
|
} |
|
} |
|
return out |
|
} |
|
|
|
// Or returns the union of rc and b. |
|
func (rc *runContainer16) Or(b *Bitmap) *Bitmap { |
|
out := b.Clone() |
|
for _, p := range rc.iv { |
|
plast := p.last() |
|
for v := p.start; v <= plast; v++ { |
|
out.Add(uint32(v)) |
|
} |
|
} |
|
return out |
|
} |
|
|
|
//func (rc *runContainer32) and(container) container { |
|
// panic("TODO. not yet implemented") |
|
//} |
|
|
|
// serializedSizeInBytes returns the number of bytes of memory |
|
// required by this runContainer16. This is for the |
|
// Roaring format, as specified https://github.com/RoaringBitmap/RoaringFormatSpec/ |
|
func (rc *runContainer16) serializedSizeInBytes() int { |
|
// number of runs in one uint16, then each run |
|
// needs two more uint16 |
|
return 2 + len(rc.iv)*4 |
|
} |
|
|
|
// serializedSizeInBytes returns the number of bytes of memory |
|
// required by this runContainer32. |
|
func (rc *runContainer32) serializedSizeInBytes() int { |
|
return 4 + len(rc.iv)*8 |
|
}
|
|
|