Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor numeric types #61

Merged
merged 3 commits into from
May 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go: ["1.17", "1.18"]
go: ["1.18"]
steps:
- name: Set up Go ${{ matrix.go }}
uses: actions/setup-go@v3
Expand Down
42 changes: 42 additions & 0 deletions codegen/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package main

import (
_ "embed"
"os"
"text/template"
)

//go:embed numbers.tpl
var numbers string

type Type struct {
Name string
Type string
}

func main() {
t, err := template.New("numbers").Parse(numbers)
if err != nil {
panic(err)
}

dst, err := os.OpenFile("column_numbers.go", os.O_RDWR|os.O_CREATE, os.ModePerm)
if err != nil {
panic(err)
}

if err := t.Execute(dst, []Type{
{Name: "Int", Type: "int"},
{Name: "Int16", Type: "int16"},
{Name: "Int32", Type: "int32"},
{Name: "Int64", Type: "int64"},
{Name: "Uint", Type: "uint"},
{Name: "Uint16", Type: "uint16"},
{Name: "Uint32", Type: "uint32"},
{Name: "Uint64", Type: "uint64"},
{Name: "Float32", Type: "float32"},
{Name: "Float64", Type: "float64"},
}); err != nil {
panic(err)
}
}
62 changes: 62 additions & 0 deletions codegen/numbers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// This code was generated, DO NOT EDIT.
// Any changes will be lost if this file is regenerated.

package column

import (
"github.com/kelindar/bitmap"
"github.com/kelindar/column/commit"
)

{{ range . }}
// --------------------------- {{.Name}} ----------------------------

// make{{.Name}}s creates a new vector for {{.Type}}s
func make{{.Name}}s() Column {
return makeNumeric(
func(buffer *commit.Buffer, idx uint32, value {{.Type}}) {
buffer.Put{{.Name}}(idx, value)
},
func(r *commit.Reader, fill bitmap.Bitmap, data []{{.Type}}) {
for r.Next() {
offset := r.IndexAtChunk()
switch r.Type {
case commit.Put:
fill[offset>>6] |= 1 << (offset & 0x3f)
data[offset] = r.{{.Name}}()
case commit.Add:
fill[offset>>6] |= 1 << (offset & 0x3f)
data[offset] = r.AddTo{{.Name}}(data[offset])
case commit.Delete:
fill.Remove(offset)
}
}
},
)
}

// {{.Type}}Writer represents a read-write accessor for {{.Type}}
type {{.Type}}Writer struct {
numericReader[{{.Type}}]
writer *commit.Buffer
}

// Set sets the value at the current transaction cursor
func (s {{.Type}}Writer) Set(value {{.Type}}) {
s.writer.Put{{.Name}}(s.txn.cursor, value)
}

// Add atomically adds a delta to the value at the current transaction cursor
func (s {{.Type}}Writer) Add(delta {{.Type}}) {
s.writer.Add{{.Name}}(s.txn.cursor, delta)
}

// {{.Name}} returns a read-write accessor for {{.Type}} column
func (txn *Txn) {{.Name}}(columnName string) {{.Type}}Writer {
return {{.Type}}Writer{
numericReader: numericReaderFor[{{.Type}}](txn, columnName),
writer: txn.bufferFor(columnName),
}
}

{{ end }}
2 changes: 1 addition & 1 deletion collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ func (c *Collection) CreateIndex(indexName, columnName string, fn func(r Reader)
for chunk := commit.Chunk(0); int(chunk) < chunks; chunk++ {
if column.Snapshot(chunk, buffer) {
reader.Seek(buffer)
index.Apply(reader)
index.Apply(chunk, reader)
}
}

Expand Down
18 changes: 9 additions & 9 deletions collection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ import (

/*
cpu: Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz
BenchmarkCollection/insert-8 2523 469481 ns/op 24356 B/op 500 allocs/op
BenchmarkCollection/select-at-8 22194190 54.23 ns/op 0 B/op 0 allocs/op
BenchmarkCollection/scan-8 2068 568953 ns/op 122 B/op 0 allocs/op
BenchmarkCollection/count-8 571449 2057 ns/op 0 B/op 0 allocs/op
BenchmarkCollection/range-8 28660 41695 ns/op 3 B/op 0 allocs/op
BenchmarkCollection/update-at-8 5911978 202.8 ns/op 0 B/op 0 allocs/op
BenchmarkCollection/update-all-8 1280 946272 ns/op 3726 B/op 0 allocs/op
BenchmarkCollection/delete-at-8 6405852 188.9 ns/op 0 B/op 0 allocs/op
BenchmarkCollection/delete-all-8 2073188 562.6 ns/op 0 B/op 0 allocs/op
BenchmarkCollection/insert-8 2451 482358 ns/op 24429 B/op 500 allocs/op
BenchmarkCollection/select-at-8 23077500 54.52 ns/op 0 B/op 0 allocs/op
BenchmarkCollection/scan-8 2029 593730 ns/op 142 B/op 0 allocs/op
BenchmarkCollection/count-8 750106 1675 ns/op 0 B/op 0 allocs/op
BenchmarkCollection/range-8 28710 41710 ns/op 7 B/op 0 allocs/op
BenchmarkCollection/update-at-8 5986646 202.9 ns/op 0 B/op 0 allocs/op
BenchmarkCollection/update-all-8 1286 956927 ns/op 4186 B/op 0 allocs/op
BenchmarkCollection/delete-at-8 7158105 227.3 ns/op 0 B/op 0 allocs/op
BenchmarkCollection/delete-all-8 2115686 604.5 ns/op 0 B/op 0 allocs/op
*/
func BenchmarkCollection(b *testing.B) {
amount := 100000
Expand Down
36 changes: 24 additions & 12 deletions column.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Roman Atachiants and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.

//go:generate genny -pkg=column -in=column_generate.go -out=column_numbers.go gen "number=float32,float64,int,int16,int32,int64,uint,uint16,uint32,uint64"
//go:generate go run ./codegen/main.go

package column

Expand Down Expand Up @@ -34,15 +34,20 @@ func typeOf(column Column) (typ columnType) {
return
}

type segment[T any] struct {
fill bitmap.Bitmap // The fill-list
data []T // The actual values
}

// --------------------------- Contracts ----------------------------

// Column represents a column implementation
type Column interface {
Grow(idx uint32)
Apply(*commit.Reader)
Apply(commit.Chunk, *commit.Reader)
Value(idx uint32) (interface{}, bool)
Contains(idx uint32) bool
Index() *bitmap.Bitmap
Index(commit.Chunk) bitmap.Bitmap
Snapshot(chunk commit.Chunk, dst *commit.Buffer)
}

Expand All @@ -52,16 +57,16 @@ type Numeric interface {
LoadFloat64(uint32) (float64, bool)
LoadUint64(uint32) (uint64, bool)
LoadInt64(uint32) (int64, bool)
FilterFloat64(uint32, bitmap.Bitmap, func(v float64) bool)
FilterUint64(uint32, bitmap.Bitmap, func(v uint64) bool)
FilterInt64(uint32, bitmap.Bitmap, func(v int64) bool)
FilterFloat64(commit.Chunk, bitmap.Bitmap, func(v float64) bool)
FilterUint64(commit.Chunk, bitmap.Bitmap, func(v uint64) bool)
FilterInt64(commit.Chunk, bitmap.Bitmap, func(v int64) bool)
}

// Textual represents a column that stores strings.
type Textual interface {
Column
LoadString(uint32) (string, bool)
FilterString(uint32, bitmap.Bitmap, func(v string) bool)
FilterString(commit.Chunk, bitmap.Bitmap, func(v string) bool)
}

// --------------------------- Constructors ----------------------------
Expand Down Expand Up @@ -160,12 +165,19 @@ func (c *column) Grow(idx uint32) {
}

// Apply performs a series of operations on a column.
func (c *column) Apply(r *commit.Reader) {
func (c *column) Apply(chunk commit.Chunk, r *commit.Reader) {
c.lock.RLock()
defer c.lock.RUnlock()

r.Rewind()
c.Column.Apply(r)
c.Column.Apply(chunk, r)
}

// Index loads the appropriate column index for a given chunk
func (c *column) Index(chunk commit.Chunk) bitmap.Bitmap {
c.lock.RLock()
defer c.lock.RUnlock()
return c.Column.Index(chunk)
}

// Snapshot takes a snapshot of a column, skipping indexes
Expand Down Expand Up @@ -205,7 +217,7 @@ func (c *columnBool) Grow(idx uint32) {
}

// Apply applies a set of operations to the column.
func (c *columnBool) Apply(r *commit.Reader) {
func (c *columnBool) Apply(chunk commit.Chunk, r *commit.Reader) {
for r.Next() {
v := uint64(1) << (r.Offset & 0x3f)
switch r.Type {
Expand All @@ -229,8 +241,8 @@ func (c *columnBool) Contains(idx uint32) bool {
}

// Index returns the fill list for the column
func (c *columnBool) Index() *bitmap.Bitmap {
return &c.data
func (c *columnBool) Index(chunk commit.Chunk) bitmap.Bitmap {
return chunk.OfBitmap(c.data)
}

// Snapshot writes the entire column into the specified destination buffer
Expand Down
Loading