Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: go-chi/chi
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.1.1
Choose a base ref
...
head repository: go-chi/chi
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v3.1.2
Choose a head ref
  • 1 commit
  • 5 files changed
  • 1 contributor

Commits on Jul 24, 2017

  1. Flatten Context.URLParams data structure

    Peter Kieltyka committed Jul 24, 2017
    Copy the full SHA
    7e6b856 View commit details
Showing with 25 additions and 33 deletions.
  1. +10 −18 context.go
  2. +4 −4 mux.go
  3. +6 −5 mux_test.go
  4. +2 −5 tree.go
  5. +3 −1 tree_test.go
28 changes: 10 additions & 18 deletions context.go
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ type Context struct {

// URLParams are the stack of routeParams captured during the
// routing lifecycle across a stack of sub-routers.
URLParams RouteParamsStack
URLParams RouteParams

// The endpoint routing pattern that matched the request URI path
// or `RoutePath` of the current sub-router. This value will update
@@ -50,7 +50,8 @@ func NewRouteContext() *Context {
func (x *Context) reset() {
x.RoutePath = ""
x.RoutePatterns = x.RoutePatterns[:0]
x.URLParams = x.URLParams[:0]
x.URLParams.Keys = x.URLParams.Keys[:0]
x.URLParams.Values = x.URLParams.Values[:0]

x.routePattern = ""
x.routeParams.Keys = x.routeParams.Keys[:0]
@@ -59,11 +60,9 @@ func (x *Context) reset() {
}

func (x *Context) URLParam(key string) string {
for s := len(x.URLParams) - 1; s >= 0; s-- {
for k := len(x.URLParams[s].Keys) - 1; k >= 0; k-- {
if x.URLParams[s].Keys[k] == key {
return x.URLParams[s].Values[k]
}
for k := len(x.URLParams.Keys) - 1; k >= 0; k-- {
if x.URLParams.Keys[k] == key {
return x.URLParams.Values[k]
}
}
return ""
@@ -95,17 +94,10 @@ type RouteParams struct {
Keys, Values []string
}

type RouteParamsStack []RouteParams

// Add will append a URL parameter to the end of the route param stack
func (s *RouteParamsStack) Add(key, value string) {
x := len(*s) - 1
if x < 0 {
*s = append(*s, RouteParams{})
x = 0
}
(*s)[x].Keys = append((*s)[x].Keys, key)
(*s)[x].Values = append((*s)[x].Values, value)
// Add will append a URL parameter to the end of the route param
func (s *RouteParams) Add(key, value string) {
(*s).Keys = append((*s).Keys, key)
(*s).Values = append((*s).Values, value)
}

// ServerBaseContext wraps an http.Handler to set the request context to the
8 changes: 4 additions & 4 deletions mux.go
Original file line number Diff line number Diff line change
@@ -283,12 +283,12 @@ func (mx *Mux) Mount(pattern string, handler http.Handler) {
}

// Wrap the sub-router in a handlerFunc to scope the request path for routing.
subHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
mountHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
rctx := RouteContext(r.Context())
rctx.RoutePath = "/"

nx := len(rctx.routeParams.Keys) - 1 // index of last param in list
if nx >= 0 && rctx.routeParams.Keys[nx] == "*" {
if nx >= 0 && rctx.routeParams.Keys[nx] == "*" && len(rctx.routeParams.Values) >= nx {
rctx.RoutePath += rctx.routeParams.Values[nx]
}

@@ -300,7 +300,7 @@ func (mx *Mux) Mount(pattern string, handler http.Handler) {
mx.NotFoundHandler().ServeHTTP(w, r)
})

mx.handle(mALL|mSTUB, pattern, subHandler)
mx.handle(mALL|mSTUB, pattern, mountHandler)
mx.handle(mALL|mSTUB, pattern+"/", notFoundHandler)
pattern += "/"
}
@@ -310,7 +310,7 @@ func (mx *Mux) Mount(pattern string, handler http.Handler) {
if subroutes != nil {
method |= mSTUB
}
n := mx.handle(method, pattern+"*", subHandler)
n := mx.handle(method, pattern+"*", mountHandler)

if subroutes != nil {
n.subroutes = subroutes
11 changes: 6 additions & 5 deletions mux_test.go
Original file line number Diff line number Diff line change
@@ -1548,11 +1548,12 @@ func BenchmarkMux(b *testing.B) {
mx.Get("/hi", h2)
mx.Get("/sup/{id}/and/{this}", h3)

mx.Route("/sharing/{hash}", func(mx Router) { // subrouter-1
mx.Get("/", h4)
mx.Get("/{network}", h5)
mx.Route("/direct", func(mx Router) { // subrouter-2
mx.Get("/", h6)
mx.Route("/sharing/{hash}", func(mx Router) {
mx.Get("/", h4) // subrouter-1
mx.Get("/{network}", h5) // subrouter-1
mx.Get("/twitter", h5)
mx.Route("/direct", func(mx Router) {
mx.Get("/", h6) // subrouter-2
})
})

7 changes: 2 additions & 5 deletions tree.go
Original file line number Diff line number Diff line change
@@ -353,12 +353,9 @@ func (n *node) FindRoute(rctx *Context, method methodTyp, path string) endpoints
return nil
}

rp := RouteParams{}
rp.Keys = append(rp.Keys, rctx.routeParams.Keys...)
rp.Values = append(rp.Values, rctx.routeParams.Values...)

// Record the routing params in the request lifecycle
rctx.URLParams = append(rctx.URLParams, rp)
rctx.URLParams.Keys = append(rctx.URLParams.Keys, rctx.routeParams.Keys...)
rctx.URLParams.Values = append(rctx.URLParams.Values, rctx.routeParams.Values...)

// Record the routing pattern in the request lifecycle
if rn.endpoints[method].pattern != "" {
4 changes: 3 additions & 1 deletion tree_test.go
Original file line number Diff line number Diff line change
@@ -414,11 +414,13 @@ func BenchmarkTreeGet(b *testing.B) {
tr.InsertRoute(mGET, "/pinggggg", h2)
tr.InsertRoute(mGET, "/hello", h1)

mctx := NewRouteContext()

b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
mctx := NewRouteContext()
mctx.reset()
tr.FindRoute(mctx, mGET, "/ping/123/456")
}
}