Introduce msg.PackBuffer() - it's like msg.Pack() but can reuse a byte buffer

msg.Pack() always allocates a byte slice. This is good for simplicity,
but in a serious application it's preferable to reuse byte slices to
reduce the GC overhead. This patch introduces a new public method:
PackBuffer(). It's exaclty like Pack() but is able to reuse a
given byte slice. It will still allocate a new slice if the given one
is too small.
This commit is contained in:
Marek Majkowski 2014-01-10 07:46:24 -08:00
parent a627d88e3f
commit d18d87b37d
1 changed files with 10 additions and 1 deletions

11
msg.go
View File

@ -1290,6 +1290,11 @@ func (h *MsgHdr) String() string {
// Pack packs a Msg: it is converted to to wire format.
// If the dns.Compress is true the message will be in compressed wire format.
func (dns *Msg) Pack() (msg []byte, err error) {
return dns.PackBuffer(nil)
}
// PackWithBuffer packs a Msg, reusing a given buffer if possible to reduce memory allocations
func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) {
var dh Header
var compression map[string]int
if dns.Compress {
@ -1335,7 +1340,11 @@ func (dns *Msg) Pack() (msg []byte, err error) {
dh.Nscount = uint16(len(ns))
dh.Arcount = uint16(len(extra))
msg = make([]byte, dns.packLen()+1)
msg = buf
if packLen := dns.packLen(); len(msg) <= packLen {
msg = make([]byte, packLen+1)
}
// Pack it in: header and then the pieces.
off := 0
off, err = packStructCompress(&dh, msg, off, compression, dns.Compress)