From: qydysky Date: Wed, 3 Feb 2021 12:14:14 +0000 (+0800) Subject: 临时kv会话模块 X-Git-Tag: v.0.3.11 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=4ef84af5cb765ea8f64bc80e445dad41ce16971f;p=part%2F.git 临时kv会话模块 --- diff --git a/idpool/Idpool.go b/idpool/Idpool.go index 6a25bab..ad35a47 100644 --- a/idpool/Idpool.go +++ b/idpool/Idpool.go @@ -26,7 +26,8 @@ func New() (*Idpool) { } } -func (t *Idpool) Get() (o Id) { +func (t *Idpool) Get() (o *Id) { + o = new(Id) o.item = t.pool.Get() o.Id = uintptr(unsafe.Pointer(&o.item)) t.Lock() @@ -35,9 +36,10 @@ func (t *Idpool) Get() (o Id) { return } -func (t *Idpool) Put(i Id) { +func (t *Idpool) Put(i *Id) { if i.item == nil {return} t.pool.Put(i.item) + i.item = nil t.Lock() t.sum -= 1 t.Unlock() diff --git a/idpool/Idpool_test.go b/idpool/Idpool_test.go index ee8e856..43ffd68 100644 --- a/idpool/Idpool_test.go +++ b/idpool/Idpool_test.go @@ -11,6 +11,7 @@ func Test(t *testing.T){ t.Log(a.Id,a.item,pool.Len()) t.Log(b.Id,b.item) pool.Put(a) + pool.Put(a) t.Log(a.Id,a.item,pool.Len()) t.Log(b.Id,b.item) a = pool.Get() diff --git a/session/Session.go b/session/Session.go deleted file mode 100644 index 0de4574..0000000 --- a/session/Session.go +++ /dev/null @@ -1,73 +0,0 @@ -package part - -import ( - "time" - "errors" - "strconv" -) - -type session struct { - SumInSecond int64 - Timeout int64 - session_now int64 - session_rand int64 - session_ks map[string]string - session_kt map[string]int64 - session_stop chan bool -} - -func Session(SumInSecond,Timeout int64) (*session,error) { - if SumInSecond == 0 {return &session{},errors.New("SumInTimeout == 0")} - if Timeout == 0 {return &session{},errors.New("Timeout == 0")} - - s := new(session) - - if s.session_now == 0 { - s.session_rand = 1 - s.session_ks = make(map[string]string) - s.session_kt = make(map[string]int64) - s.session_stop = make(chan bool,1) - s.SumInSecond = SumInSecond - s.Timeout = Timeout - go func(){ - for{ - s.session_now = time.Now().Unix() - time.Sleep(time.Second) - } - }() - } - - return s,nil -} - -func (s *session) Set(key string) (val string) { - - s.session_stop <- true - - if s.session_rand >= s.SumInSecond {s.session_rand = 1}else{s.session_rand += 1} - - t := strconv.FormatInt(s.session_rand, 10) - s.session_ks[t] = key - s.session_kt[t] = s.session_now - - <-s.session_stop - return t -} - -func (s *session) Get(val string) (ok bool,key string){ - - K, oks := s.session_ks[val] - if !oks {return false,""} - T, _ := s.session_kt[val] - - return s.session_now-T <= s.Timeout, K -} - -func (s *session) Check(val string,key string) bool { - ok,k := s.Get(val) - return ok && k == key -} - -func (s *session) Buf() (int64,int) { - return s.session_now,len(s.session_ks) -} diff --git a/tmplKV/tmplK.go b/tmplKV/tmplK.go new file mode 100644 index 0000000..d476c8e --- /dev/null +++ b/tmplKV/tmplK.go @@ -0,0 +1,100 @@ +package part + +import ( + "time" + "sync" + idpool "github.com/qydysky/part/idpool" +) + +type tmplK struct { + SumInDruation int64 + Druation int64 + now int64 + pool *idpool.Idpool + kvt_map map[string]tmplK_item + sync.Mutex +} + +type tmplK_item struct { + kv uintptr + kt int64 + uid *idpool.Id +} + +func New_tmplK(SumInDruation,Druation int64) (*tmplK) { + + s := &tmplK{ + SumInDruation:SumInDruation, + Druation:Druation, + kvt_map:make(map[string]tmplK_item), + pool:idpool.New(), + } + go func(){ + ticker := time.NewTicker(time.Second) + for{ + s.now = (<- ticker.C).Unix() + go func(){ + tmp := make(map[string]tmplK_item) + for k,v := range s.kvt_map {tmp[k] = v} + s.Lock() + s.kvt_map = tmp + s.Unlock() + }() + } + }() + + return s +} + +func (s *tmplK) Set(key string) (id uintptr) { + + if tmp, oks := s.kvt_map[key];oks { + defer s.pool.Put(tmp.uid)//在取得新Id后才put回 + } else if s.SumInDruation >= 0 && s.pool.Len() >= uint(s.SumInDruation){//不为无限&&达到限额 随机替代 + for oldkey,item := range s.kvt_map { + s.Lock() + s.kvt_map[key] = tmplK_item{ + kv: item.kv, + kt: s.now, + uid: item.uid, + } + delete(s.kvt_map,oldkey) + s.Unlock() + return item.kv + } + } + + Uid := s.pool.Get() + + s.Lock() + s.kvt_map[key] = tmplK_item{ + kv: Uid.Id, + kt: s.now, + uid: Uid, + } + s.Unlock() + + return Uid.Id +} + +func (s *tmplK) Get(key string) (isLive bool,id uintptr){ + tmp, ok := s.kvt_map[key] + id = tmp.kv + isLive = ok && s.Druation < 0 || s.now - tmp.kt <= s.Druation + if !isLive && ok { + s.pool.Put(tmp.uid) + s.Lock() + delete(s.kvt_map,key) + s.Unlock() + } + return +} + +func (s *tmplK) Check(key string,id uintptr) bool { + ok,k := s.Get(key) + return ok && k == id +} + +func (s *tmplK) Buf() (int64,int) { + return s.now,len(s.kvt_map) +} diff --git a/tmplKV/tmplK_test.go b/tmplKV/tmplK_test.go new file mode 100644 index 0000000..3c65465 --- /dev/null +++ b/tmplKV/tmplK_test.go @@ -0,0 +1,23 @@ +package part + +import ( + "time" + "testing" +) + +func Test_tmplK(t *testing.T) { + s := New_tmplK(1e6, 5) + k1 := s.Set("a") + if !s.Check("a",k1) {t.Error(`no match1`)} + k2 := s.Set("a") + if s.Check("a",k1) {t.Error(`match`)} + if !s.Check("a",k2) {t.Error(`no match2`)} + if o,p := s.Buf();p != 1 || o - time.Now().Unix() > 1{t.Error(`sum/time no match1`)} + + time.Sleep(time.Second*time.Duration(5)) + + if s.Check("a",k1) {t.Error(`no TO1`)} + if s.Check("a",k1) {t.Error(`no TO2`)} + + if o,p := s.Buf();p != 0 || o - time.Now().Unix() > 1{t.Error(`sum/time no match2`)} +} diff --git a/tmplKV/tmplV.go b/tmplKV/tmplV.go new file mode 100644 index 0000000..f89cb2f --- /dev/null +++ b/tmplKV/tmplV.go @@ -0,0 +1,97 @@ +package part + +import ( + "time" + "sync" + idpool "github.com/qydysky/part/idpool" +) + +type tmplV struct { + SumInDruation int64 + Druation int64 + now int64 + pool *idpool.Idpool + kvt_map map[uintptr]tmplV_item + sync.Mutex +} + +type tmplV_item struct { + kv string + kt int64 + uid *idpool.Id +} + +func New_tmplV(SumInDruation,Druation int64) (*tmplV) { + + s := &tmplV{ + SumInDruation:SumInDruation, + Druation:Druation, + kvt_map:make(map[uintptr]tmplV_item), + pool:idpool.New(), + } + go func(){ + ticker := time.NewTicker(time.Second) + for{ + s.now = (<- ticker.C).Unix() + go func(){ + tmp := make(map[uintptr]tmplV_item) + for k,v := range s.kvt_map {tmp[k] = v} + s.Lock() + s.kvt_map = tmp + s.Unlock() + }() + } + }() + + return s +} + +func (s *tmplV) Set(contect string) (key uintptr) { + + if s.SumInDruation >= 0 && s.pool.Len() >= uint(s.SumInDruation) {//不为无限&&达到限额 随机替代 + for key,item := range s.kvt_map { + s.Lock() + s.kvt_map[key] = tmplV_item{ + kv: contect, + kt: s.now, + uid: item.uid, + } + s.Unlock() + return key + } + } + + Uid := s.pool.Get() + + s.Lock() + s.kvt_map[Uid.Id] = tmplV_item{ + kv: contect, + kt: s.now, + uid: Uid, + } + s.Unlock() + + return Uid.Id +} + +func (s *tmplV) Get(key uintptr) (isLive bool,contect string){ + K, ok := s.kvt_map[key] + contect = K.kv + isLive = ok && s.Druation < 0 || s.now - K.kt <= s.Druation + if !isLive && ok { + s.pool.Put(K.uid) + s.Lock() + delete(s.kvt_map,key) + s.Unlock() + } + return +} + +func (s *tmplV) Check(key uintptr,contect string) bool { + ok,k := s.Get(key) + return ok && k == contect +} + +func (s *tmplV) Buf() (int64,int) { + return s.now,len(s.kvt_map) +} diff --git a/session/Session_test.go b/tmplKV/tmplV_test.go similarity index 71% rename from session/Session_test.go rename to tmplKV/tmplV_test.go index 2104be6..f87fb5c 100644 --- a/session/Session_test.go +++ b/tmplKV/tmplV_test.go @@ -5,9 +5,8 @@ import ( "testing" ) -func Test_session(t *testing.T) { - s,e := Session(1e6, 1) - if e != nil {return} +func Test_tmplV(t *testing.T) { + s := New_tmplV(1e6, 1) v := s.Set("a") if o,p := s.Buf();p != 1 || o - time.Now().Unix() > 1{return} if ok,k := s.Get(v);!ok || k != "a" {return}