Skip to content

Commit 77ce7d9

Browse files
committed
reset buffer if its average use size smaller than quater of capacity
closes #95
1 parent a535b8e commit 77ce7d9

File tree

3 files changed

+51
-23
lines changed

3 files changed

+51
-23
lines changed

connection.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ func (conn *Connection) writeAuthRequest(w *bufio.Writer, scramble []byte) (err
442442
if err != nil {
443443
return errors.New("auth: pack error " + err.Error())
444444
}
445-
if err := write(w, packet); err != nil {
445+
if err := write(w, packet.b); err != nil {
446446
return errors.New("auth: write error " + err.Error())
447447
}
448448
if err = w.Flush(); err != nil {
@@ -521,7 +521,7 @@ func (conn *Connection) closeConnection(neterr error, forever bool) (err error)
521521
conn.c = nil
522522
}
523523
for i := range conn.shard {
524-
conn.shard[i].buf = conn.shard[i].buf[:0]
524+
conn.shard[i].buf.Reset()
525525
requests := &conn.shard[i].requests
526526
for pos := range requests {
527527
fut := requests[pos].first
@@ -621,14 +621,14 @@ func (conn *Connection) writer(w *bufio.Writer, c net.Conn) {
621621
}
622622
packet, shard.buf = shard.buf, packet
623623
shard.bufmut.Unlock()
624-
if len(packet) == 0 {
624+
if packet.Len() == 0 {
625625
continue
626626
}
627-
if err := write(w, packet); err != nil {
627+
if err := write(w, packet.b); err != nil {
628628
conn.reconnect(err, c)
629629
return
630630
}
631-
packet = packet[0:0]
631+
packet.Reset()
632632
}
633633
}
634634

@@ -717,14 +717,14 @@ func (conn *Connection) putFuture(fut *Future, body func(*msgpack.Encoder) error
717717
return
718718
default:
719719
}
720-
firstWritten := len(shard.buf) == 0
721-
if cap(shard.buf) == 0 {
722-
shard.buf = make(smallWBuf, 0, 128)
720+
firstWritten := shard.buf.Len() == 0
721+
if shard.buf.Cap() == 0 {
722+
shard.buf.b = make([]byte, 0, 128)
723723
shard.enc = msgpack.NewEncoder(&shard.buf)
724724
}
725-
blen := len(shard.buf)
725+
blen := shard.buf.Len()
726726
if err := fut.pack(&shard.buf, shard.enc, body); err != nil {
727-
shard.buf = shard.buf[:blen]
727+
shard.buf.Trunc(blen)
728728
shard.bufmut.Unlock()
729729
if f := conn.fetchFuture(fut.requestId); f == fut {
730730
fut.markReady(conn)

request.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -352,25 +352,25 @@ func (conn *Connection) EvalAsync(expr string, args interface{}) *Future {
352352

353353
func (fut *Future) pack(h *smallWBuf, enc *msgpack.Encoder, body func(*msgpack.Encoder) error) (err error) {
354354
rid := fut.requestId
355-
hl := len(*h)
356-
*h = append(*h, smallWBuf{
355+
hl := h.Len()
356+
h.Write([]byte{
357357
0xce, 0, 0, 0, 0, // length
358358
0x82, // 2 element map
359359
KeyCode, byte(fut.requestCode), // request code
360360
KeySync, 0xce,
361361
byte(rid >> 24), byte(rid >> 16),
362362
byte(rid >> 8), byte(rid),
363-
}...)
363+
})
364364

365365
if err = body(enc); err != nil {
366366
return
367367
}
368368

369-
l := uint32(len(*h) - 5 - hl)
370-
(*h)[hl+1] = byte(l >> 24)
371-
(*h)[hl+2] = byte(l >> 16)
372-
(*h)[hl+3] = byte(l >> 8)
373-
(*h)[hl+4] = byte(l)
369+
l := uint32(h.Len() - 5 - hl)
370+
h.b[hl+1] = byte(l >> 24)
371+
h.b[hl+2] = byte(l >> 16)
372+
h.b[hl+3] = byte(l >> 8)
373+
h.b[hl+4] = byte(l)
374374

375375
return
376376
}

smallbuf.go

+33-5
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,47 @@ func (s *smallBuf) Bytes() []byte {
5151
return nil
5252
}
5353

54-
type smallWBuf []byte
54+
type smallWBuf struct {
55+
b []byte
56+
sum uint
57+
n uint
58+
}
5559

5660
func (s *smallWBuf) Write(b []byte) (int, error) {
57-
*s = append(*s, b...)
58-
return len(b), nil
61+
s.b = append(s.b, b...)
62+
return len(s.b), nil
5963
}
6064

6165
func (s *smallWBuf) WriteByte(b byte) error {
62-
*s = append(*s, b)
66+
s.b = append(s.b, b)
6367
return nil
6468
}
6569

6670
func (s *smallWBuf) WriteString(ss string) (int, error) {
67-
*s = append(*s, ss...)
71+
s.b = append(s.b, ss...)
6872
return len(ss), nil
6973
}
74+
75+
func (s smallWBuf) Len() int {
76+
return len(s.b)
77+
}
78+
79+
func (s smallWBuf) Cap() int {
80+
return cap(s.b)
81+
}
82+
83+
func (s *smallWBuf) Trunc(n int) {
84+
s.b = s.b[:n]
85+
}
86+
87+
func (s *smallWBuf) Reset() {
88+
s.sum = uint(uint64(s.sum) * 15 / 16) + uint(len(s.b))
89+
if s.n < 16 {
90+
s.n++
91+
}
92+
if cap(s.b) > 1024 && s.sum / s.n < uint(cap(s.b))/4 {
93+
s.b = make([]byte, 0, s.sum/s.n)
94+
} else {
95+
s.b = s.b[:0]
96+
}
97+
}

0 commit comments

Comments
 (0)