github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/system/mqtt/admin/types.go (about) 1 // This file is part of the Smart Home 2 // Program complex distribution https://github.com/e154/smart-home 3 // Copyright (C) 2016-2023, Filippov Alex 4 // 5 // This library is free software: you can redistribute it and/or 6 // modify it under the terms of the GNU Lesser General Public 7 // License as published by the Free Software Foundation; either 8 // version 3 of the License, or (at your option) any later version. 9 // 10 // This library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 // Library General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public 16 // License along with this library. If not, see 17 // <https://www.gnu.org/licenses/>. 18 19 package admin 20 21 import ( 22 "container/list" 23 "errors" 24 "time" 25 26 "github.com/DrmagicE/gmqtt/server" 27 ) 28 29 var ( 30 // ErrInvalidTopicFilter ... 31 ErrInvalidTopicFilter = errors.New("invalid topic filter") 32 // ErrInvalidQos ... 33 ErrInvalidQos = errors.New("invalid Qos") 34 // ErrInvalidClientID ... 35 ErrInvalidClientID = errors.New("invalid clientID") 36 // ErrInvalidUtf8String ... 37 ErrInvalidUtf8String = errors.New("invalid utf-8 string") 38 // ErrNotFound ... 39 ErrNotFound = errors.New("not found") 40 ) 41 42 // Indexer provides a index for a ordered list that supports queries in O(1). 43 // All methods are not concurrency-safe. 44 type Indexer struct { 45 index map[string]*list.Element 46 rows *list.List 47 } 48 49 // NewIndexer is the constructor of Indexer. 50 func NewIndexer() *Indexer { 51 return &Indexer{ 52 index: make(map[string]*list.Element), 53 rows: list.New(), 54 } 55 } 56 57 // Set sets the value for the id. 58 func (i *Indexer) Set(id string, value interface{}) { 59 if e, ok := i.index[id]; ok { 60 e.Value = value 61 } else { 62 elem := i.rows.PushBack(value) 63 i.index[id] = elem 64 } 65 } 66 67 // Remove removes and returns the value for the given id. 68 // Return nil if not found. 69 func (i *Indexer) Remove(id string) *list.Element { 70 elem := i.index[id] 71 if elem != nil { 72 i.rows.Remove(elem) 73 } 74 delete(i.index, id) 75 return elem 76 } 77 78 // GetByID returns the value for the given id. 79 // Return nil if not found. 80 // Notice: Any access to the return *list.Element also require the mutex, 81 // because the Set method can modify the Value for *list.Element when updating the Value for the same id. 82 // If the caller needs the Value in *list.Element, it must get the Value before the next Set is called. 83 func (i *Indexer) GetByID(id string) *list.Element { 84 return i.index[id] 85 } 86 87 // Iterate iterates at most n elements in the list begin from offset. 88 // Notice: Any access to the *list.Element in fn also require the mutex, 89 // because the Set method can modify the Value for *list.Element when updating the Value for the same id. 90 // If the caller needs the Value in *list.Element, it must get the Value before the next Set is called. 91 func (i *Indexer) Iterate(fn func(elem *list.Element), offset, n uint) { 92 if i.rows.Len() < int(offset) { 93 return 94 } 95 var j uint 96 for e := i.rows.Front(); e != nil; e = e.Next() { 97 if j >= offset && j < offset+n { 98 fn(e) 99 } 100 if j == offset+n { 101 break 102 } 103 j++ 104 } 105 } 106 107 // Len returns the length of list. 108 func (i *Indexer) Len() int { 109 return i.rows.Len() 110 } 111 112 // GetOffsetN ... 113 func GetOffsetN(page, pageSize uint) (offset, n uint) { 114 offset = (page - 1) * pageSize 115 n = pageSize 116 return 117 } 118 119 const ( 120 // Online ... 121 Online = "online" 122 // Offline ... 123 Offline = "offline" 124 ) 125 126 func statusText(client server.Client) string { 127 if client.SessionInfo().IsExpired(time.Now()) { 128 return Online 129 } else { 130 return Offline 131 } 132 }