github.com/turingchain2020/turingchain@v1.1.21/common/skiplist/queue.go (about) 1 package skiplist 2 3 import ( 4 "container/list" 5 6 "github.com/turingchain2020/turingchain/types" 7 ) 8 9 //Scorer 接口实现 Value的 Score 功能 10 type Scorer interface { 11 GetScore() int64 12 Hash() []byte 13 //在score相同情况下的比较 14 Compare(Scorer) int 15 //占用字节大小 16 ByteSize() int64 17 } 18 19 // Queue skiplist 实现的一个 按照score 排序的队列,score相同的按照元素到的先后排序 20 type Queue struct { 21 txMap map[string]*list.Element 22 txList *SkipList 23 maxsize int64 24 cacheBytes int64 25 } 26 27 // NewQueue 创建队列 28 func NewQueue(maxsize int64) *Queue { 29 return &Queue{ 30 txMap: make(map[string]*list.Element), 31 txList: NewSkipList(&SkipValue{Score: -1, Value: nil}), 32 maxsize: maxsize, 33 } 34 } 35 36 /* 37 为了处理相同 Score 的问题,需要一个队列保存相同 Score 下面的交易 38 */ 39 func (cache *Queue) insertSkipValue(item Scorer) *list.Element { 40 skvalue := cache.CreateSkipValue(item) 41 value := cache.txList.Find(skvalue) 42 var txlist *list.List 43 if value == nil { 44 txlist = list.New() 45 skvalue.Value = txlist 46 cache.txList.Insert(skvalue) 47 } else { 48 txlist = value.Value.(*list.List) 49 } 50 return txlist.PushBack(item) 51 } 52 53 func (cache *Queue) deleteSkipValue(item *list.Element) error { 54 if item == nil { 55 return nil 56 } 57 skvalue := cache.CreateSkipValue(item.Value.(Scorer)) 58 value := cache.txList.Find(skvalue) 59 var txlist *list.List 60 if value == nil { 61 return types.ErrNotFound 62 } 63 txlist = value.Value.(*list.List) 64 txlist.Remove(item) 65 if txlist.Len() == 0 { 66 cache.txList.Delete(value) 67 } 68 return nil 69 } 70 71 //CreateSkipValue 创建一个 仅仅有 score 的Value 72 func (cache *Queue) CreateSkipValue(item Scorer) *SkipValue { 73 skvalue := &SkipValue{Score: item.GetScore()} 74 return skvalue 75 } 76 77 //MaxSize 最大的cache数量 78 func (cache *Queue) MaxSize() int64 { 79 return cache.maxsize 80 } 81 82 //Exist 是否存在 83 func (cache *Queue) Exist(hash string) bool { 84 _, exists := cache.txMap[hash] 85 return exists 86 } 87 88 //GetItem 获取数据通过 key 89 func (cache *Queue) GetItem(hash string) (Scorer, error) { 90 if k, exist := cache.txMap[hash]; exist { 91 return k.Value.(Scorer), nil 92 } 93 return nil, types.ErrNotFound 94 } 95 96 //GetCacheBytes get cache byte size 97 func (cache *Queue) GetCacheBytes() int64 { 98 return cache.cacheBytes 99 } 100 101 //Insert Scorer item to queue 102 func (cache *Queue) Insert(hash string, item Scorer) { 103 cache.cacheBytes += item.ByteSize() 104 cache.txMap[hash] = cache.insertSkipValue(item) 105 } 106 107 // Push item 到队列中,如果插入的数据优先级比队列中更大,那么弹出优先级最小的,然后插入这个数据,否则报错 108 func (cache *Queue) Push(item Scorer) error { 109 hash := item.Hash() 110 if cache.Exist(string(hash)) { 111 return types.ErrTxExist 112 } 113 sv := cache.CreateSkipValue(item) 114 if int64(cache.Size()) >= cache.maxsize { 115 tail := cache.Last() 116 lasthash := string(tail.Hash()) 117 cmp := sv.Compare(cache.CreateSkipValue(tail)) 118 if cmp == Big || (cmp == Equal && item.Compare(tail) == Big) { 119 err := cache.Remove(lasthash) 120 if err != nil { 121 return err 122 } 123 } else { 124 return types.ErrMemFull 125 } 126 } 127 cache.Insert(string(hash), item) 128 return nil 129 } 130 131 // Remove 删除数据 132 func (cache *Queue) Remove(hash string) error { 133 elm, ok := cache.txMap[hash] 134 if !ok { 135 return types.ErrNotFound 136 } 137 //保证txMap中先删除,这个用于计数 138 delete(cache.txMap, hash) 139 err := cache.deleteSkipValue(elm) 140 if err != nil { 141 println("queue_data_crash") 142 return err 143 } 144 cache.cacheBytes -= elm.Value.(Scorer).ByteSize() 145 return nil 146 } 147 148 // Size 数据总数 149 func (cache *Queue) Size() int { 150 return len(cache.txMap) 151 } 152 153 //Last 取出最后一个交易 154 func (cache *Queue) Last() Scorer { 155 if cache.Size() == 0 { 156 return nil 157 } 158 tailqueue := cache.txList.GetIterator().Last() 159 tail := tailqueue.Value.(*list.List).Back().Value.(Scorer) 160 return tail 161 } 162 163 //First 取出第一个交易 164 func (cache *Queue) First() Scorer { 165 if cache.Size() == 0 { 166 return nil 167 } 168 tailqueue := cache.txList.GetIterator().First() 169 tail := tailqueue.Value.(*list.List).Front().Value.(Scorer) 170 return tail 171 } 172 173 // Walk 遍历整个队列 174 func (cache *Queue) Walk(count int, cb func(value Scorer) bool) { 175 i := 0 176 cache.txList.Walk(func(item interface{}) bool { 177 l := item.(*list.List) 178 for e := l.Front(); e != nil; e = e.Next() { 179 if !cb(e.Value.(Scorer)) { 180 return false 181 } 182 i++ 183 if i == count { 184 return false 185 } 186 } 187 return true 188 }) 189 }