github.com/turingchain2020/turingchain@v1.1.21/common/db/list_helper.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package db 6 7 import ( 8 "bytes" 9 "fmt" 10 11 log "github.com/turingchain2020/turingchain/common/log/log15" 12 "github.com/turingchain2020/turingchain/types" 13 ) 14 15 //ListHelper ... 16 type ListHelper struct { 17 db IteratorDB 18 } 19 20 var listlog = log.New("module", "db.ListHelper") 21 22 //NewListHelper new 23 func NewListHelper(db IteratorDB) *ListHelper { 24 return &ListHelper{db: db} 25 } 26 27 //PrefixScan 前缀 28 func (db *ListHelper) PrefixScan(prefix []byte) [][]byte { 29 it := db.db.Iterator(prefix, nil, false) 30 defer it.Close() 31 32 resutls := newCollector(0) 33 for it.Rewind(); it.Valid(); it.Next() { 34 if it.Error() != nil { 35 listlog.Error("PrefixScan it.Value()", "error", it.Error()) 36 return nil 37 } 38 resutls.collect(it) 39 //blog.Debug("PrefixScan", "key", string(item.Key()), "value", string(value)) 40 } 41 return resutls.result() 42 } 43 44 //const 45 const ( 46 // direction 位模式指定direction 参数 47 // 000, <- 位从低位开始数 48 // 0位:direction ListDESC ListASC 49 // 1位:next key, 目前是一个特殊用途, 因为其他的都是返回value, 这个模式同时返回key, value。 不和其他位组合 50 // 2位: 为1返回时,返回 key+value,默认只返回value. 返回的是 types.Encode(types.KeyValue) 51 // 3位: 为1返回时,返回 key, 默认只返回value. 和 2位不可以同时设置为1 52 ListDESC = int32(0) // 0 53 ListASC = int32(1) // 1 54 ListSeek = int32(2) // 10 55 ListWithKey = int32(4) // 01xx 56 ListKeyOnly = int32(8) // 10xx 57 ) 58 59 //List 列表 60 func (db *ListHelper) List(prefix, key []byte, count, direction int32) [][]byte { 61 if len(key) != 0 && count == 1 && direction == ListSeek { 62 return db.nextKeyValue(prefix, key, count, direction) 63 } 64 65 if len(key) == 0 { 66 if isASC(direction) { 67 return db.IteratorScanFromFirst(prefix, count, direction) 68 } 69 return db.IteratorScanFromLast(prefix, count, direction) 70 } 71 return db.IteratorScan(prefix, key, count, direction) 72 } 73 74 //IteratorScan 迭代 75 func (db *ListHelper) IteratorScan(prefix []byte, key []byte, count int32, direction int32) [][]byte { 76 reserse := isRervese(direction) 77 it := db.db.Iterator(prefix, nil, reserse) 78 defer it.Close() 79 results := newCollector(direction) 80 81 var i int32 82 it.Seek(key) 83 if !it.Valid() { 84 listlog.Error("PrefixScan it.Value()", "error", it.Error()) 85 return nil 86 } 87 for it.Next(); it.Valid(); it.Next() { 88 if it.Error() != nil { 89 listlog.Error("PrefixScan it.Value()", "error", it.Error()) 90 return nil 91 } 92 if isdeleted(it.Value()) { 93 continue 94 } 95 results.collect(it) 96 i++ 97 if i == count { 98 break 99 } 100 } 101 return results.result() 102 } 103 104 func (db *ListHelper) iteratorScan(prefix []byte, count int32, reverse bool, direction int32) [][]byte { 105 it := db.db.Iterator(prefix, nil, reverse) 106 defer it.Close() 107 results := newCollector(direction) 108 var i int32 109 for it.Rewind(); it.Valid(); it.Next() { 110 if it.Error() != nil { 111 listlog.Error("PrefixScan it.Value()", "error", it.Error()) 112 return nil 113 } 114 if isdeleted(it.Value()) { 115 continue 116 } 117 results.collect(it) 118 i++ 119 if i == count { 120 break 121 } 122 } 123 return results.result() 124 } 125 126 //IteratorScanFromFirst 从头迭代 127 func (db *ListHelper) IteratorScanFromFirst(prefix []byte, count int32, direction int32) (values [][]byte) { 128 return db.iteratorScan(prefix, count, false, direction) 129 } 130 131 //IteratorScanFromLast 从尾迭代 132 func (db *ListHelper) IteratorScanFromLast(prefix []byte, count int32, direction int32) (values [][]byte) { 133 return db.iteratorScan(prefix, count, true, direction) 134 } 135 136 func isdeleted(d []byte) bool { 137 return len(d) == 0 138 } 139 140 //PrefixCount 前缀数量 141 func (db *ListHelper) PrefixCount(prefix []byte) (count int64) { 142 it := db.db.Iterator(prefix, nil, true) 143 defer it.Close() 144 for it.Rewind(); it.Valid(); it.Next() { 145 if it.Error() != nil { 146 listlog.Error("PrefixCount it.Value()", "error", it.Error()) 147 count = 0 148 return 149 } 150 if isdeleted(it.Value()) { 151 continue 152 } 153 count++ 154 } 155 return 156 } 157 158 //IteratorCallback 迭代回滚 159 func (db *ListHelper) IteratorCallback(start []byte, end []byte, count int32, direction int32, fn func(key, value []byte) bool) { 160 reserse := isRervese(direction) 161 it := db.db.Iterator(start, end, reserse) 162 defer it.Close() 163 var i int32 164 for it.Rewind(); it.Valid(); it.Next() { 165 value := it.Value() 166 if it.Error() != nil { 167 listlog.Error("PrefixScan it.Value()", "error", it.Error()) 168 return 169 } 170 if isdeleted(it.Value()) { 171 continue 172 } 173 key := it.Key() 174 //判断key 和 end 的关系 175 if end != nil { 176 cmp := bytes.Compare(key, end) 177 if !reserse && cmp > 0 { 178 fmt.Println("break1") 179 break 180 } 181 if reserse && cmp < 0 { 182 fmt.Println("break2") 183 break 184 } 185 } 186 if fn(cloneByte(key), cloneByte(value)) { 187 fmt.Println("break3") 188 break 189 } 190 //count 到数目了 191 i++ 192 if i == count { 193 fmt.Println("break4") 194 break 195 } 196 } 197 } 198 199 func isASC(direction int32) bool { 200 return direction&ListASC == ListASC 201 } 202 203 func isRervese(direction int32) bool { 204 return !isASC(direction) 205 } 206 207 //nextKeyValue List 时, count 为 1, deriction 为 ListSeek, key 非空, 取key 的下一个KV 208 func (db *ListHelper) nextKeyValue(prefix, key []byte, count, direction int32) (values [][]byte) { 209 it := db.db.Iterator(prefix, nil, true) 210 defer it.Close() 211 flag := it.Seek(key) 212 //判断是已经删除的key 213 for it.Valid() && isdeleted(it.Value()) { 214 it.Next() 215 if !it.Valid() { 216 return nil 217 } 218 } 219 if !flag || !bytes.Equal(key, it.Key()) { 220 it.Next() 221 if !it.Valid() { 222 return nil 223 } 224 for isdeleted(it.Value()) { 225 it.Next() 226 if !it.Valid() { 227 return nil 228 } 229 } 230 } 231 return [][]byte{cloneByte(it.Key()), cloneByte(it.Value())} 232 } 233 234 // collector 辅助收集list 的数据 235 type collector struct { 236 results [][]byte 237 direction int32 238 } 239 240 func newCollector(direction int32) *collector { 241 r := make([][]byte, 0) 242 return &collector{results: r, direction: direction} 243 } 244 245 func (c *collector) collect(it Iterator) { 246 //blog.Debug("collect", "key", string(item.Key()), "value", value) 247 if c.direction&ListKeyOnly != 0 { 248 c.results = append(c.results, cloneByte(it.Key())) 249 } else if c.direction&ListWithKey != 0 { 250 v := types.KeyValue{Key: cloneByte(it.Key()), Value: cloneByte(it.Value())} 251 c.results = append(c.results, types.Encode(&v)) 252 // c.results = append(c.results, Key: cloneByte(it.Key()), Value: cloneByte(it.Value())) 253 } else { 254 c.results = append(c.results, cloneByte(it.Value())) 255 } 256 } 257 258 func (c *collector) result() [][]byte { 259 if len(c.results) == 0 { 260 return nil 261 } 262 return c.results 263 }