type WebPath struct {
Path string `json:"path"`
// current net.Conn: conn, ok := r.Context().Value(&WebPath).(net.Conn)
- f func(w http.ResponseWriter, r *http.Request)
- Per *WebPath `json:"-"`
- Same *WebPath `json:"same"`
- Next *WebPath `json:"next"`
- l sync.RWMutex
+ f func(w http.ResponseWriter, r *http.Request)
+ PerSame *WebPath `json:"-"`
+ Per *WebPath `json:"-"`
+ Same *WebPath `json:"same"`
+ Next *WebPath `json:"next"`
+ l sync.RWMutex
}
// WebSync
if key, left, fin := parsePath(path); t.Path == key {
if fin {
- return t.f, true
+ return t.f, t.f != nil
} else {
if t.Same != nil {
return t.Same.Load(left)
return
}
+ if f == nil {
+ t.Delete(path)
+ return
+ }
+
t.l.Lock()
defer t.l.Unlock()
t.f = f
return
} else {
- t.Same = &WebPath{}
+ t.Same = &WebPath{PerSame: t}
t.Same.Store(left, f)
return
}
t.Same.Store(left, f)
return
} else {
- t.Same = &WebPath{}
+ t.Same = &WebPath{PerSame: t}
t.Same.Store(left, f)
return
}
}
}
+func (t *WebPath) Delete(path string) (deleteMe bool) {
+ if len(path) == 0 || path[0] != '/' {
+ return
+ }
+
+ t.l.Lock()
+ defer t.l.Unlock()
+
+ if key, left, fin := parsePath(path); t.Path == key {
+ if fin {
+ t.f = nil
+ return t.f == nil && t.Next == nil && t.Same == nil
+ } else {
+ if t.Same != nil {
+ if t.Same.Delete(left) {
+ t.Same = nil
+ }
+ return t.f == nil && t.Next == nil && t.Same == nil
+ } else {
+ return false
+ }
+ }
+ } else {
+ if t.Next != nil {
+ if t.Next.Delete(path) {
+ t.Next = nil
+ }
+ return t.f == nil && t.Next == nil && t.Same == nil
+ } else {
+ return false
+ }
+ }
+}
+
type Limits struct {
g []*limitItem
l sync.RWMutex
webPath.Store("/", f("a"))
webPath.Store("/1", f("b"))
+ webPath.Store("/2", f("b"))
webPath.Store("/1/1", f("c"))
+ webPath.Store("/1/2", f("d"))
+ webPath.Delete("/2")
+ webPath.Delete("/1/2")
if m, e := json.Marshal(webPath); e != nil {
t.Fatal(e)
} else if string(m) != `{"path":"/","same":null,"next":{"path":"/1","same":{"path":"/1","same":null,"next":null},"next":null}}` {