Commit 1aaf1a02 authored by Geoff Simmons's avatar Geoff Simmons

Refactor log record parsing to work with no allocations.

parent 95054cbe
...@@ -44,24 +44,73 @@ type existence struct{} ...@@ -44,24 +44,73 @@ type existence struct{}
var ( var (
exister = struct{}{} exister = struct{}{}
spaceByte = []byte(" ") sessBytes = []byte("ess")
str2type = map[string]TxType{ reqBytes = []byte("eq")
"sess": Sess, bereqBytes = []byte("ereq")
"req": Req, http1Bytes = []byte("TTP/1")
"bereq": BeReq, rxreqBytes = []byte("xreq")
} esiBytes = []byte("si")
str2reason = map[string]Reason{ restartBytes = []byte("estart")
"HTTP/1": HTTP1, passBytes = []byte("ass")
"rxreq": RxReq, fetchBytes = []byte("etch")
"esi": ESI, bgFetchBytes = []byte("gfetch")
"restart": Restart, pipeBytes = []byte("ipe")
"pass": Pass,
"fetch": Fetch,
"bgfetch": BgFetch,
"pipe": Pipe,
}
) )
func bytes2Type(b []byte) (TxType, bool) {
switch b[0] {
case byte('s'):
if bytes.Equal(b[1:], sessBytes) {
return Sess, true
}
case byte('r'):
if bytes.Equal(b[1:], reqBytes) {
return Req, true
}
case byte('b'):
if bytes.Equal(b[1:], bereqBytes) {
return BeReq, true
}
}
return TxUnknown, false
}
func bytes2Reason(b []byte) (Reason, bool) {
switch b[0] {
case byte('H'):
if bytes.Equal(b[1:], http1Bytes) {
return HTTP1, true
}
case byte('r'):
if bytes.Equal(b[1:], rxreqBytes) {
return RxReq, true
}
if bytes.Equal(b[1:], restartBytes) {
return Restart, true
}
case byte('e'):
if bytes.Equal(b[1:], esiBytes) {
return ESI, true
}
case byte('p'):
if bytes.Equal(b[1:], passBytes) {
return Pass, true
}
if bytes.Equal(b[1:], pipeBytes) {
return Pipe, true
}
case byte('f'):
if bytes.Equal(b[1:], fetchBytes) {
return Fetch, true
}
case byte('b'):
if bytes.Equal(b[1:], bgFetchBytes) {
return BgFetch, true
}
}
return ReasonUnknown, false
}
type grpNode struct { type grpNode struct {
children []uint32 children []uint32
vxid uint32 vxid uint32
...@@ -137,33 +186,43 @@ func (c *Cursor) NewQuery(grp Grouping, query string) (*Query, error) { ...@@ -137,33 +186,43 @@ func (c *Cursor) NewQuery(grp Grouping, query string) (*Query, error) {
// Parses a Begin or Link record for the purposes of grouping // Parses a Begin or Link record for the purposes of grouping
func (q *Query) parseRec(payload Payload) (TxType, uint32, Reason, error) { func (q *Query) parseRec(payload Payload) (TxType, uint32, Reason, error) {
flds := bytes.Split(payload, spaceByte) min, max, ok := fieldNDelims(payload, 0)
if len(flds) != 3 { if !ok {
// XXX // XXX error handling
return TxUnknown, 0, ReasonUnknown, nil return TxUnknown, 0, ReasonUnknown, nil
} }
txtype, exists := str2type[string(flds[0])] txtype, ok := bytes2Type(payload[min:max])
if !exists { if !ok {
// XXX // XXX error handling
return TxUnknown, 0, ReasonUnknown, nil return TxUnknown, 0, ReasonUnknown, nil
} }
vxid, ok := atoUint32(flds[1]) min, max, ok = fieldNDelims(payload, 1)
if !ok { if !ok {
// XXX // XXX error handling
return txtype, 0, ReasonUnknown, nil return txtype, 0, ReasonUnknown, nil
} }
reason, exists := str2reason[string(flds[2])] vxid, ok := atoUint32(payload[min:max])
if !exists { if !ok {
// XXX // XXX error handling
return txtype, 0, ReasonUnknown, nil
}
min, max, ok = fieldNDelims(payload, 2)
if !ok {
// XXX error handling
return txtype, vxid, ReasonUnknown, nil return txtype, vxid, ReasonUnknown, nil
} }
reason, ok := bytes2Reason(payload[min:max])
if !ok {
// XXX error handling
return TxUnknown, vxid, ReasonUnknown, nil
}
return txtype, vxid, reason, nil return txtype, vxid, reason, nil
} }
func (q *Query) link(pvxid uint32, vxid uint32) { func (q *Query) link(pvxid uint32, vxid uint32) {
child, cexists := q.grpNodes[vxid] child, cexists := q.grpNodes[vxid]
if !cexists { if !cexists {
child = grpNode{ vxid: vxid } child = grpNode{vxid: vxid}
} }
child.pvxid = pvxid child.pvxid = pvxid
q.grpNodes[vxid] = child q.grpNodes[vxid] = child
...@@ -172,7 +231,7 @@ func (q *Query) link(pvxid uint32, vxid uint32) { ...@@ -172,7 +231,7 @@ func (q *Query) link(pvxid uint32, vxid uint32) {
} }
parent, pexists := q.grpNodes[pvxid] parent, pexists := q.grpNodes[pvxid]
if !pexists { if !pexists {
parent = grpNode{ vxid: pvxid } parent = grpNode{vxid: pvxid}
} }
found := false found := false
for _, xid := range parent.children { for _, xid := range parent.children {
......
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