Skip to content

Commit

Permalink
Add ToBitlist() and ToBitlist64() conversion methods (#41)
Browse files Browse the repository at this point in the history
* Add ToBitlist() and ToBitlist64() conversion methods

* double conversion check
  • Loading branch information
farazdagi authored Jan 29, 2021
1 parent 6e8547d commit 0db5713
Show file tree
Hide file tree
Showing 4 changed files with 267 additions and 0 deletions.
5 changes: 5 additions & 0 deletions bitlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ func (b Bitlist) BytesNoTrim() []byte {
return ret
}

// ToBitlist64 converts []byte backed bitlist into []uint64 backed bitlist.
func (b Bitlist) ToBitlist64() *Bitlist64 {
return NewBitlist64FromBytes(b.BytesNoTrim())
}

// Count returns the number of 1s in the bitlist.
func (b Bitlist) Count() uint64 {
c := 0
Expand Down
16 changes: 16 additions & 0 deletions bitlist64.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,22 @@ func (b *Bitlist64) Bytes() []byte {
return ret[:len(ret)-allLeadingZeroes>>bytesInWordLog2]
}

// ToBitlist converts []uint64 backed bitlist into []byte backed bitlist.
func (b *Bitlist64) ToBitlist() Bitlist {
if len(b.data) == 0 {
return Bitlist{}
}

ret := make([]byte, len(b.data)*bytesInWord)
for idx, word := range b.data {
start := idx << bytesInWordLog2
binary.LittleEndian.PutUint64(ret[start:start+bytesInWord], word)
}

// Append size byte when returning.
return append(ret, 0x1)
}

// Count returns the number of 1s in the bitlist.
func (b *Bitlist64) Count() uint64 {
c := 0
Expand Down
82 changes: 82 additions & 0 deletions bitlist64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,88 @@ func TestBitlist64_NewBitlist64FromBytes(t *testing.T) {
}
}

func TestBitlist64_ToBitlist(t *testing.T) {
tests := []struct {
from *Bitlist64
want Bitlist
}{
{
from: &Bitlist64{size: 0, data: []uint64{}},
want: Bitlist{},
},
{
from: &Bitlist64{size: 64, data: []uint64{0x0000000000000000}},
want: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
},
{
from: &Bitlist64{size: 64, data: []uint64{0xFFFFFFFFFFFFFFFF}},
want: []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01},
},
{
from: &Bitlist64{size: 128, data: []uint64{0x02, 0x01}},
want: []byte{
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01,
},
},
{
from: &Bitlist64{size: 64, data: []uint64{0xF0DEBC9A78563412}},
want: []byte{0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x01},
},
{
from: &Bitlist64{size: 128, data: []uint64{0x00, 0x00}},
want: []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01,
},
},
{
from: &Bitlist64{size: 128, data: []uint64{0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}},
want: []byte{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x01,
},
},
{
from: &Bitlist64{size: 128, data: []uint64{0xFFFFFFFFFFFFFFF1, 0xFFFFFFFFFFFFFFF2}},
want: []byte{
0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x01,
},
},
{
from: &Bitlist64{size: 192, data: []uint64{
0xFFFFFFFFFFFFFFF1,
0xFFFFFFFFFFFFFFF2,
0x00F4FFFFFFFFFFF3,
}},
want: []byte{
0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00,
0x01,
},
},
}

for _, tt := range tests {
t.Run(fmt.Sprintf("data:%#x", tt.from), func(t *testing.T) {
got := tt.from.ToBitlist()
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("ToBitlist(%#x) = %+v, wanted %+v", tt.from, got, tt.want)
}
from := tt.from.ToBitlist().ToBitlist64()
if !reflect.DeepEqual(from, tt.from) {
t.Errorf("ToBitlist(%#x).ToBitlist64() = %+v, wanted %+v", tt.from, from, tt.from)
}
})
}
}

func TestBitlist64_Len(t *testing.T) {
tests := []struct {
bitlist *Bitlist64
Expand Down
164 changes: 164 additions & 0 deletions bitlist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,170 @@ func TestBitlist_BytesNoTrim(t *testing.T) {
}
}

func TestBitlist_ToBitlist64(t *testing.T) {
tests := []struct {
bitlist Bitlist
want *Bitlist64
}{
{
bitlist: Bitlist{},
want: &Bitlist64{
size: 0,
data: []uint64{},
},
},
{
bitlist: Bitlist{0x00},
want: &Bitlist64{
size: 0,
data: []uint64{},
},
},
{
bitlist: Bitlist{0x01},
want: &Bitlist64{
size: 0,
data: []uint64{},
},
},
{
bitlist: Bitlist{0x02},
want: &Bitlist64{
size: 64,
data: []uint64{0x00},
},
},
{
bitlist: Bitlist{0x03},
want: &Bitlist64{
size: 64,
data: []uint64{0x01},
},
},
{
bitlist: Bitlist{0x12},
want: &Bitlist64{
size: 64,
data: []uint64{0x02},
},
},
{
bitlist: Bitlist{0x02, 0x01},
want: &Bitlist64{
size: 64,
data: []uint64{0x02},
},
},
{
bitlist: Bitlist{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01,
},
want: &Bitlist64{
size: 64,
data: []uint64{0x02000000000000},
},
},
{
bitlist: Bitlist{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01,
},
want: &Bitlist64{
size: 64,
data: []uint64{0x0200000000000000},
},
},
{
bitlist: Bitlist{
0x04, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x01,
},
want: &Bitlist64{
size: 128,
data: []uint64{0x0000000000060504, 0x0000000000020000},
},
},
{
bitlist: Bitlist{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02,
},
want: &Bitlist64{
size: 128,
data: []uint64{0x0200000000000000, 0x0002000000000000},
},
},
{
bitlist: Bitlist{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02,
},
want: &Bitlist64{
size: 192,
data: []uint64{0x00, 0x0200000000000000, 0x0002000000000000},
},
},
{
bitlist: Bitlist{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03,
},
want: &Bitlist64{
size: 128,
data: []uint64{0x0200000000000000, 0x0102000000000000},
},
},
{
bitlist: Bitlist{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08,
},
want: &Bitlist64{
size: 128,
data: []uint64{0x0200000000000000, 0x0002000000000000},
},
},
{
bitlist: Bitlist{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
},
want: &Bitlist64{
size: 192,
data: []uint64{0x00, 0x00, 0x00},
},
},
{
bitlist: Bitlist{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
},
want: &Bitlist64{
size: 128,
data: []uint64{0x00, 0x00},
},
},
{
bitlist: Bitlist{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
},
want: &Bitlist64{
size: 128,
data: []uint64{0x00, 0x00},
},
},
}

for _, tt := range tests {
got := tt.bitlist.ToBitlist64()
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("(%#x).ToBitlist64() = %#v, wanted %#v", tt.bitlist, got, tt.want)
}
}
}

func TestBitlist_Count(t *testing.T) {
tests := []struct {
bitlist Bitlist
Expand Down

0 comments on commit 0db5713

Please sign in to comment.