Skip to content

Commit

Permalink
refactor(types): 采用 map 代替原来的 slice
Browse files Browse the repository at this point in the history
性能相差无几,但是少了许多代码。
  • Loading branch information
caixw committed May 22, 2024
1 parent b04c719 commit ff156e5
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 90 deletions.
6 changes: 3 additions & 3 deletions header/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ const (
NoCache = "no-cache"
Identity = "identity"

MessageHTTP = "message/http" // MessageHTTP TRACE 请求方法的 content-type 值
MultipartFormData = "multipart/form-data" // MultipartFormData 表单提交类型
FormData = "application/x-www-form-urlencoded" // FormData 普通的表单上传
MessageHTTP = "message/http" // SSE 的 content-type 值
MultipartFormData = "multipart/form-data" // 表单提交类型
FormData = "application/x-www-form-urlencoded" // 普通的表单上传
EventStream = "text/event-stream"
Plain = "text/plain"
HTML = "text/html"
Expand Down
2 changes: 1 addition & 1 deletion internal/tree/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (

func TestTrace(w http.ResponseWriter, r *http.Request) { trace.Trace(w, r, true) }

// NewTestTree 返回以 http.Handler 作为参数实例化的 Tree
// NewTestTree 返回以 [http.Handler] 作为参数实例化的 Tree
func NewTestTree(a *assert.Assertion, lock bool, trace http.Handler, i *syntax.Interceptors) *Tree[http.Handler] {
t := New("", lock, i, http.NotFoundHandler(), trace, BuildTestNodeHandlerFunc(http.StatusMethodNotAllowed), BuildTestNodeHandlerFunc(http.StatusOK))
a.NotNil(t)
Expand Down
76 changes: 18 additions & 58 deletions types/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ var contextPool = &sync.Pool{New: func() any { return &Context{} }}
//
// Context 同时实现了 [Route] 接口。
type Context struct {
Path string // 实际请求的路径信息
keys []string
vals []string
paramsCount int
routerName string
node Node
Path string // 实际请求的路径信息
params map[string]string
routerName string
node Node
}

func NewContext() *Context {
Expand All @@ -31,9 +29,7 @@ func NewContext() *Context {

func (ctx *Context) Reset() {
ctx.Path = ""
ctx.keys = ctx.keys[:0]
ctx.vals = ctx.vals[:0]
ctx.paramsCount = 0
clear(ctx.params)
ctx.routerName = ""
ctx.node = nil
}
Expand All @@ -50,7 +46,7 @@ func (ctx *Context) RouterName() string { return ctx.routerName }

func (ctx *Context) Destroy() {
const destroyMaxSize = 30
if ctx != nil && len(ctx.keys) <= destroyMaxSize {
if ctx != nil && len(ctx.params) <= destroyMaxSize {
contextPool.Put(ctx)
}
}
Expand Down Expand Up @@ -139,67 +135,31 @@ func (ctx *Context) MustFloat(key string, def float64) float64 {
}

func (ctx *Context) Get(key string) (string, bool) {
if ctx == nil {
if ctx.params == nil {
return "", false
}

for i, k := range ctx.keys {
if k == key {
return ctx.vals[i], true
}
}
return "", false
v, f := ctx.params[key]
return v, f
}

func (ctx *Context) Count() (cnt int) {
if ctx == nil {
return 0
}
return ctx.paramsCount
}
func (ctx *Context) Count() int { return len(ctx.params) }

func (ctx *Context) Set(k, v string) {
deletedIndex := -1

for i, key := range ctx.keys {
if key == k {
ctx.vals[i] = v
return
}
if key == "" && deletedIndex == -1 {
deletedIndex = i
}
}

// 没有需要修改的项
ctx.paramsCount++
if deletedIndex != -1 { // 优先考虑被标记为删除的项作为添加
ctx.keys[deletedIndex] = k
ctx.vals[deletedIndex] = v
} else {
ctx.keys = append(ctx.keys, k)
ctx.vals = append(ctx.vals, v)
if ctx.params == nil {
ctx.params = map[string]string{k: v}
return
}
ctx.params[k] = v
}

func (ctx *Context) Delete(k string) {
if ctx == nil {
return
}

for i, key := range ctx.keys {
if key == k {
ctx.keys[i] = ""
ctx.paramsCount--
return
}
if ctx.params != nil {
delete(ctx.params, k)
}
}

func (ctx *Context) Range(f func(key, val string)) {
for i, k := range ctx.keys {
if k != "" {
f(k, ctx.vals[i])
}
for k, v := range ctx.params {
f(k, v)
}
}
34 changes: 9 additions & 25 deletions types/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,6 @@ func TestContext_Float(t *testing.T) {
val, err = ctx.Float("k5")
a.ErrorIs(err, ErrParamNotExists()).Equal(val, 0.0)
a.Equal(ctx.MustFloat("k5", -10.0), -10.0)

var ps2 *Context
val, err = ps2.Float("key1")
a.Equal(err, ErrParamNotExists()).Equal(val, 0.0)
}

func TestContext_Set(t *testing.T) {
Expand All @@ -162,27 +158,20 @@ func TestContext_Set(t *testing.T) {
a.Equal(ctx.Count(), 1)

ctx.Set("k1", "v2")
a.Equal(ctx.Count(), 1)
a.Equal(ctx.keys, []string{"k1"})
a.Equal(ctx.vals, []string{"v2"})
a.Equal(ctx.Count(), 1).
Equal(ctx.params, map[string]string{"k1": "v2"})

ctx.Set("k2", "v2")
a.Equal(ctx.keys, []string{"k1", "k2"})
a.Equal(ctx.vals, []string{"v2", "v2"})
a.Equal(ctx.Count(), 2)
a.Equal(ctx.params, map[string]string{"k1": "v2", "k2": "v2"}).
Equal(ctx.Count(), 2)
}

func TestContext_Get(t *testing.T) {
a := assert.New(t, false)

var ctx *Context
a.Zero(ctx.Count())
v, found := ctx.Get("not-exists")
a.False(found).Zero(v)

ctx = NewContext()
ctx := NewContext()
ctx.Set("k1", "v1")
v, found = ctx.Get("k1")
v, found := ctx.Get("k1")
a.True(found).Equal(v, "v1")

v, found = ctx.Get("not-exists")
Expand All @@ -193,10 +182,7 @@ func TestContext_Get(t *testing.T) {
func TestContext_Delete(t *testing.T) {
a := assert.New(t, false)

var ctx *Context
ctx.Delete("k1")

ctx = NewContext()
ctx := NewContext()
ctx.Path = "/path"
ctx.Set("k1", "v1")
ctx.Set("k2", "v2")
Expand All @@ -207,12 +193,10 @@ func TestContext_Delete(t *testing.T) {
a.Equal(1, ctx.Count())

ctx.Delete("k2")
a.Equal(0, ctx.Count()).
Equal(2, len(ctx.keys))
a.Equal(0, ctx.Count())

ctx.Set("k3", "v3")
a.Equal(1, ctx.Count()).
Equal(2, len(ctx.keys))
a.Equal(1, ctx.Count())
}

func TestContext_Range(t *testing.T) {
Expand Down
8 changes: 5 additions & 3 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,11 @@ type Node interface {
// BuildNodeHandler 为节点生成处理方法
type BuildNodeHandler[T any] func(Node) T

// Middleware 中间件对象需要实现的接口
// Middleware 中间件
//
// 中间件用于改变一个路由项的行为,运行于在路由项的初始化阶段。
type Middleware[T any] interface {
// Middleware 包装处理 next
// Middleware 调整路由项 next 的行为
//
// next 路由项的处理函数;
// method 当前路由的请求方法;
Expand All @@ -125,7 +127,7 @@ type Middleware[T any] interface {
Middleware(next T, method, pattern, router string) T
}

// MiddlewareFunc 中间件处理函数
// MiddlewareFunc 中间件
type MiddlewareFunc[T any] func(next T, method, pattern, router string) T

func (f MiddlewareFunc[T]) Middleware(next T, method, pattern, router string) T {
Expand Down

0 comments on commit ff156e5

Please sign in to comment.