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  }