support for Difference

This commit is contained in:
Todd Gruben 2014-07-25 21:02:04 +00:00
parent 48d6c56533
commit c0058c0904
5 changed files with 65 additions and 4 deletions

View file

@ -260,7 +260,7 @@ func Union(a_bm IBitmap, b_bm IBitmap) IBitmap {
return output
}
func AND_NOT(a_bm IBitmap, b_bm IBitmap) IBitmap {
func Difference(a_bm IBitmap, b_bm IBitmap) IBitmap {
var a = a_bm.Min()
var b = b_bm.Min()
defer a.Close()

View file

@ -3,6 +3,7 @@ package index
import (
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
)
@ -17,17 +18,32 @@ func TestBitmaps(t *testing.T) {
So(bc1, ShouldEqual, bc2)
So(bc1, ShouldEqual, 4096)
})
Convey("function AND_NOT 1 and not 0 => true ", t, func() {
Convey("function Difference 1 and not 0 => true ", t, func() {
bm1 := CreateRBBitmap()
bm2 := CreateRBBitmap()
SetBit(bm1, 1)
//SetBit(bm2,2)
all := AND_NOT(bm1, bm2)
all := Difference(bm1, bm2)
res := BitCount(all)
So(1, ShouldEqual, res)
})
Convey("function Difference 1 and not 0 => true ", t, func() {
bm1 := CreateRBBitmap()
bm2 := CreateRBBitmap()
SetBit(bm1, 1)
SetBit(bm1, 2)
SetBit(bm1, 3)
SetBit(bm1, 4)
SetBit(bm2, 3)
//SetBit(bm2,2)
all := Difference(bm1, bm2)
res := BitCount(all)
So(3, ShouldEqual, res)
})
Convey("UNION even + odd equal 4096 ", t, func() {
even := CreateRBBitmap()
for i := uint64(0); i < uint64(4096); i += 2 {

View file

@ -79,6 +79,19 @@ func (self *CmdUnion) Execute(f *Fragment) Calculation {
return f.union(self.bitmap_ids)
}
type CmdDifference struct {
*Responder
bitmap_ids []BitmapHandle
}
func NewDifference(bitmaps []BitmapHandle) *CmdDifference {
result := &CmdDifference{NewResponder("Difference"), bitmaps}
return result
}
func (self *CmdDifference) Execute(f *Fragment) Calculation {
return f.difference(self.bitmap_ids)
}
type CmdIntersect struct {
*Responder
bitmaps []BitmapHandle

View file

@ -115,6 +115,17 @@ func (self *FragmentContainer) Union(frag_id util.SUUID, bh []BitmapHandle) (Bit
return 0, errors.New("Invalid Bitmap Handle")
}
func (self *FragmentContainer) Difference(frag_id util.SUUID, bh []BitmapHandle) (BitmapHandle, error) {
if fragment, found := self.GetFragment(frag_id); found {
request := NewDifference(bh)
fragment.requestChan <- request
result := request.Response()
util.SendTimer("fragmant_container_Difference", result.exec_time.Nanoseconds())
return result.answer.(BitmapHandle), nil
}
return 0, errors.New("Invalid Bitmap Handle")
}
func (self *FragmentContainer) Get(frag_id util.SUUID, bitmap_id uint64) (BitmapHandle, error) {
if fragment, found := self.GetFragment(frag_id); found {
request := NewGet(bitmap_id)
@ -316,6 +327,7 @@ func (self *Fragment) union(bitmaps []BitmapHandle) BitmapHandle {
}
return self.AllocHandle(result)
}
func (self *Fragment) intersect(bitmaps []BitmapHandle) BitmapHandle {
var result IBitmap
for i, id := range bitmaps {
@ -328,6 +340,20 @@ func (self *Fragment) intersect(bitmaps []BitmapHandle) BitmapHandle {
}
return self.AllocHandle(result)
}
func (self *Fragment) difference(bitmaps []BitmapHandle) BitmapHandle {
result := NewBitmap()
for i, id := range bitmaps {
bm, _ := self.getBitmap(id)
if i == 0 {
result = bm
} else {
result = Difference(result, bm)
}
}
return self.AllocHandle(result)
}
func (self *Fragment) Persist() {
err := self.impl.Persist()
if err != nil {

View file

@ -6,6 +6,7 @@ import (
// "io/ioutil"
// "time"
"pilosa/util"
. "github.com/smartystreets/goconvey/convey"
)
@ -35,7 +36,7 @@ func TestFragment(t *testing.T) {
So(num, ShouldEqual, 1)
})
Convey("Union/Intersect", t, func() {
Convey("Union/Intersect/Difference", t, func() {
bi1 := uint64(1234)
bi2 := uint64(4321)
@ -53,6 +54,11 @@ func TestFragment(t *testing.T) {
num, _ = dummy.Count(general, result)
So(num, ShouldEqual, 0)
result, _ = dummy.Difference(general, handles)
num, _ = dummy.Count(general, result)
So(num, ShouldEqual, 1)
})
Convey("Union Empty", t, func() {