mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-09 22:51:02 +00:00
support for Difference
This commit is contained in:
parent
48d6c56533
commit
c0058c0904
5 changed files with 65 additions and 4 deletions
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue