client.go | 4 ++-- connection.go | 2 +- internal/pieceordering/pieceordering.go | 23 ++++++++++++----------- internal/pieceordering/pieceordering_test.go | 38 ++++++++++++++++++++++++++++++++------ diff --git a/client.go b/client.go index 83f3e5fa82a742019f3df4baffbad3ac5355f77f..b69ea07f8df7670e8312c7a4506792b726373d45 100644 --- a/client.go +++ b/client.go @@ -2019,7 +2019,7 @@ delete(t.Pieces[req.Index].PendingChunkSpecs, req.chunkSpec) me.dataReady(t, req) if len(t.Pieces[req.Index].PendingChunkSpecs) == 0 { for _, c := range t.Conns { - c.pieceRequestOrder.RemovePiece(int(req.Index)) + c.pieceRequestOrder.DeletePiece(int(req.Index)) } me.queuePieceCheck(t, req.Index) } @@ -2117,7 +2117,7 @@ if r.Index == piece { panic("wat") } } - conn.pieceRequestOrder.RemovePiece(int(piece)) + conn.pieceRequestOrder.DeletePiece(int(piece)) } if t.wantPiece(int(piece)) && conn.PeerHasPiece(piece) { conn.pendPiece(int(piece), t.Pieces[piece].Priority) diff --git a/connection.go b/connection.go index 42b1a75d005e5e94309073b061f27e617efb293d..ea4295dee483d14be9e9d3bc25a4abaf57e8f4cf 100644 --- a/connection.go +++ b/connection.go @@ -89,7 +89,7 @@ } func (cn *connection) pendPiece(piece int, priority piecePriority) { if priority == piecePriorityNone { - cn.pieceRequestOrder.RemovePiece(piece) + cn.pieceRequestOrder.DeletePiece(piece) return } key := cn.piecePriorities[piece] diff --git a/internal/pieceordering/pieceordering.go b/internal/pieceordering/pieceordering.go index 71816fc6e9a5f80059d67e008d131ef6df593581..60ab0c77a3a75d4dd357dfd300235a766603bb3b 100644 --- a/internal/pieceordering/pieceordering.go +++ b/internal/pieceordering/pieceordering.go @@ -22,9 +22,7 @@ if existingKey, ok := me.pieceKeys[piece]; ok { if existingKey == key { return } - if me.sl.Remove(existingKey).Value.(int) != piece { - panic("piecekeys map lied to us") - } + me.removeKeyPiece(existingKey, piece) } me.sl.Insert(key, piece) if me.pieceKeys == nil { @@ -33,18 +31,21 @@ } me.pieceKeys[piece] = key } -func (me *Instance) RemovePiece(piece int) { +func (me *Instance) removeKeyPiece(key, piece int) { + if me.sl.Remove(key).Value.(int) != piece { + panic("piecekeys map lied to us") + } + if me.sl.Remove(key) != nil { + panic("duplicate key") + } +} + +func (me *Instance) DeletePiece(piece int) { key, ok := me.pieceKeys[piece] if !ok { return } - el := me.sl.Remove(key) - if el == nil { - panic("element not present but should be") - } - if me.sl.Remove(key) != nil { - panic("duplicate key") - } + me.removeKeyPiece(key, piece) delete(me.pieceKeys, piece) } diff --git a/internal/pieceordering/pieceordering_test.go b/internal/pieceordering/pieceordering_test.go index 30c9c01c3c81e7725183ee9f44323b6e1c317225..59849ba6bc59f3aa4ce2906695a7bc526e5f5466 100644 --- a/internal/pieceordering/pieceordering_test.go +++ b/internal/pieceordering/pieceordering_test.go @@ -4,16 +4,26 @@ import ( "testing" ) +func instanceSlice(i *Instance) (sl []int) { + for e := i.First(); e != nil; e = e.Next() { + sl = append(sl, e.Piece()) + } + return +} + func checkOrder(t *testing.T, i *Instance, pp []int) { + fatal := func() { + t.Fatalf("have %v, expected %v", instanceSlice(i), pp) + } e := i.First() for _, p := range pp { if p != e.Piece() { - t.FailNow() + fatal() } e = e.Next() } if e != nil { - t.FailNow() + fatal() } } @@ -24,10 +34,26 @@ i.SetPiece(1, 0) checkOrder(t, i, []int{1, 0}) i.SetPiece(1, 2) checkOrder(t, i, []int{0, 1}) - i.RemovePiece(1) + i.DeletePiece(1) checkOrder(t, i, []int{0}) - i.RemovePiece(2) - i.RemovePiece(1) + i.DeletePiece(2) + i.DeletePiece(1) checkOrder(t, i, []int{0}) - i.RemovePiece(0) + i.DeletePiece(0) + checkOrder(t, i, nil) + i.SetPiece(2, 1) + i.SetPiece(1, 1) + i.SetPiece(3, 1) + checkOrder(t, i, []int{3, 1, 2}) + // Move a piece that isn't the youngest in a key. + i.SetPiece(1, -1) + checkOrder(t, i, []int{1, 3, 2}) + i.DeletePiece(2) + i.DeletePiece(3) + i.DeletePiece(1) + checkOrder(t, i, nil) + i.DeletePiece(2) + i.DeletePiece(3) + i.DeletePiece(1) + checkOrder(t, i, nil) }