refactor gin context

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
Bo-Yi Wu 2020-05-09 00:46:47 +08:00
parent 0a09a5bb56
commit 7035cc2dd7
4 changed files with 32 additions and 31 deletions

View File

@ -54,6 +54,7 @@ type Context struct {
fullPath string fullPath string
engine *Engine engine *Engine
params *Params
// This mutex protect Keys map // This mutex protect Keys map
mu sync.RWMutex mu sync.RWMutex
@ -95,6 +96,7 @@ func (c *Context) reset() {
c.Accepted = nil c.Accepted = nil
c.queryCache = nil c.queryCache = nil
c.formCache = nil c.formCache = nil
*c.params = (*c.params)[0:0]
} }
// Copy returns a copy of the current context that can be safely used outside the request's scope. // Copy returns a copy of the current context that can be safely used outside the request's scope.

53
gin.go
View File

@ -113,8 +113,8 @@ type Engine struct {
noMethod HandlersChain noMethod HandlersChain
pool sync.Pool pool sync.Pool
trees methodTrees trees methodTrees
paramsPool sync.Pool // paramsPool sync.Pool
maxParams uint16 maxParams uint16
} }
var _ IRouter = &Engine{} var _ IRouter = &Engine{}
@ -165,7 +165,8 @@ func Default() *Engine {
} }
func (engine *Engine) allocateContext() *Context { func (engine *Engine) allocateContext() *Context {
return &Context{engine: engine} v := make(Params, 0, engine.maxParams)
return &Context{engine: engine, params: &v}
} }
// Delims sets template left and right delims and returns a Engine instance. // Delims sets template left and right delims and returns a Engine instance.
@ -276,13 +277,13 @@ func (engine *Engine) addRoute(method, path string, handlers HandlersChain) {
} }
// Lazy-init paramsPool alloc func // Lazy-init paramsPool alloc func
if engine.paramsPool.New == nil && engine.maxParams > 0 { // if engine.paramsPool.New == nil && engine.maxParams > 0 {
engine.paramsPool.New = func() interface{} { // engine.paramsPool.New = func() interface{} {
// log.Println("engine.maxParams:", engine.maxParams) // // log.Println("engine.maxParams:", engine.maxParams)
ps := make(Params, 0, engine.maxParams) // ps := make(Params, 0, engine.maxParams)
return &ps // return &ps
} // }
} // }
} }
// Routes returns a slice of registered routes, including some useful information, such as: // Routes returns a slice of registered routes, including some useful information, such as:
@ -401,22 +402,20 @@ func (engine *Engine) HandleContext(c *Context) {
c.index = oldIndexValue c.index = oldIndexValue
} }
func (engine *Engine) getParams() *Params { // func (engine *Engine) getParams() *Params {
// c := engine.pool.Get().(*Context) // ps := engine.paramsPool.Get().(*Params)
// c.Params = c.Params[0:0] // *ps = (*ps)[0:0] // reset slice
ps := engine.paramsPool.Get().(*Params) // return ps
*ps = (*ps)[0:0] // reset slice // }
return ps
}
func (engine *Engine) putParams(ps *Params) { // func (engine *Engine) putParams(ps *Params) {
// c := engine.pool.Get().(*Context) // c := engine.pool.Get().(*Context)
// c.Params = *ps // c.Params = *ps
// engine.pool.Put(c) // engine.pool.Put(c)
if ps != nil { // if ps != nil {
engine.paramsPool.Put(ps) // engine.paramsPool.Put(ps)
} // }
} // }
func (engine *Engine) handleHTTPRequest(c *Context) { func (engine *Engine) handleHTTPRequest(c *Context) {
httpMethod := c.Request.Method httpMethod := c.Request.Method
@ -439,9 +438,9 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
} }
root := t[i].root root := t[i].root
// Find route in tree // Find route in tree
value := root.getValue(rPath, engine.getParams, unescape) value := root.getValue(rPath, c.params, unescape)
if value.params != nil { if value.params != nil {
engine.putParams(value.params) // engine.putParams(value.params)
c.Params = *value.params c.Params = *value.params
} }
if value.handlers != nil { if value.handlers != nil {

View File

@ -419,7 +419,7 @@ type nodeValue struct {
// If no handle can be found, a TSR (trailing slash redirect) recommendation is // If no handle can be found, a TSR (trailing slash redirect) recommendation is
// made if a handle exists with an extra (without the) trailing slash for the // made if a handle exists with an extra (without the) trailing slash for the
// given path. // given path.
func (n *node) getValue(path string, params func() *Params, unescape bool) (value nodeValue) { func (n *node) getValue(path string, params *Params, unescape bool) (value nodeValue) {
value = nodeValue{} value = nodeValue{}
walk: // Outer loop for walking the tree walk: // Outer loop for walking the tree
for { for {
@ -474,7 +474,7 @@ walk: // Outer loop for walking the tree
// } // }
if params != nil { if params != nil {
if value.params == nil { if value.params == nil {
value.params = params() value.params = params
} }
// Expand slice within preallocated capacity // Expand slice within preallocated capacity
i := len(*value.params) i := len(*value.params)
@ -536,7 +536,7 @@ walk: // Outer loop for walking the tree
// Save param value // Save param value
if params != nil { if params != nil {
if value.params == nil { if value.params == nil {
value.params = params() value.params = params
} }
// Expand slice within preallocated capacity // Expand slice within preallocated capacity
i := len(*value.params) i := len(*value.params)

View File

@ -40,7 +40,7 @@ func checkRequests(t *testing.T, tree *node, requests testRequests, unescapes ..
} }
for _, request := range requests { for _, request := range requests {
value := tree.getValue(request.path, getParams, unescape) value := tree.getValue(request.path, getParams(), unescape)
if value.handlers == nil { if value.handlers == nil {
if !request.nilHandler { if !request.nilHandler {