Use tidwall/btree generics for piece request ordering

This commit is contained in:
Matt Joiner 2021-12-15 14:37:52 +11:00
parent c47e6b1f60
commit 62060fb897
4 changed files with 71 additions and 794 deletions

47
go.mod
View File

@ -1,6 +1,6 @@
module github.com/anacrolix/torrent module github.com/anacrolix/torrent
go 1.16 go 1.18
require ( require (
github.com/RoaringBitmap/roaring v0.9.4 github.com/RoaringBitmap/roaring v0.9.4
@ -36,11 +36,56 @@ require (
github.com/pion/webrtc/v3 v3.0.32 github.com/pion/webrtc/v3 v3.0.32
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
github.com/tidwall/btree v0.7.2-0.20211211132910-4215444137fc
go.etcd.io/bbolt v1.3.6 go.etcd.io/bbolt v1.3.6
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac
zombiezen.com/go/sqlite v0.8.0 zombiezen.com/go/sqlite v0.8.0
) )
require (
github.com/alexflint/go-scalar v1.0.0 // indirect
github.com/anacrolix/confluence v1.9.0 // indirect
github.com/anacrolix/mmsg v1.0.0 // indirect
github.com/anacrolix/stm v0.3.0 // indirect
github.com/benbjohnson/immutable v0.3.0 // indirect
github.com/bits-and-blooms/bitset v1.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/pion/dtls/v2 v2.0.9 // indirect
github.com/pion/ice/v2 v2.1.12 // indirect
github.com/pion/interceptor v0.0.15 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/mdns v0.0.5 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/rtcp v1.2.6 // indirect
github.com/pion/rtp v1.7.2 // indirect
github.com/pion/sctp v1.7.12 // indirect
github.com/pion/sdp/v3 v3.0.4 // indirect
github.com/pion/srtp/v2 v2.0.5 // indirect
github.com/pion/stun v0.3.5 // indirect
github.com/pion/transport v0.12.3 // indirect
github.com/pion/turn/v2 v2.0.5 // indirect
github.com/pion/udp v0.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/rogpeppe/go-internal v1.8.0 // indirect
github.com/rs/dnscache v0.0.0-20210201191234-295bba877686 // indirect
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 // indirect
golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e // indirect
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20211023085530-d6a326fbbf70 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
modernc.org/libc v1.11.82 // indirect
modernc.org/mathutil v1.4.1 // indirect
modernc.org/memory v1.0.5 // indirect
)
// https://gitlab.com/cznic/sqlite/-/issues/77#note_744477407 // https://gitlab.com/cznic/sqlite/-/issues/77#note_744477407
require modernc.org/sqlite v1.14.2-0.20211125151325-d4ed92c0a70f // indirect require modernc.org/sqlite v1.14.2-0.20211125151325-d4ed92c0a70f // indirect

781
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,6 @@ import (
"github.com/anacrolix/multiless" "github.com/anacrolix/multiless"
"github.com/anacrolix/torrent/metainfo" "github.com/anacrolix/torrent/metainfo"
"github.com/google/btree"
"github.com/anacrolix/torrent/types" "github.com/anacrolix/torrent/types"
) )
@ -52,8 +51,11 @@ func GetRequestablePieces(input Input, pro *PieceRequestOrder, f func(ih metainf
storageLeft = &cap storageLeft = &cap
} }
var allTorrentsUnverifiedBytes int64 var allTorrentsUnverifiedBytes int64
pro.tree.Ascend(func(i btree.Item) bool { min, ok := pro.tree.Min()
_i := i.(*pieceRequestOrderItem) if !ok {
return
}
pro.tree.Ascend(min, func(_i pieceRequestOrderItem) bool {
ih := _i.key.InfoHash ih := _i.key.InfoHash
var t Torrent = input.Torrent(ih) var t Torrent = input.Torrent(ih)
var piece Piece = t.Piece(_i.key.Index) var piece Piece = t.Piece(_i.key.Index)

View File

@ -4,19 +4,24 @@ import (
"fmt" "fmt"
"github.com/anacrolix/torrent/metainfo" "github.com/anacrolix/torrent/metainfo"
"github.com/google/btree" "github.com/tidwall/btree"
) )
func NewPieceOrder() *PieceRequestOrder { func NewPieceOrder() *PieceRequestOrder {
return &PieceRequestOrder{ return &PieceRequestOrder{
tree: btree.New(32), tree: btree.NewOptions(
func(a, b pieceRequestOrderItem) bool {
return a.Less(&b)
},
btree.Options{NoLocks: true}),
keys: make(map[PieceRequestOrderKey]PieceRequestOrderState), keys: make(map[PieceRequestOrderKey]PieceRequestOrderState),
} }
} }
type PieceRequestOrder struct { type PieceRequestOrder struct {
tree *btree.BTree tree *btree.BTree[pieceRequestOrderItem]
keys map[PieceRequestOrderKey]PieceRequestOrderState keys map[PieceRequestOrderKey]PieceRequestOrderState
pathHint btree.PathHint
} }
type PieceRequestOrderKey struct { type PieceRequestOrderKey struct {
@ -35,8 +40,7 @@ type pieceRequestOrderItem struct {
state PieceRequestOrderState state PieceRequestOrderState
} }
func (me *pieceRequestOrderItem) Less(other btree.Item) bool { func (me *pieceRequestOrderItem) Less(otherConcrete *pieceRequestOrderItem) bool {
otherConcrete := other.(*pieceRequestOrderItem)
return pieceOrderLess(me, otherConcrete).Less() return pieceOrderLess(me, otherConcrete).Less()
} }
@ -44,15 +48,17 @@ func (me *PieceRequestOrder) Add(key PieceRequestOrderKey, state PieceRequestOrd
if _, ok := me.keys[key]; ok { if _, ok := me.keys[key]; ok {
panic(key) panic(key)
} }
if me.tree.ReplaceOrInsert(&pieceRequestOrderItem{ if _, ok := me.tree.SetHint(pieceRequestOrderItem{
key: key, key: key,
state: state, state: state,
}) != nil { }, &me.pathHint); ok {
panic("shouldn't already have this") panic("shouldn't already have this")
} }
me.keys[key] = state me.keys[key] = state
} }
type PieceRequestOrderPathHint = btree.PathHint
func (me *PieceRequestOrder) Update(key PieceRequestOrderKey, state PieceRequestOrderState) { func (me *PieceRequestOrder) Update(key PieceRequestOrderKey, state PieceRequestOrderState) {
oldState, ok := me.keys[key] oldState, ok := me.keys[key]
if !ok { if !ok {
@ -65,11 +71,11 @@ func (me *PieceRequestOrder) Update(key PieceRequestOrderKey, state PieceRequest
key: key, key: key,
state: oldState, state: oldState,
} }
if me.tree.Delete(&item) == nil { if _, ok := me.tree.DeleteHint(item, &me.pathHint); !ok {
panic(fmt.Sprintf("%#v", key)) panic(fmt.Sprintf("%#v", key))
} }
item.state = state item.state = state
if me.tree.ReplaceOrInsert(&item) != nil { if _, ok := me.tree.SetHint(item, &me.pathHint); ok {
panic(key) panic(key)
} }
me.keys[key] = state me.keys[key] = state
@ -84,11 +90,10 @@ func (me *PieceRequestOrder) existingItemForKey(key PieceRequestOrderKey) pieceR
func (me *PieceRequestOrder) Delete(key PieceRequestOrderKey) { func (me *PieceRequestOrder) Delete(key PieceRequestOrderKey) {
item := me.existingItemForKey(key) item := me.existingItemForKey(key)
if me.tree.Delete(&item) == nil { if _, ok := me.tree.DeleteHint(item, &me.pathHint); !ok {
panic(key) panic(key)
} }
delete(me.keys, key) delete(me.keys, key)
// log.Printf("deleting %#v", key)
} }
func (me *PieceRequestOrder) Len() int { func (me *PieceRequestOrder) Len() int {