added difference for run and array containers

This commit is contained in:
Todd Gruben 2017-06-14 13:52:57 -05:00 committed by Matt Jaffee
parent 970795bac1
commit ccef8be844
2 changed files with 73 additions and 4 deletions

View file

@ -2394,6 +2394,7 @@ func difference(a, b *container) *container {
}
}
// differenceArrayArray computes the difference bween two arrays.
func differenceArrayArray(a, b *container) *container {
output := &container{}
na, nb := len(a.array), len(b.array)
@ -2418,6 +2419,7 @@ func differenceArrayArray(a, b *container) *container {
return output
}
// differenceArrayRun computes the difference of an array from a run.
func differenceArrayRun(a, b *container) *container {
// func (ac *arrayContainer) iandNotRun16(rc *runContainer16) container {
@ -2458,6 +2460,7 @@ func differenceArrayRun(a, b *container) *container {
return output
}
// differenceBitmapRun computes the difference of an bitmap from a run.
func differenceBitmapRun(a, b *container) *container {
if a.n == 0 || b.n == 0 {
return a.clone()
@ -2470,16 +2473,65 @@ func differenceBitmapRun(a, b *container) *container {
return output
}
// differenceRunArray computes the difference of an run from a array.
func differenceRunArray(a, b *container) *container {
// TODO
if a.n == 0 || b.n == 0 {
return a.clone()
}
output := &container{runs: make([]interval32, 0, a.n)}
i := 0
j := 0
vr := a.runs[j]
working := true
for working {
switch {
case b.array[i] < vr.start: //before
case b.array[i] > vr.last: //after
if vr.start <= vr.last {
output.n += output.runAppendInterval(vr)
}
j++
if j < len(a.runs) {
vr = a.runs[j]
} else {
working = false
}
case b.array[i] == vr.start: //begining of run
vr.start++
case b.array[i] == a.runs[j].last: //end of run
vr.last--
if vr.last >= vr.start {
output.n += output.runAppendInterval(vr)
}
j++
if j < len(a.runs) {
vr = a.runs[j]
} else {
working = false
}
case b.array[i] > vr.start: //inside run
output.n += output.runAppendInterval(interval32{start: vr.start, last: b.array[i] - 1})
vr.start = b.array[i] + 1
}
i++
if i >= len(b.array) {
working = false
}
}
if vr.start <= vr.last {
output.n += output.runAppendInterval(vr)
}
if output.n < ArrayMaxSize && len(output.runs) > output.n/2 {
output.runToArray()
} else if len(output.runs) > RunMaxSize {
output.runToBitmap()
}
return output
}
// differenceRunBitmap computes the difference of an run from a bitmap.
func differenceRunBitmap(a, b *container) *container {
// TODO
if a.n == 0 || b.n == 0 {
@ -2502,6 +2554,7 @@ func differenceRunBitmap(a, b *container) *container {
return output
}
// differenceRunRun computes the difference of two runs.
func differenceRunRun(a, b *container) *container {
if a.n == 0 || b.n == 0 {
return a.clone()

View file

@ -1113,7 +1113,6 @@ func TestDifferenceArrayRun(t *testing.T) {
}
}
/*
func TestDifferenceRunArray(t *testing.T) {
a := &container{}
b := &container{}
@ -1127,6 +1126,21 @@ func TestDifferenceRunArray(t *testing.T) {
array: []uint32{5, 6, 7, 8, 9, 10},
exp: []interval32{{start: 0, last: 4}, {start: 11, last: 12}},
},
{
runs: []interval32{{start: 0, last: 12}},
array: []uint32{0, 1, 2, 3},
exp: []interval32{{start: 4, last: 12}},
},
{
runs: []interval32{{start: 0, last: 12}},
array: []uint32{9, 10, 11, 12, 13},
exp: []interval32{{start: 0, last: 8}},
},
{
runs: []interval32{{start: 1, last: 12}},
array: []uint32{0, 9, 10, 11, 12, 13},
exp: []interval32{{start: 1, last: 8}},
},
}
for i, test := range tests {
a.runs = test.runs
@ -1134,12 +1148,14 @@ func TestDifferenceRunArray(t *testing.T) {
b.array = test.array
b.n = len(b.array)
ret := differenceRunArray(a, b)
if !reflect.DeepEqual(ret.array, test.exp) {
t.Fatalf("test #%v expected %v, but got %v", i, test.exp, ret.array)
if !reflect.DeepEqual(ret.runs, test.exp) {
t.Fatalf("test #%v expected %v, but got %v", i, test.exp, ret.runs)
}
}
}
/*
func TestDifferenceRunBitmap(t *testing.T) {
a := &container{}
b := &container{bitmap: make([]uint64, bitmapN)}