Skip to content

Commit

Permalink
Merge pull request #12 from go-faster/feat/bool-speedup
Browse files Browse the repository at this point in the history
feat(proto): speedup for ColBool
  • Loading branch information
ernado authored Jan 2, 2022
2 parents 35e1900 + 0d5b27a commit 8706ec0
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 37 deletions.
37 changes: 0 additions & 37 deletions proto/col_bool.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package proto

import "github.com/go-faster/errors"

// ColBool is Bool column.
type ColBool []bool

Expand All @@ -26,38 +24,3 @@ func (c ColBool) Rows() int {
func (c *ColBool) Reset() {
*c = (*c)[:0]
}

// EncodeColumn encodes Bool rows to *Buffer.
func (c ColBool) EncodeColumn(b *Buffer) {
start := len(b.Buf)
b.Buf = append(b.Buf, make([]byte, len(c))...)
for i := range c {
if c[i] {
b.Buf[i+start] = boolTrue
} else {
b.Buf[i+start] = boolFalse
}
}
}

// DecodeColumn decodes Bool rows from *Reader.
func (c *ColBool) DecodeColumn(r *Reader, rows int) error {
data, err := r.ReadRaw(rows)
if err != nil {
return errors.Wrap(err, "read")
}
v := *c
v = append(v, make([]bool, rows)...)
for i := range data {
switch data[i] {
case boolTrue:
v[i] = true
case boolFalse:
v[i] = false
default:
return errors.Errorf("[%d]: bad value %d for Bool", i, data[i])
}
}
*c = v
return nil
}
40 changes: 40 additions & 0 deletions proto/col_bool_safe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//go:build !amd64 || nounsafe

package proto

import "github.com/go-faster/errors"

// EncodeColumn encodes Bool rows to *Buffer.
func (c ColBool) EncodeColumn(b *Buffer) {
start := len(b.Buf)
b.Buf = append(b.Buf, make([]byte, len(c))...)
for i := range c {
if c[i] {
b.Buf[i+start] = boolTrue
} else {
b.Buf[i+start] = boolFalse
}
}
}

// DecodeColumn decodes Bool rows from *Reader.
func (c *ColBool) DecodeColumn(r *Reader, rows int) error {
data, err := r.ReadRaw(rows)
if err != nil {
return errors.Wrap(err, "read")
}
v := *c
v = append(v, make([]bool, rows)...)
for i := range data {
switch data[i] {
case boolTrue:
v[i] = true
case boolFalse:
v[i] = false
default:
return errors.Errorf("[%d]: bad value %d for Bool", i, data[i])
}
}
*c = v
return nil
}
36 changes: 36 additions & 0 deletions proto/col_bool_unsafe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//go:build amd64 && !nounsafe

package proto

import (
"unsafe"

"github.com/go-faster/errors"
)

// EncodeColumn encodes Bool rows to *Buffer.
func (c ColBool) EncodeColumn(b *Buffer) {
if len(c) == 0 {
return
}
offset := len(b.Buf)
b.Buf = append(b.Buf, make([]byte, len(c))...)
s := *(*slice)(unsafe.Pointer(&c)) // #nosec G103
src := *(*[]byte)(unsafe.Pointer(&s)) // #nosec G103
dst := b.Buf[offset:]
copy(dst, src)
}

// DecodeColumn decodes Bool rows from *Reader.
func (c *ColBool) DecodeColumn(r *Reader, rows int) error {
if rows == 0 {
return nil
}
*c = append(*c, make([]bool, rows)...)
s := *(*slice)(unsafe.Pointer(c)) // #nosec G103
dst := *(*[]byte)(unsafe.Pointer(&s)) // #nosec G103
if err := r.ReadFull(dst); err != nil {
return errors.Wrap(err, "read full")
}
return nil
}

0 comments on commit 8706ec0

Please sign in to comment.