Commit 005f1cab authored by Jonathan Mace's avatar Jonathan Mace

Add merging of unprocessed atoms and some tests

parent b0b87424
......@@ -8,28 +8,31 @@ import (
)
type Writer struct {
finalized []atomlayer.Atom
atoms []atomlayer.Atom
prev atomlayer.Atom // Previous header
basePath []atomlayer.Atom
currentPath []atomlayer.Atom
level int
err error
overflowed bool
}
var emptyAtom = []byte{}
func NewWriter() *Writer {
var w Writer
w.level = -1
w.prev = emptyAtom
return &w
return write()
}
// Writes to a specific bag
func WriteBag(bagIndex uint64) *Writer {
return write(MakeIndexedHeader(0, bagIndex))
}
// Returns a writer that writes data starting at the provided path
func write(basePath ...atomlayer.Atom) *Writer {
var w Writer
w.atoms = append(w.atoms, MakeIndexedHeader(0, bagIndex))
w.prev = emptyAtom
w.level = len(basePath) - 1
w.basePath = basePath
w.prev = nil
return &w
}
......@@ -50,7 +53,7 @@ func (w *Writer) enter(header atomlayer.Atom) {
// Always write the header, even if it's in an erroneous order
w.atoms = append(w.atoms, header)
w.prev = emptyAtom
w.prev = nil
w.currentPath = append(w.currentPath, header)
w.level++
}
......@@ -67,7 +70,6 @@ func (w *Writer) Exit() {
w.atoms = w.atoms[:len(w.atoms)-1]
}
}
}
func (w *Writer) Write(data []byte) {
......@@ -86,12 +88,17 @@ func (w *Writer) WriteSorted(datas ...[]byte) {
func (w *Writer) MarkOverflow() {
if !w.overflowed {
w.overflowed = true
w.atoms = append(w.atoms, emptyAtom)
w.atoms = append(w.atoms, atomlayer.TrimMarker)
}
}
func (w *Writer) AddUnprocessedAtoms(atoms []atomlayer.Atom) {
w.finalized = atomlayer.Merge(w.finalized, atoms)
}
func (w *Writer) Atoms() ([]atomlayer.Atom, error) {
return w.atoms, w.err
atoms := make([]atomlayer.Atom, 0, len(w.basePath) + len(w.atoms) + len(w.finalized))
return append(append(atoms, w.basePath...), atomlayer.Merge(w.atoms, w.finalized)...), w.err
}
func (w *Writer) seterror(err error) error {
......
......@@ -180,4 +180,201 @@ func TestWriteOverflow(t *testing.T) {
atomlayer.TrimMarker,
)
assert.Equal(t, expect, as)
}
func TestWriteNothingSorted(t *testing.T) {
w := NewWriter()
w.Enter(2)
w.WriteSorted()
w.Exit()
as, err := w.Atoms()
assert.Nil(t, err)
assert.Empty(t, as)
}
func TestWriteSorted1(t *testing.T) {
w := NewWriter()
w.Enter(2)
w.WriteSorted([]byte{1}, []byte{2})
w.Exit()
as, err := w.Atoms()
assert.Nil(t, err)
expect := atoms(
header(0,2),
data(1),
data(2),
)
assert.Equal(t, expect, as)
}
func TestWriteSorted2(t *testing.T) {
w := NewWriter()
w.Enter(2)
w.WriteSorted([]byte{2}, []byte{1})
w.Exit()
as, err := w.Atoms()
assert.Nil(t, err)
expect := atoms(
header(0,2),
data(1),
data(2),
)
assert.Equal(t, expect, as)
}
func TestWriteSorted3(t *testing.T) {
w := NewWriter()
w.Enter(2)
w.WriteSorted([]byte{100}, []byte{}, []byte{5, 200})
w.Exit()
as, err := w.Atoms()
assert.Nil(t, err)
expect := atoms(
header(0,2),
data(),
data(5, 200),
data(100),
)
assert.Equal(t, expect, as)
}
func TestWriteUnsorted(t *testing.T) {
w := NewWriter()
w.Enter(2)
w.Write([]byte{2})
w.Write([]byte{1})
w.WriteSorted([]byte{4}, []byte{3})
w.Exit()
as, err := w.Atoms()
assert.Nil(t, err)
expect := atoms(
header(0,2),
data(2),
data(1),
data(3),
data(4),
)
assert.Equal(t, expect, as)
}
func TestUnprocessedAtoms(t *testing.T) {
w := NewWriter()
w.Enter(2)
w.Enter(10)
w.Enter(4)
w.Enter(5)
w.Write([]byte{2})
w.Write([]byte{1})
w.Exit()
w.Exit()
w.Exit()
w.Exit()
as, err := w.Atoms()
assert.Nil(t, err)
expect := atoms(
header(0,2),
header(1,10),
header(2,4),
header(3,5),
data(2),
data(1),
)
assert.Equal(t, expect, as)
w.AddUnprocessedAtoms(atoms(
header(0, 2),
header(1, 10),
header(2, 7),
header(3, 5),
data(2),
))
as, err = w.Atoms()
assert.Nil(t, err)
expect = atoms(
header(0,2),
header(1,10),
header(2,4),
header(3,5),
data(2),
data(1),
header(2,7),
header(3,5),
data(2),
)
assert.Equal(t, expect, as)
}
func TestUnprocessedAtomsInBag(t *testing.T) {
w := WriteBag(2)
w.Enter(10)
w.Enter(4)
w.Enter(5)
w.Write([]byte{2})
w.Write([]byte{1})
w.Exit()
w.Exit()
w.Exit()
as, err := w.Atoms()
assert.Nil(t, err)
expect := atoms(
header(0,2),
header(1,10),
header(2,4),
header(3,5),
data(2),
data(1),
)
assert.Equal(t, expect, as)
w.AddUnprocessedAtoms(atoms(
header(1, 10),
header(2, 7),
header(3, 5),
data(2),
))
as, err = w.Atoms()
assert.Nil(t, err)
expect = atoms(
header(0,2),
header(1,10),
header(2,4),
header(3,5),
data(2),
data(1),
header(2,7),
header(3,5),
data(2),
)
assert.Equal(t, expect, as)
}
\ No newline at end of file
......@@ -168,7 +168,7 @@ func TestUpdateXTraceParents(t *testing.T) {
}
func TestUpdateXTrace(t *testing.T) {
func TestXTraceUnprocessed(t *testing.T) {
var baggage tracingplane.BaggageContext
baggage.Atoms = atoms(
header(0, 3),
......@@ -176,13 +176,50 @@ func TestUpdateXTrace(t *testing.T) {
header(0, 5),
header(1, 0),
data(143, 189, 154, 1, 65, 170, 219, 47),
header(1, 1),
data(242, 64, 253, 113, 224, 239, 96, 55),
data(2, 62, 33, 56, 120, 22, 229, 128),
data(125, 152, 88, 29, 177, 134, 140, 248),
header(1, 1),
data(2, 62, 33, 56, 120, 22, 229, 128),
data(125, 152, 88, 29, 177, 134, 140, 248),
data(242, 64, 253, 113, 224, 239, 96, 55),
header(1, 3),
data(3),
header(0, 10),
data(100),
)
xtrace := XTraceMetadata{}
err := baggage.ReadBag(5, &xtrace)
assert.Nil(t, err)
expectUnprocessed := atoms(
header(1, 3),
data(3),
data(3),
)
assert.Equal(t, expectUnprocessed, xtrace.GetUnprocessedAtoms())
baggage.Drop(5)
expectBaggage := atoms(
header(0,3),
data(5),
header(0,10),
data(100),
)
assert.Equal(t, expectBaggage, baggage.Atoms)
baggage.Set(7, &xtrace)
expect := atoms(
header(0, 3),
data(5),
header(0, 7),
header(1, 0),
data(143, 189, 154, 1, 65, 170, 219, 47),
header(1, 1),
data(2, 62, 33, 56, 120, 22, 229, 128),
data(125, 152, 88, 29, 177, 134, 140, 248),
data(242, 64, 253, 113, 224, 239, 96, 55),
header(1, 3),
data(3),
header(0, 10),
data(100),
)
assert.Equal(t, expect, baggage.Atoms)
}
\ No newline at end of file
......@@ -6,7 +6,8 @@ import (
"github.com/tracingplane/tracingplane-go/atomlayer"
)
// BDL methods for reading and writing from and to BaggageContexts
// This file contains extra methods for the BaggageContext structs that are used by BDL-generated code to read and
// write atoms.
// Read the specified bag index into the provided bag object
func (baggage *BaggageContext) ReadBag(bagIndex uint64, bag bdl.Bag) error {
......@@ -29,7 +30,7 @@ func (baggage *BaggageContext) Set(bagIndex uint64, bag bdl.Bag) error {
// Write the new bag
writer := baggageprotocol.WriteBag(bagIndex)
bag.Write(writer)
// TODO: merge back in unprocessed atoms
writer.AddUnprocessedAtoms(bag.GetUnprocessedAtoms())
newAtoms, err := writer.Atoms()
// Merge it back in
......
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