]> 127.0.0.1 Git - part/.git/commitdiff
Improve v0.22.6
authorqydysky <32743305+qydysky@users.noreply.github.com>
Sat, 11 Feb 2023 12:02:05 +0000 (20:02 +0800)
committerqydysky <32743305+qydysky@users.noreply.github.com>
Sat, 11 Feb 2023 12:02:05 +0000 (20:02 +0800)
web/Web.go
web/Web_test.go

index 7bc30f9f144adda089bf3f6ca3b5fef7acda1fb6..8cc84ac215ad6cda776f9e524e10c237516ce84c 100644 (file)
@@ -26,109 +26,75 @@ type WebPath struct {
        f     func(w http.ResponseWriter, r *http.Request)
        sameP *WebPath
        next  *WebPath
-       l     sync.RWMutex
+       sync.RWMutex
 }
 
 func (t *WebPath) Load(path string) (func(w http.ResponseWriter, r *http.Request), bool) {
-       t.l.RLock()
-       if t.path == "" {
-               t.l.RUnlock()
-               return nil, false
-       } else if t.path == path {
-               t.l.RUnlock()
+       t.RLock()
+       defer t.RUnlock()
+       if t.path == path || t.f == nil {
+               // 操作本节点
                return t.f, true
-       } else if len(path) > len(t.path) && path[:len(t.path)] == t.path {
-               if t.path == "/" || path[len(t.path)] == '/' {
-                       if t.sameP != nil {
-                               if f, ok := t.sameP.Load(path); ok {
-                                       t.l.RUnlock()
-                                       return f, true
-                               } else {
-                                       t.l.RUnlock()
-                                       return t.f, true
-                               }
-                       } else {
-                               t.l.RUnlock()
-                               return t.f, true
+       } else if lp, ltp := len(path), len(t.path); lp > ltp && path[:ltp] == t.path && (path[ltp] == '/' || t.path[ltp-1] == '/') {
+               // 操作sameP节点
+               if t.sameP != nil {
+                       if f, ok := t.sameP.Load(path); ok {
+                               return f, true
                        }
+               }
+               if t.path[ltp-1] == '/' {
+                       return t.f, true
                } else {
-                       if t.next != nil {
-                               t.l.RUnlock()
-                               return t.next.Load(path)
-                       } else {
-                               t.l.RUnlock()
-                               return nil, false
-                       }
+                       return nil, false
                }
-       } else if t.next != nil {
-               t.l.RUnlock()
-               return t.next.Load(path)
+       } else if lp < ltp && t.path[:lp] == path && (path[lp-1] == '/' || t.path[lp] == '/') {
+               // 操作sameP节点
+               return nil, false
        } else {
-               t.l.RUnlock()
+               // 操作next节点
+               if t.next != nil {
+                       if f, ok := t.next.Load(path); ok {
+                               return f, true
+                       }
+               }
                return nil, false
        }
 }
 
 func (t *WebPath) Store(path string, f func(w http.ResponseWriter, r *http.Request)) {
-       t.l.RLock()
-       if t.path == path || t.path == "" {
-               t.l.RUnlock()
-               t.l.Lock()
+       t.Lock()
+       defer t.Unlock()
+       if t.path == path || t.f == nil {
+               // 操作本节点
                t.path = path
                t.f = f
-               t.l.Unlock()
-       } else if len(path) > len(t.path) && path[:len(t.path)] == t.path {
-               if t.path == "/" || path[len(t.path)] == '/' {
-                       if t.sameP != nil {
-                               t.l.RUnlock()
-                               t.sameP.Store(path, f)
-                       } else {
-                               t.l.RUnlock()
-                               t.l.Lock()
-                               t.sameP = &WebPath{
-                                       path: path,
-                                       f:    f,
-                               }
-                               t.l.Unlock()
-                       }
+       } else if len(path) > len(t.path) && path[:len(t.path)] == t.path && (path[len(t.path)-1] == '/' || t.path[len(t.path)-1] == '/') {
+               // 操作sameP节点
+               if t.sameP != nil {
+                       t.sameP.Store(path, f)
                } else {
-                       if t.next != nil {
-                               t.l.RUnlock()
-                               t.l.Lock()
-                               tmp := WebPath{path: t.path, f: t.f, sameP: t.sameP, next: t.next}
-                               t.path = path
-                               t.f = f
-                               t.next = &tmp
-                               t.l.Unlock()
-                       } else {
-                               t.l.RUnlock()
-                               t.l.Lock()
-                               t.next = &WebPath{
-                                       path: path,
-                                       f:    f,
-                               }
-                               t.l.Unlock()
+                       t.sameP = &WebPath{
+                               path: path,
+                               f:    f,
                        }
                }
-       } else if len(path) < len(t.path) && t.path[:len(path)] == path {
-               t.l.RUnlock()
-               t.l.Lock()
+       } else if len(path) < len(t.path) && t.path[:len(path)] == path && (path[len(path)-1] == '/' || t.path[len(path)-1] == '/') {
+               // 操作sameP节点
                tmp := WebPath{path: t.path, f: t.f, sameP: t.sameP, next: t.next}
                t.path = path
                t.f = f
                t.sameP = &tmp
-               t.l.Unlock()
-       } else if t.next != nil {
-               t.l.RUnlock()
-               t.next.Store(path, f)
+               t.next = nil
        } else {
-               t.l.RUnlock()
-               t.l.Lock()
-               t.next = &WebPath{
-                       path: path,
-                       f:    f,
+               // 操作next节点
+               if t.next != nil {
+                       t.next.Store(path, f)
+               } else {
+                       t.next = &WebPath{
+                               path: path,
+                               f:    f,
+                       }
                }
-               t.l.Unlock()
        }
 }
 
@@ -190,7 +156,7 @@ func Easy_boot() *Web {
                        }
                        http.ServeFile(w, r, path)
                },
-               `/exit`: func(w http.ResponseWriter, r *http.Request) {
+               `/exit`: func(_ http.ResponseWriter, _ *http.Request) {
                        s.Server.Shutdown(context.Background())
                },
        })
index cdb00d851e47241add31066980adbf2e26679024..c437abf0fc6c76401b45edb1345c96d44d013c44 100644 (file)
@@ -6,6 +6,8 @@ import (
        "strconv"
        "testing"
        "time"
+
+       reqf "github.com/qydysky/part/reqf"
 )
 
 func Test_Server(t *testing.T) {
@@ -16,7 +18,7 @@ func Test_Server(t *testing.T) {
 
 func Test_ServerSyncMap(t *testing.T) {
        var m WebPath
-       m.Store("/", func(w http.ResponseWriter, r *http.Request) {
+       m.Store("/", func(w http.ResponseWriter, _ *http.Request) {
                w.Write([]byte("1"))
        })
        NewSyncMap(&http.Server{
@@ -24,7 +26,7 @@ func Test_ServerSyncMap(t *testing.T) {
        }, &m)
        for i := 0; i < 20; i++ {
                time.Sleep(time.Second)
-               m.Store("/1", func(w http.ResponseWriter, r *http.Request) {
+               m.Store("/1", func(w http.ResponseWriter, _ *http.Request) {
 
                        type d struct {
                                A string         `json:"a"`
@@ -46,7 +48,7 @@ func BenchmarkXxx(b *testing.B) {
        }
        b.ResetTimer()
        for i := 0; i < b.N; i++ {
-               m.Store("/", func(w http.ResponseWriter, r *http.Request) {
+               m.Store("/", func(w http.ResponseWriter, _ *http.Request) {
                        ResStruct{0, "ok", d{"/"}}.Write(w)
                })
        }
@@ -61,20 +63,70 @@ func Test_ServerSyncMapP(t *testing.T) {
        NewSyncMap(&http.Server{
                Addr: "127.0.0.1:9090",
        }, &m)
-       m.Store("/", func(w http.ResponseWriter, r *http.Request) {
-               ResStruct{0, "ok", d{"/"}}.Write(w)
-       })
-       m.Store("/1/2", func(w http.ResponseWriter, r *http.Request) {
+       m.Store("/1/2", func(w http.ResponseWriter, _ *http.Request) {
                ResStruct{0, "ok", d{"/1/2"}}.Write(w)
        })
-       m.Store("/1", func(w http.ResponseWriter, r *http.Request) {
-               ResStruct{0, "ok", d{"/1"}}.Write(w)
+       m.Store("/1/", func(w http.ResponseWriter, _ *http.Request) {
+               ResStruct{0, "ok", d{"/1/"}}.Write(w)
        })
-       m.Store("/2", func(w http.ResponseWriter, r *http.Request) {
-               ResStruct{0, "ok", d{"/2"}}.Write(w)
+       m.Store("/2/", func(w http.ResponseWriter, _ *http.Request) {
+               ResStruct{0, "ok", d{"/2/"}}.Write(w)
+       })
+       m.Store("/", func(w http.ResponseWriter, _ *http.Request) {
+               ResStruct{0, "ok", d{"/"}}.Write(w)
        })
 
-       time.Sleep(time.Second * time.Duration(23))
+       r := reqf.New()
+       res := ResStruct{}
+       r.Reqf(reqf.Rval{
+               Url: "http://127.0.0.1:9090/",
+       })
+       json.Unmarshal(r.Respon, &res)
+       if data, ok := res.Data.(map[string]any); !ok || data["path"].(string) != "/" {
+               t.Fatal("")
+       }
+       r.Reqf(reqf.Rval{
+               Url: "http://127.0.0.1:9090/1",
+       })
+       json.Unmarshal(r.Respon, &res)
+       if data, ok := res.Data.(map[string]any); !ok || data["path"].(string) != "/" {
+               t.Fatal("")
+       }
+       r.Reqf(reqf.Rval{
+               Url: "http://127.0.0.1:9090/1/",
+       })
+       json.Unmarshal(r.Respon, &res)
+       if data, ok := res.Data.(map[string]any); !ok || data["path"].(string) != "/1/" {
+               t.Fatal("")
+       }
+       r.Reqf(reqf.Rval{
+               Url: "http://127.0.0.1:9090/2",
+       })
+       json.Unmarshal(r.Respon, &res)
+       if data, ok := res.Data.(map[string]any); !ok || data["path"].(string) != "/" {
+               t.Fatal("")
+       }
+       r.Reqf(reqf.Rval{
+               Url: "http://127.0.0.1:9090/1/23",
+       })
+       json.Unmarshal(r.Respon, &res)
+       if data, ok := res.Data.(map[string]any); !ok || data["path"].(string) != "/1/" {
+               t.Fatal("")
+       }
+       r.Reqf(reqf.Rval{
+               Url: "http://127.0.0.1:9090/1/2/3",
+       })
+       json.Unmarshal(r.Respon, &res)
+       if data, ok := res.Data.(map[string]any); !ok || data["path"].(string) != "/1/" {
+               t.Fatal("")
+       }
+       r.Reqf(reqf.Rval{
+               Url: "http://127.0.0.1:9090/1/2",
+       })
+       json.Unmarshal(r.Respon, &res)
+       if data, ok := res.Data.(map[string]any); !ok || data["path"].(string) != "/1/2" {
+               t.Fatal("")
+       }
 }
 
 type ResStruct struct {