From 7e9e660e14afa19ff269ea11450bcda21feede03 Mon Sep 17 00:00:00 2001 From: Xiuming Chen Date: Mon, 11 Nov 2013 02:02:11 -0800 Subject: [PATCH 1/3] Minor changes, avoid recursive approach in readPacket() --- packets.go | 69 +++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/packets.go b/packets.go index a263a06e7..c8a3ff52c 100644 --- a/packets.go +++ b/packets.go @@ -24,54 +24,53 @@ import ( // Read packet to buffer 'data' func (mc *mysqlConn) readPacket() ([]byte, error) { - // Read packet header - data, err := mc.buf.readNext(4) - if err != nil { - errLog.Print(err.Error()) - mc.Close() - return nil, driver.ErrBadConn - } + var payload []byte + for { + // Read packet header + data, err := mc.buf.readNext(4) + if err != nil { + errLog.Print(err.Error()) + mc.Close() + return nil, driver.ErrBadConn + } - // Packet Length [24 bit] - pktLen := int(uint32(data[0]) | uint32(data[1])<<8 | uint32(data[2])<<16) + // Packet Length [24 bit] + pktLen := int(uint32(data[0]) | uint32(data[1])<<8 | uint32(data[2])<<16) - if pktLen < 1 { - errLog.Print(errMalformPkt.Error()) - mc.Close() - return nil, driver.ErrBadConn - } + if pktLen < 1 { + errLog.Print(errMalformPkt.Error()) + mc.Close() + return nil, driver.ErrBadConn + } - // Check Packet Sync [8 bit] - if data[3] != mc.sequence { - if data[3] > mc.sequence { - return nil, errPktSyncMul - } else { - return nil, errPktSync + // Check Packet Sync [8 bit] + if data[3] != mc.sequence { + if data[3] > mc.sequence { + return nil, errPktSyncMul + } else { + return nil, errPktSync + } } - } - mc.sequence++ + mc.sequence++ - // Read packet body [pktLen bytes] - if data, err = mc.buf.readNext(pktLen); err == nil { - if pktLen < maxPacketSize { - return data, nil + // Read packet body [pktLen bytes] + data, err = mc.buf.readNext(pktLen) + if err != nil { + errLog.Print(err.Error()) + mc.Close() + return nil, driver.ErrBadConn } // Make a copy since data becomes invalid with the next read buf := make([]byte, len(data)) copy(buf, data) - // More data - data, err = mc.readPacket() - if err == nil { - return append(buf, data...), nil + payload = append(payload, buf...) + + if pktLen < maxPacketSize { + return payload, nil } } - - // err case - mc.Close() - errLog.Print(err.Error()) - return nil, driver.ErrBadConn } // Write packet buffer 'data' From 745998a31577b0d27723930133c1461cb0db2cbb Mon Sep 17 00:00:00 2001 From: Xiuming Chen Date: Mon, 11 Nov 2013 04:06:45 -0800 Subject: [PATCH 2/3] Remove the buffer copying, no longer necessary --- packets.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packets.go b/packets.go index c8a3ff52c..e99146011 100644 --- a/packets.go +++ b/packets.go @@ -61,11 +61,7 @@ func (mc *mysqlConn) readPacket() ([]byte, error) { return nil, driver.ErrBadConn } - // Make a copy since data becomes invalid with the next read - buf := make([]byte, len(data)) - copy(buf, data) - - payload = append(payload, buf...) + payload = append(payload, data...) if pktLen < maxPacketSize { return payload, nil From 784729654675c3bd4e7f9b45f230185ca697c9ff Mon Sep 17 00:00:00 2001 From: Xiuming Chen Date: Wed, 13 Nov 2013 03:23:21 -0800 Subject: [PATCH 3/3] Avoid buffer copying for non-splitting packets --- packets.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packets.go b/packets.go index e99146011..b570a3e1c 100644 --- a/packets.go +++ b/packets.go @@ -61,9 +61,16 @@ func (mc *mysqlConn) readPacket() ([]byte, error) { return nil, driver.ErrBadConn } + isLastPacket := (pktLen < maxPacketSize) + + // Zero allocations for non-splitting packets + if isLastPacket && payload == nil { + return data, nil + } + payload = append(payload, data...) - if pktLen < maxPacketSize { + if isLastPacket { return payload, nil } }