Skip to content

Commit

Permalink
Use math/bits OnesCount to preallocate slices (#995)
Browse files Browse the repository at this point in the history
* Use math/bits OnesCount to preallocate slices

* trailing zeroes to scan flags

* avoid epilogue loop

---------

Co-authored-by: lance6716 <[email protected]>
  • Loading branch information
serprex and lance6716 authored Feb 22, 2025
1 parent c729fe3 commit 08630ce
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 18 deletions.
19 changes: 7 additions & 12 deletions client/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"crypto/tls"
"fmt"
"math/bits"
"net"
"runtime"
"runtime/debug"
Expand Down Expand Up @@ -557,13 +558,10 @@ func (c *Conn) execSend(query string) error {
// separated by "|". Examples of capability names are CLIENT_DEPRECATE_EOF and CLIENT_PROTOCOL_41.
// These are defined as constants in the mysql package.
func (c *Conn) CapabilityString() string {
var caps []string
capability := c.capability
for i := 0; capability != 0; i++ {
field := uint32(1 << i)
if capability&field == 0 {
continue
}
caps := make([]string, 0, bits.OnesCount32(capability))
for capability != 0 {
field := uint32(1 << bits.TrailingZeros32(capability))
capability ^= field

switch field {
Expand Down Expand Up @@ -642,13 +640,10 @@ func (c *Conn) CapabilityString() string {
// StatusString returns a "|" separated list of status fields. Example status values are SERVER_QUERY_WAS_SLOW and SERVER_STATUS_AUTOCOMMIT.
// These are defined as constants in the mysql package.
func (c *Conn) StatusString() string {
var stats []string
status := c.status
for i := 0; status != 0; i++ {
field := uint16(1 << i)
if status&field == 0 {
continue
}
stats := make([]string, 0, bits.OnesCount16(status))
for status != 0 {
field := uint16(1 << bits.TrailingZeros16(status))
status ^= field

switch field {
Expand Down
15 changes: 9 additions & 6 deletions replication/row_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/hex"
"fmt"
"io"
"math/bits"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -754,7 +755,7 @@ func (e *TableMapEvent) VisibilityMap() map[int]bool {
if len(e.VisibilityBitmap) == 0 {
return nil
}
ret := make(map[int]bool)
ret := make(map[int]bool, len(e.VisibilityBitmap)*8)
i := 0
for _, field := range e.VisibilityBitmap {
for c := 0x80; c != 0; c >>= 1 {
Expand Down Expand Up @@ -1146,15 +1147,17 @@ func (e *RowsEvent) decodeImage(data []byte, bitmap []byte, rowImageType EnumRow
}

row := make([]interface{}, e.ColumnCount)
skips := make([]int, 0)

// refer: https://github.com/alibaba/canal/blob/c3e38e50e269adafdd38a48c63a1740cde304c67/dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/event/RowsLogBuffer.java#L63
count := 0
for i := 0; i < int(e.ColumnCount); i++ {
if isBitSet(bitmap, i) {
count++
}
col := 0
for ; col+8 <= int(e.ColumnCount); col += 8 {
count += bits.OnesCount8(bitmap[col>>3])
}
if col < int(e.ColumnCount) {
count += bits.OnesCount8(bitmap[col>>3] & byte((1<<(int(e.ColumnCount)-col))-1))
}
skips := make([]int, 0, int(e.ColumnCount)-count)
count = bitmapByteSize(count)

nullBitmap := data[pos : pos+count]
Expand Down

0 comments on commit 08630ce

Please sign in to comment.