piece-request-order.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package requestStrategy
  2. import (
  3. g "github.com/anacrolix/generics"
  4. "github.com/anacrolix/torrent/metainfo"
  5. )
  6. type Btree interface {
  7. Delete(pieceRequestOrderItem)
  8. Add(pieceRequestOrderItem)
  9. Scan(func(pieceRequestOrderItem) bool)
  10. }
  11. func NewPieceOrder(btree Btree, cap int) *PieceRequestOrder {
  12. return &PieceRequestOrder{
  13. tree: btree,
  14. keys: make(map[PieceRequestOrderKey]PieceRequestOrderState, cap),
  15. }
  16. }
  17. type PieceRequestOrder struct {
  18. tree Btree
  19. keys map[PieceRequestOrderKey]PieceRequestOrderState
  20. }
  21. type PieceRequestOrderKey struct {
  22. Index int
  23. InfoHash metainfo.Hash
  24. }
  25. type PieceRequestOrderState struct {
  26. Availability int
  27. Priority piecePriority
  28. Partial bool
  29. }
  30. type pieceRequestOrderItem struct {
  31. key PieceRequestOrderKey
  32. state PieceRequestOrderState
  33. }
  34. func (me *pieceRequestOrderItem) Less(otherConcrete *pieceRequestOrderItem) bool {
  35. return pieceOrderLess(me, otherConcrete).Less()
  36. }
  37. // Returns the old state if the key was already present.
  38. func (me *PieceRequestOrder) Add(
  39. key PieceRequestOrderKey,
  40. state PieceRequestOrderState,
  41. ) (old g.Option[PieceRequestOrderState]) {
  42. if old.Value, old.Ok = me.keys[key]; old.Ok {
  43. if state == old.Value {
  44. return
  45. }
  46. me.tree.Delete(pieceRequestOrderItem{key, old.Value})
  47. }
  48. me.tree.Add(pieceRequestOrderItem{key, state})
  49. me.keys[key] = state
  50. return
  51. }
  52. func (me *PieceRequestOrder) Update(
  53. key PieceRequestOrderKey,
  54. state PieceRequestOrderState,
  55. ) {
  56. if !me.Add(key, state).Ok {
  57. panic("key should have been added already")
  58. }
  59. }
  60. func (me *PieceRequestOrder) existingItemForKey(key PieceRequestOrderKey) pieceRequestOrderItem {
  61. return pieceRequestOrderItem{
  62. key: key,
  63. state: me.keys[key],
  64. }
  65. }
  66. func (me *PieceRequestOrder) Delete(key PieceRequestOrderKey) bool {
  67. state, ok := me.keys[key]
  68. if !ok {
  69. return false
  70. }
  71. me.tree.Delete(pieceRequestOrderItem{key, state})
  72. delete(me.keys, key)
  73. return true
  74. }
  75. func (me *PieceRequestOrder) Len() int {
  76. return len(me.keys)
  77. }