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  }