mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-12 15:51:01 +00:00
initial bit shift functions for all container type
This commit is contained in:
parent
e472ed3984
commit
933d5e28e7
3 changed files with 210 additions and 0 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue