• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

go-sql-driver / mysql / 15624673805

13 Jun 2025 01:56AM UTC coverage: 82.906% (-0.004%) from 82.91%
15624673805

push

github

web-flow
[1.9] fix PING on compressed connections (#1723)

Add missing mc.syncSequence()

Fix #1718

15 of 18 new or added lines in 2 files covered. (83.33%)

7 existing lines in 3 files now uncovered.

3264 of 3937 relevant lines covered (82.91%)

2489344.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.14
/buffer.go
1
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
2
//
3
// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
4
//
5
// This Source Code Form is subject to the terms of the Mozilla Public
6
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
7
// You can obtain one at http://mozilla.org/MPL/2.0/.
8

9
package mysql
10

11
import (
12
        "io"
13
)
14

15
const defaultBufSize = 4096
16
const maxCachedBufSize = 256 * 1024
17

18
// readerFunc is a function that compatible with io.Reader.
19
// We use this function type instead of io.Reader because we want to
20
// just pass mc.readWithTimeout.
21
type readerFunc func([]byte) (int, error)
22

23
// A buffer which is used for both reading and writing.
24
// This is possible since communication on each connection is synchronous.
25
// In other words, we can't write and read simultaneously on the same connection.
26
// The buffer is similar to bufio.Reader / Writer but zero-copy-ish
27
// Also highly optimized for this particular use case.
28
type buffer struct {
29
        buf       []byte // read buffer.
30
        cachedBuf []byte // buffer that will be reused. len(cachedBuf) <= maxCachedBufSize.
31
}
32

33
// newBuffer allocates and returns a new buffer.
34
func newBuffer() buffer {
18,710✔
35
        return buffer{
18,710✔
36
                cachedBuf: make([]byte, defaultBufSize),
18,710✔
37
        }
18,710✔
38
}
18,710✔
39

40
// busy returns true if the read buffer is not empty.
41
func (b *buffer) busy() bool {
171,744✔
42
        return len(b.buf) > 0
171,744✔
43
}
171,744✔
44

45
// len returns how many bytes in the read buffer.
46
func (b *buffer) len() int {
33,928,237✔
47
        return len(b.buf)
33,928,237✔
48
}
33,928,237✔
49

50
// fill reads into the read buffer until at least _need_ bytes are in it.
51
func (b *buffer) fill(need int, r readerFunc) error {
103,665✔
52
        // we'll move the contents of the current buffer to dest before filling it.
103,665✔
53
        dest := b.cachedBuf
103,665✔
54

103,665✔
55
        // grow buffer if necessary to fit the whole packet.
103,665✔
56
        if need > len(dest) {
104,113✔
57
                // Round up to the next multiple of the default size
448✔
58
                dest = make([]byte, ((need/defaultBufSize)+1)*defaultBufSize)
448✔
59

448✔
60
                // if the allocated buffer is not too large, move it to backing storage
448✔
61
                // to prevent extra allocations on applications that perform large reads
448✔
62
                if len(dest) <= maxCachedBufSize {
512✔
63
                        b.cachedBuf = dest
64✔
64
                }
64✔
65
        }
66

67
        // move the existing data to the start of the buffer.
68
        n := len(b.buf)
103,665✔
69
        copy(dest[:n], b.buf)
103,665✔
70

103,665✔
71
        for {
208,280✔
72
                nn, err := r(dest[n:])
104,615✔
73
                n += nn
104,615✔
74

104,615✔
75
                if err == nil && n < need {
105,565✔
76
                        continue
950✔
77
                }
78

79
                b.buf = dest[:n]
103,665✔
80

103,665✔
81
                if err == io.EOF {
103,665✔
82
                        if n < need {
×
83
                                err = io.ErrUnexpectedEOF
×
84
                        } else {
×
85
                                err = nil
×
86
                        }
×
87
                }
88
                return err
103,665✔
89
        }
90
}
91

92
// returns next N bytes from buffer.
93
// The returned slice is only guaranteed to be valid until the next read
94
func (b *buffer) readNext(need int) []byte {
33,925,982✔
95
        data := b.buf[:need:need]
33,925,982✔
96
        b.buf = b.buf[need:]
33,925,982✔
97
        return data
33,925,982✔
98
}
33,925,982✔
99

100
// takeBuffer returns a buffer with the requested size.
101
// If possible, a slice from the existing buffer is returned.
102
// Otherwise a bigger buffer is made.
103
// Only one buffer (total) can be used at a time.
104
func (b *buffer) takeBuffer(length int) ([]byte, error) {
69,177✔
105
        if b.busy() {
69,177✔
106
                return nil, ErrBusyBuffer
×
107
        }
×
108

109
        // test (cheap) general case first
110
        if length <= len(b.cachedBuf) {
138,098✔
111
                return b.cachedBuf[:length], nil
68,921✔
112
        }
68,921✔
113

114
        if length < maxCachedBufSize {
384✔
115
                b.cachedBuf = make([]byte, length)
128✔
116
                return b.cachedBuf, nil
128✔
117
        }
128✔
118

119
        // buffer is larger than we want to store.
120
        return make([]byte, length), nil
128✔
121
}
122

123
// takeSmallBuffer is shortcut which can be used if length is
124
// known to be smaller than defaultBufSize.
125
// Only one buffer (total) can be used at a time.
126
func (b *buffer) takeSmallBuffer(length int) ([]byte, error) {
20,827✔
127
        if b.busy() {
20,827✔
UNCOV
128
                return nil, ErrBusyBuffer
×
UNCOV
129
        }
×
130
        return b.cachedBuf[:length], nil
20,827✔
131
}
132

133
// takeCompleteBuffer returns the complete existing buffer.
134
// This can be used if the necessary buffer size is unknown.
135
// cap and len of the returned buffer will be equal.
136
// Only one buffer (total) can be used at a time.
137
func (b *buffer) takeCompleteBuffer() ([]byte, error) {
11,768✔
138
        if b.busy() {
11,768✔
139
                return nil, ErrBusyBuffer
×
140
        }
×
141
        return b.cachedBuf, nil
11,768✔
142
}
143

144
// store stores buf, an updated buffer, if its suitable to do so.
145
func (b *buffer) store(buf []byte) {
96✔
146
        if cap(buf) <= maxCachedBufSize && cap(buf) > cap(b.cachedBuf) {
192✔
147
                b.cachedBuf = buf[:cap(buf)]
96✔
148
        }
96✔
149
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc