mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
185 lines
4.6 KiB
Go
185 lines
4.6 KiB
Go
// Copyright 2021 Molecula Corp. All rights reserved.
|
|
package pilosa_test
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/molecula/featurebase/v3"
|
|
)
|
|
|
|
// Ensure a row can be merged
|
|
func TestRow_Merge(t *testing.T) {
|
|
tests := []struct {
|
|
r1 *pilosa.Row
|
|
r2 *pilosa.Row
|
|
exp uint64
|
|
}{
|
|
{
|
|
r1: pilosa.NewRow(1, 2, 3, ShardWidth+1, 2*ShardWidth),
|
|
r2: pilosa.NewRow(3, 4, 5),
|
|
exp: 7,
|
|
},
|
|
{
|
|
r1: pilosa.NewRow(),
|
|
r2: pilosa.NewRow(2, 66000, 70000, 70001, 70002, 70003, 70004),
|
|
exp: 7,
|
|
},
|
|
}
|
|
|
|
for i, test := range tests {
|
|
t.Run(fmt.Sprintf("#%d:", i), func(t *testing.T) {
|
|
test.r1.Merge(test.r2)
|
|
if cnt := test.r1.Count(); cnt != test.exp {
|
|
t.Fatalf("merged count %d is not %d", cnt, test.exp)
|
|
}
|
|
if length := len(test.r1.Columns()); uint64(length) != test.exp {
|
|
t.Fatalf("merged length %d is not %d", length, test.exp)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Ensure a row can Xor'ed
|
|
func TestRow_Xor(t *testing.T) {
|
|
r1 := pilosa.NewRow(0, 1, ShardWidth)
|
|
r2 := pilosa.NewRow(0, 2*ShardWidth)
|
|
exp := []uint64{1, ShardWidth, 2 * ShardWidth}
|
|
|
|
res := r1.Xor(r2)
|
|
if res.Count() != 3 {
|
|
t.Fatalf("Test 1 Count after xor %d != 3\n", res.Count())
|
|
}
|
|
|
|
if !reflect.DeepEqual(res.Columns(), exp) {
|
|
t.Fatalf("Test 2 Results %v != expected %v\n", res.Columns(), exp)
|
|
}
|
|
res = r2.Xor(r1)
|
|
if res.Count() != 3 {
|
|
t.Fatalf("Test 3 Count after xor %d != 3\n", res.Count())
|
|
}
|
|
if !reflect.DeepEqual(res.Columns(), exp) {
|
|
t.Fatalf("Test 4 Results %v != expected %v\n", res.Columns(), exp)
|
|
}
|
|
|
|
}
|
|
func TestRow_Union_Segment(t *testing.T) {
|
|
r1 := pilosa.NewRow(0, 1, ShardWidth)
|
|
r2 := pilosa.NewRow(0, 2*ShardWidth)
|
|
exp := []uint64{0, 1, ShardWidth, 2 * ShardWidth}
|
|
res := r1.Union(r2)
|
|
|
|
if res.Count() != 4 {
|
|
t.Fatalf("Test 1 Count after Union %d != 5\n", res.Count())
|
|
}
|
|
if !reflect.DeepEqual(res.Columns(), exp) {
|
|
t.Fatalf("Test 2 Union Results %v != expected %v\n", res.Columns(), exp)
|
|
}
|
|
res = r2.Union(r1)
|
|
if res.Count() != 4 {
|
|
t.Fatalf("Test 3 Count after xor %d != 5\n", res.Count())
|
|
}
|
|
if !reflect.DeepEqual(res.Columns(), exp) {
|
|
t.Fatalf("Test 2 Union Results %v != expected %v\n", res.Columns(), exp)
|
|
}
|
|
}
|
|
|
|
func TestRow_Difference_Segment(t *testing.T) {
|
|
r1 := pilosa.NewRow(0, 1, ShardWidth)
|
|
r2 := pilosa.NewRow(0, 2*ShardWidth)
|
|
exp := []uint64{1, ShardWidth}
|
|
res := r1.Difference(r2)
|
|
|
|
if res.Count() != 2 {
|
|
t.Fatalf("Test 1 Count after Difference %d != 5\n", res.Count())
|
|
}
|
|
if !reflect.DeepEqual(res.Columns(), exp) {
|
|
t.Fatalf("Test 2 Difference Results %v != expected %v\n", res.Columns(), exp)
|
|
}
|
|
}
|
|
|
|
func TestRow_IsEmpty(t *testing.T) {
|
|
r1 := pilosa.NewRow(1, ShardWidth)
|
|
r2 := pilosa.NewRow(0, 2*ShardWidth)
|
|
res := r2.Intersect(r1)
|
|
|
|
if r1.IsEmpty() {
|
|
t.Fatal("r1 Should Not Be Empty\n")
|
|
}
|
|
if !res.IsEmpty() {
|
|
t.Fatal("Result Should Be Empty\n")
|
|
}
|
|
}
|
|
|
|
func TestRow_Includes(t *testing.T) {
|
|
row := pilosa.NewRow(0, 2*ShardWidth)
|
|
|
|
if !row.Includes(0) {
|
|
t.Fatal("row should include 0")
|
|
}
|
|
if row.Includes(1) {
|
|
t.Fatal("row should not include 1")
|
|
}
|
|
if !row.Includes(2 * ShardWidth) {
|
|
t.Fatalf("row should include %d", 2*ShardWidth)
|
|
}
|
|
}
|
|
|
|
func TestRow_DifferenceInPlace(t *testing.T) {
|
|
row0 := pilosa.NewRow(0)
|
|
row1 := pilosa.NewRow()
|
|
row2 := pilosa.NewRow(0)
|
|
res := row0.Difference(row1, row2)
|
|
|
|
if !row0.Includes(0) {
|
|
t.Fatal("row should include 0")
|
|
}
|
|
if res.Count() != 0 {
|
|
t.Fatal("results should be empty")
|
|
}
|
|
}
|
|
func eq(a, b []uint64) bool {
|
|
if len(a) != len(b) {
|
|
return false
|
|
}
|
|
for i, v := range a {
|
|
if v != b[i] {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
func TestRow_DifferenceInPlace2(t *testing.T) {
|
|
lucky := []uint64{1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63, 67, 69, 73, 75, 79, 87, 93, 99, 105, 111, 115, 127, 129, 133, 135, 141, 151, 159, 163, 169, 171, 189, 193, 195, 201, 205, 211, 219, 223, 231, 235, 237, 241, 259, 261, 267, 273, 283, 285, 289, 297}
|
|
src := pilosa.NewRow(lucky...)
|
|
row1 := pilosa.NewRow()
|
|
m := uint64(9)
|
|
for i := m; i <= lucky[len(lucky)-1]; i += m {
|
|
row1.SetBit(i)
|
|
}
|
|
m = uint64(3)
|
|
row2 := pilosa.NewRow()
|
|
for i := m; i <= lucky[len(lucky)-1]; i += m {
|
|
row2.SetBit(i)
|
|
}
|
|
row3 := pilosa.NewRow()
|
|
m = uint64(5)
|
|
for i := m; i <= lucky[len(lucky)-1]; i += m {
|
|
row3.SetBit(i)
|
|
}
|
|
row4 := pilosa.NewRow()
|
|
m = uint64(7)
|
|
for i := m; i <= lucky[len(lucky)-1]; i += m {
|
|
row4.SetBit(i)
|
|
}
|
|
res5 := src.Difference(row1, row2, row3, row4)
|
|
res6 := src.Difference(row4, row3, row2, row1)
|
|
res7 := src.Difference(row4).Difference(row3).Difference(row2).Difference(row1)
|
|
if !eq(res5.Columns(), res6.Columns()) {
|
|
t.Fatalf("results do not match: %v, %v", res5.Columns(), res6.Columns())
|
|
}
|
|
if !eq(res6.Columns(), res7.Columns()) {
|
|
t.Fatalf("results do not match: %v, %v", res6.Columns(), res7.Columns())
|
|
}
|
|
}
|