Implement async document processing in queries

This commit is contained in:
Tobie Morgan Hitchcock 2019-06-14 18:33:41 +01:00
parent bcb1d3174c
commit db1864224b
12 changed files with 565 additions and 393 deletions

View file

@ -60,6 +60,7 @@ type iterator struct {
limit int limit int
start int start int
versn int64 versn int64
async bool
} }
type workable struct { type workable struct {
@ -135,6 +136,7 @@ func (i *iterator) Close() {
i.limit = -1 i.limit = -1
i.start = -1 i.start = -1
i.versn = 0 i.versn = 0
i.async = false
iteratorPool.Put(i) iteratorPool.Put(i)
@ -161,18 +163,24 @@ func (i *iterator) setupState(ctx context.Context) {
i.split = stm.Split i.split = stm.Split
i.group = stm.Group i.group = stm.Group
i.order = stm.Order i.order = stm.Order
i.async = stm.Parallel
case *sql.CreateStatement: case *sql.CreateStatement:
i.what = stm.What i.what = stm.What
i.async = stm.Parallel
case *sql.UpdateStatement: case *sql.UpdateStatement:
i.what = stm.What i.what = stm.What
i.cond = stm.Cond i.cond = stm.Cond
i.async = stm.Parallel
case *sql.DeleteStatement: case *sql.DeleteStatement:
i.what = stm.What i.what = stm.What
i.cond = stm.Cond i.cond = stm.Cond
i.async = stm.Parallel
case *sql.InsertStatement: case *sql.InsertStatement:
i.what = sql.Exprs{stm.Data} i.what = sql.Exprs{stm.Data}
i.async = stm.Parallel
case *sql.UpsertStatement: case *sql.UpsertStatement:
i.what = sql.Exprs{stm.Data} i.what = sql.Exprs{stm.Data}
i.async = stm.Parallel
} }
if stm, ok := i.stm.(*sql.SelectStatement); ok { if stm, ok := i.stm.(*sql.SelectStatement); ok {
@ -233,7 +241,13 @@ func (i *iterator) setupWorkers(ctx context.Context) {
} }
}(i.vals) }(i.vals)
for w := 1; w <= workerCount; w++ { workers := 1
if i.async {
workers = workerCount
}
for w := 1; w <= workers; w++ {
go func(jobs <-chan *workable, vals chan<- *doneable) { go func(jobs <-chan *workable, vals chan<- *doneable) {
for j := range jobs { for j := range jobs {
res, err := newDocument(i, j.key, j.val, j.doc).query(ctx, i.stm) res, err := newDocument(i, j.key, j.val, j.doc).query(ctx, i.stm)

View file

@ -16,6 +16,7 @@ package db
import ( import (
"errors" "errors"
"runtime"
) )
type method int8 type method int8
@ -85,7 +86,7 @@ const (
var ( var (
// workerCount specifies how many workers should be used // workerCount specifies how many workers should be used
// to process each query statement concurrently. // to process each query statement concurrently.
workerCount = 1 workerCount = runtime.NumCPU()
// maxRecursiveQueries specifies how many queries will be // maxRecursiveQueries specifies how many queries will be
// processed recursively before the query is cancelled. // processed recursively before the query is cancelled.

View file

@ -160,70 +160,77 @@ type IfelseStatement struct {
// SelectStatement represents a SQL SELECT statement. // SelectStatement represents a SQL SELECT statement.
type SelectStatement struct { type SelectStatement struct {
RW bool RW bool
Expr Fields Expr Fields
What Exprs What Exprs
Cond Expr Cond Expr
Split Idents Split Idents
Group Groups Group Groups
Order Orders Order Orders
Limit Expr Limit Expr
Start Expr Start Expr
Fetch Fetchs Fetch Fetchs
Version Expr Version Expr
Timeout time.Duration Timeout time.Duration
Parallel bool
} }
// CreateStatement represents a SQL CREATE statement. // CreateStatement represents a SQL CREATE statement.
type CreateStatement struct { type CreateStatement struct {
What Exprs What Exprs
Data Expr Data Expr
Echo Token Echo Token
Timeout time.Duration Timeout time.Duration
Parallel bool
} }
// UpdateStatement represents a SQL UPDATE statement. // UpdateStatement represents a SQL UPDATE statement.
type UpdateStatement struct { type UpdateStatement struct {
What Exprs What Exprs
Data Expr Data Expr
Cond Expr Cond Expr
Echo Token Echo Token
Timeout time.Duration Timeout time.Duration
Parallel bool
} }
// DeleteStatement represents a SQL DELETE statement. // DeleteStatement represents a SQL DELETE statement.
type DeleteStatement struct { type DeleteStatement struct {
What Exprs What Exprs
Cond Expr Cond Expr
Echo Token Echo Token
Timeout time.Duration Timeout time.Duration
Parallel bool
} }
// RelateStatement represents a SQL RELATE statement. // RelateStatement represents a SQL RELATE statement.
type RelateStatement struct { type RelateStatement struct {
Type Expr Type Expr
From Exprs From Exprs
With Exprs With Exprs
Data Expr Data Expr
Uniq bool Uniq bool
Echo Token Echo Token
Timeout time.Duration Timeout time.Duration
Parallel bool
} }
// InsertStatement represents a SQL INSERT statement. // InsertStatement represents a SQL INSERT statement.
type InsertStatement struct { type InsertStatement struct {
Data Expr Data Expr
Into *Table Into *Table
Echo Token Echo Token
Timeout time.Duration Timeout time.Duration
Parallel bool
} }
// UpsertStatement represents a SQL UPSERT statement. // UpsertStatement represents a SQL UPSERT statement.
type UpsertStatement struct { type UpsertStatement struct {
Data Expr Data Expr
Into *Table Into *Table
Echo Token Echo Token
Timeout time.Duration Timeout time.Duration
Parallel bool
} }
// -------------------------------------------------- // --------------------------------------------------

View file

@ -34,6 +34,10 @@ func (p *parser) parseCreateStatement() (stmt *CreateStatement, err error) {
return nil, err return nil, err
} }
if stmt.Parallel, err = p.parseParallel(); err != nil {
return nil, err
}
return return
} }

View file

@ -36,6 +36,10 @@ func (p *parser) parseDeleteStatement() (stmt *DeleteStatement, err error) {
return nil, err return nil, err
} }
if stmt.Parallel, err = p.parseParallel(); err != nil {
return nil, err
}
return return
} }

View file

@ -244,20 +244,20 @@ func (p *parser) parsePriority() (float64, error) {
} }
func (p *parser) parseParallel() (int, error) { func (p *parser) parseParallel() (bool, error) {
if _, _, exi := p.mightBe(PARALLEL); !exi { if _, _, exi := p.mightBe(PARALLEL); !exi {
return 0, nil return true, nil
} }
tok, lit, err := p.shouldBe(NUMBER) tok, lit, err := p.shouldBe(TRUE, FALSE)
if err != nil { if err != nil {
return 0, &ParseError{Found: lit, Expected: []string{"number"}} return true, &ParseError{Found: lit, Expected: []string{"true", "false"}}
} }
val, err := p.declare(tok, lit) val, err := p.declare(tok, lit)
return int(val.(float64)), err return val.(bool), err
} }

View file

@ -40,6 +40,10 @@ func (p *parser) parseInsertStatement() (stmt *InsertStatement, err error) {
return nil, err return nil, err
} }
if stmt.Parallel, err = p.parseParallel(); err != nil {
return nil, err
}
return return
} }

View file

@ -52,6 +52,10 @@ func (p *parser) parseRelateStatement() (stmt *RelateStatement, err error) {
return nil, err return nil, err
} }
if stmt.Parallel, err = p.parseParallel(); err != nil {
return nil, err
}
return return
} }

View file

@ -67,6 +67,10 @@ func (p *parser) parseSelectStatement() (stmt *SelectStatement, err error) {
return nil, err return nil, err
} }
if stmt.Parallel, err = p.parseParallel(); err != nil {
return nil, err
}
if err = checkExpression(aggrs, stmt.Expr, stmt.Group); err != nil { if err = checkExpression(aggrs, stmt.Expr, stmt.Group); err != nil {
return nil, err return nil, err
} }

File diff suppressed because it is too large Load diff

View file

@ -38,6 +38,10 @@ func (p *parser) parseUpdateStatement() (stmt *UpdateStatement, err error) {
return nil, err return nil, err
} }
if stmt.Parallel, err = p.parseParallel(); err != nil {
return nil, err
}
return return
} }

View file

@ -40,6 +40,10 @@ func (p *parser) parseUpsertStatement() (stmt *UpsertStatement, err error) {
return nil, err return nil, err
} }
if stmt.Parallel, err = p.parseParallel(); err != nil {
return nil, err
}
return return
} }