From 84c9d0f4ba936cd22468cf8c11cb9ea232a78775 Mon Sep 17 00:00:00 2001 From: Behnam Mohammadzadeh Date: Thu, 30 May 2024 00:52:12 +0330 Subject: [PATCH] optimization: struct alignment (#2632) --- binder.go | 9 ++++----- context.go | 10 +++++----- echo.go | 12 ++++++------ echo_fs.go | 2 +- group.go | 2 +- ip.go | 2 +- response.go | 2 +- router.go | 33 ++++++++++++++++----------------- 8 files changed, 35 insertions(+), 37 deletions(-) diff --git a/binder.go b/binder.go index ebabeaf96..da15ae82a 100644 --- a/binder.go +++ b/binder.go @@ -69,9 +69,9 @@ import ( type BindingError struct { // Field is the field name where value binding failed Field string `json:"field"` + *HTTPError // Values of parameter that failed to bind. Values []string `json:"-"` - *HTTPError } // NewBindingError creates new instance of binding error @@ -94,16 +94,15 @@ func (be *BindingError) Error() string { // ValueBinder provides utility methods for binding query or path parameter to various Go built-in types type ValueBinder struct { - // failFast is flag for binding methods to return without attempting to bind when previous binding already failed - failFast bool - errors []error - // ValueFunc is used to get single parameter (first) value from request ValueFunc func(sourceParam string) string // ValuesFunc is used to get all values for parameter from request. i.e. `/api/search?ids=1&ids=2` ValuesFunc func(sourceParam string) []string // ErrorFunc is used to create errors. Allows you to use your own error type, that for example marshals to your specific json response ErrorFunc func(sourceParam string, values []string, message interface{}, internalError error) error + errors []error + // failFast is flag for binding methods to return without attempting to bind when previous binding already failed + failFast bool } // QueryParamsBinder creates query parameter value binder diff --git a/context.go b/context.go index 4edaa2ee1..f5dd5a69d 100644 --- a/context.go +++ b/context.go @@ -200,31 +200,31 @@ type Context interface { } type context struct { + logger Logger request *http.Request response *Response query url.Values echo *Echo - logger Logger store Map lock sync.RWMutex // following fields are set by Router + handler HandlerFunc // path is route path that Router matched. It is empty string where there is no route match. // Route registered with RouteNotFound is considered as a match and path therefore is not empty. path string - // pnames length is tied to param count for the matched route - pnames []string - // Usually echo.Echo is sizing pvalues but there could be user created middlewares that decide to // overwrite parameter by calling SetParamNames + SetParamValues. // When echo.Echo allocated that slice it length/capacity is tied to echo.Echo.maxParam value. // // It is important that pvalues size is always equal or bigger to pnames length. pvalues []string - handler HandlerFunc + + // pnames length is tied to param count for the matched route + pnames []string } const ( diff --git a/echo.go b/echo.go index ab66b0da8..dbb98113a 100644 --- a/echo.go +++ b/echo.go @@ -91,10 +91,6 @@ type Echo struct { Listener net.Listener TLSListener net.Listener AutoTLSManager autocert.Manager - DisableHTTP2 bool - Debug bool - HideBanner bool - HidePort bool HTTPErrorHandler HTTPErrorHandler Binder Binder JSONSerializer JSONSerializer @@ -106,6 +102,10 @@ type Echo struct { // OnAddRouteHandler is called when Echo adds new route to specific host router. OnAddRouteHandler func(host string, route Route, handler HandlerFunc, middleware []MiddlewareFunc) + DisableHTTP2 bool + Debug bool + HideBanner bool + HidePort bool } // Route contains a handler and information for matching against requests. @@ -117,9 +117,9 @@ type Route struct { // HTTPError represents an error that occurred while handling a request. type HTTPError struct { - Code int `json:"-"` - Message interface{} `json:"message"` Internal error `json:"-"` // Stores the error returned by an external dependency + Message interface{} `json:"message"` + Code int `json:"-"` } // MiddlewareFunc defines a function to process middleware. diff --git a/echo_fs.go b/echo_fs.go index a7b231f31..0ffc4b0bf 100644 --- a/echo_fs.go +++ b/echo_fs.go @@ -102,8 +102,8 @@ func StaticFileHandler(file string, filesystem fs.FS) HandlerFunc { // traverse up from current executable run path. // NB: private because you really should use fs.FS implementation instances type defaultFS struct { - prefix string fs fs.FS + prefix string } func newDefaultFS() *defaultFS { diff --git a/group.go b/group.go index eca25c947..cb37b123f 100644 --- a/group.go +++ b/group.go @@ -14,8 +14,8 @@ type Group struct { common host string prefix string - middleware []MiddlewareFunc echo *Echo + middleware []MiddlewareFunc } // Use implements `Echo#Use()` for sub-routes within the Group. diff --git a/ip.go b/ip.go index 6aed8d606..393a6c2d3 100644 --- a/ip.go +++ b/ip.go @@ -134,10 +134,10 @@ Private IPv6 address ranges: */ type ipChecker struct { + trustExtraRanges []*net.IPNet trustLoopback bool trustLinkLocal bool trustPrivateNet bool - trustExtraRanges []*net.IPNet } // TrustOption is config for which IP address to trust diff --git a/response.go b/response.go index a795ce36e..a40072dc2 100644 --- a/response.go +++ b/response.go @@ -14,10 +14,10 @@ import ( // by an HTTP handler to construct an HTTP response. // See: https://golang.org/pkg/net/http/#ResponseWriter type Response struct { + Writer http.ResponseWriter echo *Echo beforeFuncs []func() afterFuncs []func() - Writer http.ResponseWriter Status int Size int64 Committed bool diff --git a/router.go b/router.go index 03267315d..49b56966d 100644 --- a/router.go +++ b/router.go @@ -18,32 +18,31 @@ type Router struct { } type node struct { - kind kind - label byte - prefix string - parent *node - staticChildren children - originalPath string - methods *routeMethods - paramChild *node - anyChild *node - paramsCount int + methods *routeMethods + parent *node + paramChild *node + anyChild *node + // notFoundHandler is handler registered with RouteNotFound method and is executed for 404 cases + notFoundHandler *routeMethod + prefix string + originalPath string + staticChildren children + paramsCount int + label byte + kind kind // isLeaf indicates that node does not have child routes isLeaf bool // isHandler indicates that node has at least one handler registered to it isHandler bool - - // notFoundHandler is handler registered with RouteNotFound method and is executed for 404 cases - notFoundHandler *routeMethod } type kind uint8 type children []*node type routeMethod struct { + handler HandlerFunc ppath string pnames []string - handler HandlerFunc } type routeMethods struct { @@ -242,18 +241,18 @@ func (r *Router) insert(method, path string, h HandlerFunc) { if i == lcpIndex { // path node is last fragment of route path. ie. `/users/:id` - r.insertNode(method, path[:i], paramKind, routeMethod{ppath, pnames, h}) + r.insertNode(method, path[:i], paramKind, routeMethod{ppath: ppath, pnames: pnames, handler: h}) } else { r.insertNode(method, path[:i], paramKind, routeMethod{}) } } else if path[i] == '*' { r.insertNode(method, path[:i], staticKind, routeMethod{}) pnames = append(pnames, "*") - r.insertNode(method, path[:i+1], anyKind, routeMethod{ppath, pnames, h}) + r.insertNode(method, path[:i+1], anyKind, routeMethod{ppath: ppath, pnames: pnames, handler: h}) } } - r.insertNode(method, path, staticKind, routeMethod{ppath, pnames, h}) + r.insertNode(method, path, staticKind, routeMethod{ppath: ppath, pnames: pnames, handler: h}) } func (r *Router) insertNode(method, path string, t kind, rm routeMethod) {