164 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
| 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
 | |
| }
 |