From b72e1c200aebe1b75fc70b6b20551bb47a780691 Mon Sep 17 00:00:00 2001 From: ksw2000 <13825170+ksw2000@users.noreply.github.com> Date: Mon, 24 Mar 2025 22:53:11 +0800 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8FRefactor:=20reduce=20DefaultC?= =?UTF-8?q?tx=20from=20736=20to=20728=20bytes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.go | 4 ++-- ctx.go | 22 ++++++++++++---------- ctx_interface.go | 2 +- ctx_interface_gen.go | 2 +- helpers.go | 8 ++++---- router.go | 30 ++++++++++++++---------------- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/app.go b/app.go index 84059e79..d4d89d92 100644 --- a/app.go +++ b/app.go @@ -109,7 +109,7 @@ type App struct { // Route stack divided by HTTP methods stack [][]*Route // Route stack divided by HTTP methods and route prefixes - treeStack []map[string][]*Route + treeStack []map[int][]*Route // custom binders customBinders []CustomBinder // customConstraints is a list of external constraints @@ -581,7 +581,7 @@ func New(config ...Config) *App { // Create router stack app.stack = make([][]*Route, len(app.config.RequestMethods)) - app.treeStack = make([]map[string][]*Route, len(app.config.RequestMethods)) + app.treeStack = make([]map[int][]*Route, len(app.config.RequestMethods)) // Override colors app.config.ColorScheme = defaultColors(app.config.ColorScheme) diff --git a/ctx.go b/ctx.go index efd6006d..b959a48f 100644 --- a/ctx.go +++ b/ctx.go @@ -33,8 +33,11 @@ const ( schemeHTTPS = "https" ) -// maxParams defines the maximum number of parameters per route. -const maxParams = 30 +const ( + // maxParams defines the maximum number of parameters per route. + maxParams = 30 + maxDetectionPaths = 3 +) // The contextKey type is unexported to prevent collisions with context keys defined in // other packages. @@ -60,11 +63,11 @@ type DefaultCtx struct { viewBindMap sync.Map // Default view map to bind template engine method string // HTTP method baseURI string // HTTP base uri - treePath string // Path for the search in the tree pathOriginal string // Original HTTP path flashMessages redirectionMsgs // Flash messages path []byte // HTTP path with the modifications by the configuration detectionPath []byte // Route detection path + treePathHash int // Hash of the path for the search in the tree indexRoute int // Index of the current route indexHandler int // Index of the current handler methodINT int // HTTP method INT equivalent @@ -1851,12 +1854,11 @@ func (c *DefaultCtx) configDependentPaths() { // Define the path for dividing routes into areas for fast tree detection, so that fewer routes need to be traversed, // since the first three characters area select a list of routes - c.treePath = "" - const maxDetectionPaths = 3 + c.treePathHash = 0 if len(c.detectionPath) >= maxDetectionPaths { - // c.treePath is only used by Fiber and is not exposed to the user - // so we can use utils.UnsafeString instead of c.app.getString - c.treePath = utils.UnsafeString(c.detectionPath[:maxDetectionPaths]) + c.treePathHash = int(c.detectionPath[0])<<16 | + int(c.detectionPath[1])<<8 | + int(c.detectionPath[2]) } } @@ -1957,8 +1959,8 @@ func (c *DefaultCtx) getIndexRoute() int { return c.indexRoute } -func (c *DefaultCtx) getTreePath() string { - return c.treePath +func (c *DefaultCtx) getTreePathHash() int { + return c.treePathHash } func (c *DefaultCtx) getDetectionPath() string { diff --git a/ctx_interface.go b/ctx_interface.go index 32e8ee39..6ef33847 100644 --- a/ctx_interface.go +++ b/ctx_interface.go @@ -19,7 +19,7 @@ type CustomCtx interface { // Methods to use with next stack. getMethodINT() int getIndexRoute() int - getTreePath() string + getTreePathHash() int getDetectionPath() string getPathOriginal() string getValues() *[maxParams]string diff --git a/ctx_interface_gen.go b/ctx_interface_gen.go index fffe218d..a4d7db3d 100644 --- a/ctx_interface_gen.go +++ b/ctx_interface_gen.go @@ -347,7 +347,7 @@ type Ctx interface { // Methods to use with next stack. getMethodINT() int getIndexRoute() int - getTreePath() string + getTreePathHash() int getDetectionPath() string getPathOriginal() string getValues() *[maxParams]string diff --git a/helpers.go b/helpers.go index 584553a7..3f1685b1 100644 --- a/helpers.go +++ b/helpers.go @@ -113,9 +113,9 @@ func (app *App) methodExist(c *DefaultCtx) bool { // Reset stack index c.setIndexRoute(-1) - tree, ok := c.App().treeStack[i][c.getTreePath()] + tree, ok := c.App().treeStack[i][c.treePathHash] if !ok { - tree = c.App().treeStack[i][""] + tree = c.App().treeStack[i][0] } // Get stack length lenr := len(tree) - 1 @@ -157,9 +157,9 @@ func (app *App) methodExistCustom(c CustomCtx) bool { // Reset stack index c.setIndexRoute(-1) - tree, ok := c.App().treeStack[i][c.getTreePath()] + tree, ok := c.App().treeStack[i][c.getTreePathHash()] if !ok { - tree = c.App().treeStack[i][""] + tree = c.App().treeStack[i][0] } // Get stack length lenr := len(tree) - 1 diff --git a/router.go b/router.go index be289ca5..0aec6509 100644 --- a/router.go +++ b/router.go @@ -110,9 +110,9 @@ func (r *Route) match(detectionPath, path string, params *[maxParams]string) boo func (app *App) nextCustom(c CustomCtx) (bool, error) { //nolint:unparam // bool param might be useful for testing // Get stack length - tree, ok := app.treeStack[c.getMethodINT()][c.getTreePath()] + tree, ok := app.treeStack[c.getMethodINT()][c.getTreePathHash()] if !ok { - tree = app.treeStack[c.getMethodINT()][""] + tree = app.treeStack[c.getMethodINT()][0] } lenr := len(tree) - 1 @@ -158,9 +158,9 @@ func (app *App) nextCustom(c CustomCtx) (bool, error) { //nolint:unparam // bool func (app *App) next(c *DefaultCtx) (bool, error) { // Get stack length - tree, ok := app.treeStack[c.methodINT][c.treePath] + tree, ok := app.treeStack[c.methodINT][c.treePathHash] if !ok { - tree = app.treeStack[c.methodINT][""] + tree = app.treeStack[c.methodINT][0] } lenTree := len(tree) - 1 @@ -454,30 +454,28 @@ func (app *App) buildTree() *App { // loop all the methods and stacks and create the prefix tree for m := range app.config.RequestMethods { - tsMap := make(map[string][]*Route) + tsMap := make(map[int][]*Route) for _, route := range app.stack[m] { - treePath := "" - if len(route.routeParser.segs) > 0 && len(route.routeParser.segs[0].Const) >= 3 { - treePath = route.routeParser.segs[0].Const[:3] + treePathHash := 0 + if len(route.routeParser.segs) > 0 && len(route.routeParser.segs[0].Const) >= maxDetectionPaths { + treePathHash = int(route.routeParser.segs[0].Const[0])<<16 | + int(route.routeParser.segs[0].Const[1])<<8 | + int(route.routeParser.segs[0].Const[2]) } // create tree stack - tsMap[treePath] = append(tsMap[treePath], route) + tsMap[treePathHash] = append(tsMap[treePathHash], route) } - app.treeStack[m] = tsMap - } - // loop the methods and tree stacks and add global stack and sort everything - for m := range app.config.RequestMethods { - tsMap := app.treeStack[m] for treePart := range tsMap { - if treePart != "" { + if treePart != 0 { // merge global tree routes in current tree stack - tsMap[treePart] = uniqueRouteStack(append(tsMap[treePart], tsMap[""]...)) + tsMap[treePart] = uniqueRouteStack(append(tsMap[treePart], tsMap[0]...)) } // sort tree slices with the positions slc := tsMap[treePart] sort.Slice(slc, func(i, j int) bool { return slc[i].pos < slc[j].pos }) } + app.treeStack[m] = tsMap } app.routesRefreshed = false