created TokenPool

This commit is contained in:
z7zmey 2018-07-12 10:53:36 +03:00
parent b70fb72a45
commit 4da7b36056
3 changed files with 59 additions and 6 deletions

View File

@ -6,7 +6,6 @@ import (
"bytes" "bytes"
t "go/token" t "go/token"
"io" "io"
"sync"
"unicode" "unicode"
"github.com/z7zmey/php-parser/position" "github.com/z7zmey/php-parser/position"
@ -36,7 +35,7 @@ type Lexer struct {
Meta []meta.Meta Meta []meta.Meta
heredocLabel string heredocLabel string
tokenBytesBuf *bytes.Buffer tokenBytesBuf *bytes.Buffer
TokenPool sync.Pool TokenPool *TokenPool
WithMeta bool WithMeta bool
lastToken *Token lastToken *Token
} }
@ -74,9 +73,7 @@ func NewLexer(src io.Reader, fName string) *Lexer {
Meta: nil, Meta: nil,
heredocLabel: "", heredocLabel: "",
tokenBytesBuf: &bytes.Buffer{}, tokenBytesBuf: &bytes.Buffer{},
TokenPool: sync.Pool{ TokenPool: &TokenPool{},
New: func() interface{} { return &Token{} },
},
} }
} }
@ -123,7 +120,7 @@ func (l *Lexer) createToken(chars []lex.Char) *Token {
firstChar := chars[0] firstChar := chars[0]
lastChar := chars[len(chars)-1] lastChar := chars[len(chars)-1]
token := l.TokenPool.Get().(*Token) token := l.TokenPool.Get()
token.Meta = l.Meta token.Meta = l.Meta
token.Value = l.tokenString(chars) token.Value = l.tokenString(chars)

22
scanner/token_pool.go Normal file
View File

@ -0,0 +1,22 @@
package scanner
// TokenPool light version of sync.Pool for Token objects
type TokenPool struct {
pool []*Token
}
// Get returns *Token from pool or creates new object
func (tp *TokenPool) Get() *Token {
if len(tp.pool) < 1 {
return new(Token)
}
t := tp.pool[len(tp.pool)-1]
tp.pool = tp.pool[:len(tp.pool)-1]
return t
}
// Put returns *Token to pool
func (tp *TokenPool) Put(t *Token) {
tp.pool = append(tp.pool, t)
}

View File

@ -0,0 +1,34 @@
package scanner_test
import (
"reflect"
"testing"
"github.com/z7zmey/php-parser/scanner"
)
func TestTokenPoolGetNew(t *testing.T) {
tp := new(scanner.TokenPool)
newToken := tp.Get()
if newToken == nil {
t.Errorf("*TokenPool.Get() must return new *Token object\n")
}
}
func TestTokenPoolGetFromPool(t *testing.T) {
tp := new(scanner.TokenPool)
expectedToken := &scanner.Token{
Value: "test",
}
tp.Put(expectedToken)
actualToken := tp.Get()
if !reflect.DeepEqual(expectedToken, actualToken) {
t.Errorf("*TokenPool.Put() must return *Token object from pool\n")
}
}