1 // Implements ordering of torrent piece indices for such purposes as download
8 "github.com/ryszard/goskiplist/skiplist"
11 // Maintains piece integers by their ascending assigned keys.
12 type Instance struct {
13 // Contains the ascending priority keys. The keys contain a slice of piece
16 // Maps from piece index back to its key, so that it can be remove
17 // efficiently from the skip list.
21 func New() *Instance {
23 sl: skiplist.NewIntMap(),
27 // Add the piece with the given key. If the piece is already present, change
29 func (me *Instance) SetPiece(piece, key int) {
30 if existingKey, ok := me.pieceKeys[piece]; ok {
31 if existingKey == key {
34 me.removeKeyPiece(existingKey, piece)
37 if exItem, ok := me.sl.Get(key); ok {
38 itemSl = exItem.([]int)
40 me.sl.Set(key, append(itemSl, piece))
41 if me.pieceKeys == nil {
42 me.pieceKeys = make(map[int]int)
44 me.pieceKeys[piece] = key
48 // Shuffle the piece indices that share a given key.
49 func (me *Instance) shuffleItem(key int) {
50 _item, ok := me.sl.Get(key)
56 j := i + rand.Intn(len(item)-i)
57 item[i], item[j] = item[j], item[i]
62 func (me *Instance) removeKeyPiece(key, piece int) {
63 item, ok := me.sl.Get(key)
65 panic("no item for key")
67 itemSl := item.([]int)
68 for i, piece1 := range itemSl {
70 itemSl[i] = itemSl[len(itemSl)-1]
71 itemSl = itemSl[:len(itemSl)-1]
78 me.sl.Set(key, itemSl)
82 func (me *Instance) DeletePiece(piece int) {
83 key, ok := me.pieceKeys[piece]
87 me.removeKeyPiece(key, piece)
88 delete(me.pieceKeys, piece)
91 // Returns the piece with the lowest key.
92 func (me *Instance) First() Element {
93 i := me.sl.SeekToFirst()
97 return &element{i, i.Value().([]int)}
100 func (me *Instance) Empty() bool {
101 return me.sl.Len() == 0
104 type Element interface {
109 type element struct {
114 func (e *element) Next() Element {
123 e.sl = e.i.Value().([]int)
127 func (e *element) Piece() int {