featurebase/iterator_test.go
Ben Johnson de698aa03e consensus block merge
This commit refactors the anti-entropy system to fetch data from
all replicated blocks and only set/clear bits which deviate from
the consensus between all blocks.

An example of this is if 3 nodes had the following bits set for
a single bitmap:

	Node A: 1 2 3
	Node B:   2   4
	Node C: 1 2   4

Then only bits which are set on a majority will be set. In this
case bits 1, 2, & 4 are set but 3 only exists on a single node.

The node performing the merge would then determine the following
set/clear diffs for each node:

	Node A: clear(3), set(4)
	Node B: set(1)
	Node C: none

Once the merge is performed and all nodes receive their diff
instructions then the nodes will be in sync:

	Node A: 1 2 4
	Node B: 1 2 4
	Node C: 1 2 4

There still exists situations where bits can be reset. If Node A
is up and Node B & C are down then Node A's bits will be reset
once B & C come back online. We should add write consistency
settings for incoming writes so that we can ensure that a quorum
is written to before returning a success. This is outside the
scope of this commit though.
2016-05-06 16:19:10 -06:00

74 lines
1.8 KiB
Go

package pilosa_test
import (
"reflect"
"testing"
"github.com/umbel/pilosa"
)
// Ensure slice iterator and iterate over a set of pairs.
func TestSliceIterator(t *testing.T) {
// Initialize iterator.
itr := pilosa.NewSliceIterator(
[]uint64{0, 0, 2, 4},
[]uint64{0, 1, 0, 10},
)
// Iterate over all pairs.
var pairs [][2]uint64
for pid, bid, eof := itr.Next(); !eof; pid, bid, eof = itr.Next() {
pairs = append(pairs, [2]uint64{pid, bid})
}
// Verify pairs output correctly.
if !reflect.DeepEqual(pairs, [][2]uint64{
{0, 0},
{0, 1},
{2, 0},
{4, 10},
}) {
t.Fatalf("unexpected pairs: %+v", pairs)
}
}
// Ensure buffered iterator can unread values on to the buffer.
func TestBufIterator(t *testing.T) {
itr := pilosa.NewBufIterator(pilosa.NewSliceIterator(
[]uint64{0, 0, 1, 2},
[]uint64{1, 3, 0, 100},
))
itr.Seek(0, 2)
if pid, bid, eof := itr.Next(); pid != 0 || bid != 3 || eof {
t.Fatalf("unexpected seek: (%d, %d, %v)", pid, bid, eof)
} else if pid, bid, eof := itr.Next(); pid != 1 || bid != 0 || eof {
t.Fatalf("unexpected next: (%d, %d, %v)", pid, bid, eof)
}
itr.Unread()
if pid, bid, eof := itr.Next(); pid != 1 || bid != 0 || eof {
t.Fatalf("unexpected next(buffered): (%d, %d, %v)", pid, bid, eof)
}
if pid, bid, eof := itr.Next(); pid != 2 || bid != 100 || eof {
t.Fatalf("unexpected next: (%d, %d, %v)", pid, bid, eof)
} else if _, _, eof := itr.Next(); !eof {
t.Fatal("expected eof")
}
}
// Ensure buffered iterator will panic if unreading onto a full buffer.
func TestBufIterator_DoubleFillPanic(t *testing.T) {
var v interface{}
func() {
defer func() { v = recover() }()
itr := pilosa.NewBufIterator(pilosa.NewSliceIterator(nil, nil))
itr.Unread()
itr.Unread()
}()
if !reflect.DeepEqual(v, "pilosa.BufIterator: buffer full") {
t.Fatalf("unexpected panic value: %#v", v)
}
}