diff --git a/internal/record.go b/internal/record.go index 3bc11ef..7fe70b2 100644 --- a/internal/record.go +++ b/internal/record.go @@ -1,18 +1,56 @@ package internal import ( + "container/list" "math/big" "time" ) type Record interface { Symbol() string + Side() Side Price() *big.Float Quantity() *big.Float - Side() Side Timestamp() time.Time } -type RecordReader interface { - ReadRecord() (Record, error) +type RecordQueue struct { + l *list.List +} + +func (rq *RecordQueue) Push(r Record) { + if rq.l == nil { + rq.l = list.New() + } + + if r == nil { + return + } + + rq.l.PushBack(r) +} + +// Pop removes and returns the first element of the list as the first return value. If the list is +// empty returns falso on the 2nd return value, true otherwise. +func (rq *RecordQueue) Pop() (Record, bool) { + if rq.l == nil { + return nil, false + } + + el := rq.l.Front() + if el == nil { + return nil, false + } + + val := rq.l.Remove(el) + + return val.(Record), true +} + +func (rq *RecordQueue) Len() int { + if rq.l == nil { + return 0 + } + + return rq.l.Len() } diff --git a/internal/record_test.go b/internal/record_test.go new file mode 100644 index 0000000..2898abc --- /dev/null +++ b/internal/record_test.go @@ -0,0 +1,59 @@ +package internal + +import ( + "testing" +) + +func TestRecordQueue_Push(t *testing.T) { + var recCount int + newRecord := func() Record { + recCount++ + return testRecord{ + id: recCount, + } + } + + var rq RecordQueue + if rq.Len() != 0 { + t.Fatalf("zero value should have zero lenght") + } + + _, ok := rq.Pop() + if ok { + t.Fatalf("Pop() should return (_,false) on a zero value") + } + + rq.Push(nil) + if rq.Len() != 0 { + t.Fatalf("pushing nil should be a no-op") + } + + rq.Push(newRecord()) + if rq.Len() != 1 { + t.Fatalf("pushing 1st record should result in lenght of 1") + } + + rq.Push(newRecord()) + if rq.Len() != 2 { + t.Fatalf("pushing 2nd record should result in lenght of 2") + } + + rec, ok := rq.Pop() + if !ok { + t.Fatalf("Pop() should return (_,true) when the list is not empty") + } + + if rec, ok := rec.(testRecord); ok { + if rec.id != 1 { + t.Fatalf("Pop() should return the first record pushed but returned %d", rec.id) + } + } else { + t.Fatalf("Pop() should return the original record") + } +} + +type testRecord struct { + Record + + id int +}