initial bit shift functions for all container type

This commit is contained in:
Todd Gruben 2018-11-20 15:12:02 -06:00
parent e472ed3984
commit 933d5e28e7
3 changed files with 210 additions and 0 deletions

View file

@ -3006,6 +3006,85 @@ func xorBitmapBitmap(a, b *Container) *Container {
return output
}
func shift(a *Container) (*Container, bool) {
if a.isArray() {
return shiftArray(a)
} else if a.isRun() {
return shiftRun(a)
}
return shiftBitmap(a)
}
func shiftArray(a *Container) (*Container, bool) {
statsHit("shift/Array")
carry := false
output := &Container{containerType: containerArray}
output.array = make([]uint16, len(a.array))
output.array = output.array[:0]
output.n = a.n
for _, v := range a.array {
fmt.Println(v,v+1)
if v+1 == 0 { //overflow
carry = true
output.n -= 1
} else {
output.array = append(output.array, v+1)
}
}
return output, carry
}
func shiftBitmap(a *Container) (*Container, bool) {
statsHit("shift/Bitmap")
carry := false
output := &Container{containerType: containerBitmap}
output.bitmap = make([]uint64, len(a.bitmap))
output.bitmap = output.bitmap[:0]
output.n = a.n
lastcarry:=false
for i, v := range a.bitmap {
carry = (v&(1<<63))!= 0
v = v << 1
if i != 0 {
if lastcarry {
v |= 1
}
}
output.bitmap = append(output.bitmap, v)
lastcarry = carry
}
if carry {
output.n -= 1
}
return output, carry
}
func shiftRun(a *Container) (*Container, bool) {
statsHit("shift/Run")
carry := false
output := &Container{containerType: containerRun}
output.runs = make([]interval16, len(a.runs))
output.runs = output.runs[:0]
for _, v := range a.runs {
if v.start+1 == 0 {
carry = true
output.n -= 1
break
} else if v.last+1 == 0 {
v.start += 1
carry = true
output.n -= 1
} else {
v.start += 1
v.last += 1
carry = false
}
output.runs = append(output.runs, v)
}
return output, carry
}
// opType represents a type of operation.
type opType uint8

View file

@ -106,6 +106,25 @@ func bitmapFirstBitSet() []uint64 {
return bitmap
}
func bitmapSecondBitSet() []uint64 {
bitmap := make([]uint64, bitmapN)
bitmap[0] = 0x0000000000000002
return bitmap
}
func bitmapLastBitFirstRowSet() []uint64 {
bitmap := make([]uint64, bitmapN)
bitmap[0] = 0x8000000000000000
return bitmap
}
func bitmapFirstBitSecoundRowSet() []uint64 {
bitmap := make([]uint64, bitmapN)
bitmap[1] = 0x0000000000000001
return bitmap
}
func bitmapLastBitSet() []uint64 {
bitmap := make([]uint64, bitmapN)
bitmap[bitmapN-1] = 0x8000000000000000

View file

@ -3289,3 +3289,115 @@ func TestEquals(t *testing.T) {
}
}
*/
func TestShiftArray(t *testing.T) {
a := &Container{
containerType: containerArray,
}
tests := []struct {
array []uint16
exp []uint16
}{
{
array: []uint16{1},
exp: []uint16{2},
},
{
array: []uint16{},
exp: []uint16{},
},
{
array: []uint16{1, 2, 3, 4, 5, 11, 12},
exp: []uint16{2, 3, 4, 5, 6, 12,13},
},
{
array: []uint16{65535},
exp: []uint16{},
},
}
for i, test := range tests {
a.array = test.array
a.n = int32(len(a.array))
ret,_ := shiftArray(a)
if !reflect.DeepEqual(ret.array, test.exp) {
t.Fatalf("test #%v expected %v, but got %v", i, test.exp, ret.array)
}
}
}
func TestShiftBitmap(t *testing.T) {
a := &Container{
containerType: containerBitmap,
}
tests := []struct {
bitmap []uint64
exp []uint64
}{
{
bitmap:bitmapFirstBitSet() ,
exp: bitmapSecondBitSet(),
},
{
bitmap:bitmapLastBitSet() ,
exp: bitmapEmpty(),
},
{
bitmap:bitmapLastBitFirstRowSet() ,
exp: bitmapFirstBitSecoundRowSet (),
},
}
for i, test := range tests {
a.bitmap = test.bitmap
a.n = 1
ret,_ := shiftBitmap(a)
if !reflect.DeepEqual(ret.bitmap, test.exp) {
t.Fatalf("test #%v expected %v, but got %v", i, test.exp, ret.bitmap)
}
}
}
func TestShiftRun(t *testing.T) {
a := &Container{
containerType: containerRun,
}
tests := []struct {
runs []interval16
n int32
en int32
exp []interval16
carry bool
}{
{
runs: []interval16{{start: 5, last: 10}},
n: 5,
en: 5,
exp: []interval16{{start: 6, last: 11}},
carry: false,
},
{
runs: []interval16{{start: 5, last:65535 }},
n: 65530,
en: 65529,
exp: []interval16{{start: 6, last: 65535}},
carry: true,
},
{
runs: []interval16{{start: 65535, last:65535 }},
n: 1,
en: 0,
exp: []interval16{},
carry: true,
},
}
for i, test := range tests {
a.runs = test.runs
a.n = test.n
ret,c := shiftRun(a)
if !reflect.DeepEqual(ret.runs, test.exp) && c == test.carry && ret.n == test.en {
t.Fatalf("test #%v expected %v, but got %v %d", i, test.exp, ret.runs,ret.n)
}
}
}