Commit 859fa010 authored by Jonathan Mace's avatar Jonathan Mace

Update iterators and tests

parent 60824a34
......@@ -16,16 +16,30 @@ type reader struct {
err error
}
func Read(atoms atomlayer.BaggageContext) (r reader) {
r.remaining = atoms
type Reader *reader
func Read(baggage atomlayer.BaggageContext) (r reader) {
r.remaining = baggage
r.level = -1
r.advance()
return
}
func Open(atoms atomlayer.BaggageContext, bagIndex uint64) (r reader) {
// TODO: this
return Read(atoms)
// Reads data from the specified bag, only tracking skipped atoms from this bag.
func Open(baggage atomlayer.BaggageContext, bagIndex uint64) (r reader) {
target := MakeIndexedHeader(0, bagIndex)
exists, overflowed, i := find(baggage, 0, target)
r.overflowed = overflowed
r.level = 0
if exists {
_,_,j := find(baggage, i+1, target)
r.remaining = baggage[i+1:j]
}
r.advance()
return
}
// Closes the reader, treating all remaining atoms as skipped
......@@ -48,7 +62,7 @@ func (r *reader) Close() {
}
// Advances r.next zero or more atoms, until it's a header atom. If it's already a header atom, does nothing.
// Returns the headeratom and its level.
// Returns the header atom and its level.
func (r *reader) advanceToNextHeader() (atomlayer.Atom, int) {
for {
switch {
......@@ -253,4 +267,22 @@ func invalidGrandchild(currentLevel, childLevel int) error {
func invalidExit() error {
return fmt.Errorf("Exit called too many times without corresponding bag entries")
}
// Finds the specified atom in the baggage, stopping at the first atom lexicographically larger than it.
// Returns:
// exists - true if the atom was found, false otherwise
// overflowed - true if the overflow marker was found between startat and i, false otherwise
// i - the index of the match, or insertion index if not found
func find(baggage atomlayer.BaggageContext, startat int, target atomlayer.Atom) (exists bool, overflowed bool, i int) {
for i=startat; i<len(baggage); i++ {
overflowed = overflowed || atomlayer.IsTrimMarker(baggage[i])
switch bytes.Compare(baggage[i], target) {
case -1: continue // Haven't encountered yet
case 0: exists = true; return // Found it
case 1: exists = false; return // Went past it
}
}
return
}
\ No newline at end of file
......@@ -685,3 +685,146 @@ func TestSimpleXTraceBaggage2(t *testing.T) {
assert.Nil(t, reader.Next())
assert.Nil(t, reader.Enter())
}
func TestFind(t *testing.T) {
baggage := atoms(
header(0, 0),
data(5),
header(0, 2),
data(8),
[]byte{},
header(0, 4),
data(8),
)
found, overflowed, i := find(baggage, 0, header(0, 0))
assert.True(t, found)
assert.False(t, overflowed)
assert.Equal(t, 0, i)
found, overflowed, i = find(baggage, i+1, header(0, 0))
assert.False(t, found)
assert.False(t, overflowed)
assert.Equal(t, 2, i)
found, overflowed, i = find(baggage, 0, header(0, 1))
assert.False(t, found)
assert.False(t, overflowed)
assert.Equal(t, 2, i)
found, overflowed, i = find(baggage, 0, header(0, 2))
assert.True(t, found)
assert.False(t, overflowed)
assert.Equal(t, 2, i)
found, overflowed, i = find(baggage, i+1, header(0, 2))
assert.False(t, found)
assert.True(t, overflowed)
assert.Equal(t, 5, i)
found, overflowed, i = find(baggage, 0, header(0, 3))
assert.False(t, found)
assert.True(t, overflowed)
assert.Equal(t, 5, i)
found, overflowed, i = find(baggage, 0, header(0, 4))
assert.True(t, found)
assert.True(t, overflowed)
assert.Equal(t, 5, i)
found, overflowed, i = find(baggage, i+1, header(0, 4))
assert.False(t, found)
assert.False(t, overflowed)
assert.Equal(t, 7, i)
found, overflowed, i = find(baggage, 0, header(0, 5))
assert.False(t, found)
assert.True(t, overflowed)
assert.Equal(t, 7, i)
}
func TestOpenBag(t *testing.T) {
baggage := atomlayer.BaggageContext{
header(0, 3),
data(7),
data(100),
header(1, 0),
data(6),
header(1, 3),
data(15),
header(0, 4),
data(2),
header(1,0),
data(20),
header(0,5),
data(2),
data(11),
[]byte{},
header(1, 1000000),
data(15),
header(0, 10000001),
data(5,5,5,5,5),
}
r := Open(baggage, 4)
assert.Equal(t, 0, r.level)
assert.Equal(t, 0, len(r.skipped))
assert.Equal(t, 0, len(r.currentPath))
assert.False(t, r.overflowed)
assert.Equal(t, []byte{2}, r.Next())
assert.True(t, r.EnterIndexed(0))
assert.Equal(t, []byte{20}, r.Next())
assert.Nil(t, r.Next())
r.Exit()
assert.Nil(t, r.Error())
assert.Nil(t, r.Next())
assert.Nil(t, r.Enter())
r.Exit()
assert.NotNil(t, r.Error())
}
func TestOpenBagOverflow(t *testing.T) {
baggage := atoms(
header(0, 0),
data(7),
data(100),
[]byte{},
header(0, 3),
data(6),
)
r := Open(baggage, 3)
assert.True(t, r.overflowed)
r = Open(baggage, 0)
assert.False(t, r.overflowed)
baggage = atoms(
header(0, 0),
data(7),
data(100),
header(0, 3),
[]byte{},
data(6),
)
r = Open(baggage, 3)
assert.False(t, r.overflowed)
r = Open(baggage, 0)
assert.False(t, r.overflowed)
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment