]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Merge branch 'udp-tracker-no-dial' into te
authorMatt Joiner <anacrolix@gmail.com>
Mon, 29 Nov 2021 00:19:54 +0000 (11:19 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Mon, 29 Nov 2021 00:19:54 +0000 (11:19 +1100)
16 files changed:
go.mod
go.sum
peerconn.go
pending-requests.go
pending-requests_test.go
request-strategy/order.go
request-strategy/order_test.go
request-strategy/torrent.go
requesting.go
storage/sqlite/deprecated.go
storage/sqlite/direct.go
storage/sqlite/sqlite-storage_test.go
torrent.go
worse-conns.go [new file with mode: 0644]
worse-conns_test.go [new file with mode: 0644]
worst_conns.go [deleted file]

diff --git a/go.mod b/go.mod
index b3cc2cf9faac4a379e3e07236ea860536ac3e898..105f0e9add7abbb31e450536462356da4685598e 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,6 @@ module github.com/anacrolix/torrent
 go 1.17
 
 require (
-       crawshaw.io/sqlite v0.3.3-0.20210127221821-98b1f83c5508
        github.com/RoaringBitmap/roaring v0.9.4
        github.com/alexflint/go-arg v1.4.2
        github.com/anacrolix/args v0.4.1-0.20211104085705-59f0fe94eb8f
@@ -18,7 +17,7 @@ require (
        github.com/anacrolix/missinggo/perf v1.0.0
        github.com/anacrolix/missinggo/v2 v2.5.2
        github.com/anacrolix/multiless v0.2.0
-       github.com/anacrolix/squirrel v0.1.1-0.20210914065657-81bc5ecdc43a
+       github.com/anacrolix/squirrel v0.2.1-0.20211119092713-2efaee06d169
        github.com/anacrolix/sync v0.4.0
        github.com/anacrolix/tagflag v1.3.0
        github.com/anacrolix/upnp v0.1.2-0.20200416075019-5e9378ed1425
@@ -47,10 +46,9 @@ require (
        golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect
        golang.org/x/sys v0.0.0-20211023085530-d6a326fbbf70 // indirect
        golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac
+       zombiezen.com/go/sqlite v0.8.0
 )
 
-require zombiezen.com/go/sqlite v0.8.0
-
 require (
        github.com/alexflint/go-scalar v1.1.0 // indirect
        github.com/anacrolix/mmsg v1.0.0 // indirect
@@ -82,8 +80,9 @@ require (
        golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // 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.3 // indirect
+       modernc.org/libc v1.11.82 // indirect
        modernc.org/mathutil v1.4.1 // indirect
        modernc.org/memory v1.0.5 // indirect
-       modernc.org/sqlite v1.13.0 // indirect
+       // https://gitlab.com/cznic/sqlite/-/issues/77#note_744477407
+       modernc.org/sqlite v1.14.2-0.20211125151325-d4ed92c0a70f // indirect
 )
diff --git a/go.sum b/go.sum
index 5cbe92e5d399767b6a7f4424cf22564a0d2af113..6701323af50e47f129f6dedf735ed1e34c8a6af7 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -34,10 +34,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
 cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
-crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797 h1:yDf7ARQc637HoxDho7xjqdvO5ZA2Yb+xzv/fOnnvZzw=
 crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797/go.mod h1:sXBiorCo8c46JlQV3oXPKINnZ8mcqnye1EkVkqsectk=
 crawshaw.io/sqlite v0.3.2/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4=
-crawshaw.io/sqlite v0.3.3-0.20210127221821-98b1f83c5508 h1:fILCBBFnjnrQ0whVJlGhfv1E/QiaFDNtGFBObEVRnYg=
 crawshaw.io/sqlite v0.3.3-0.20210127221821-98b1f83c5508/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4=
 dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
@@ -167,8 +165,9 @@ github.com/anacrolix/multiless v0.2.0 h1:HtGBBOQcHaJM59RP3ysITId7AMIgiNF4xJucaFh
 github.com/anacrolix/multiless v0.2.0/go.mod h1:TrCLEZfIDbMVfLoQt5tOoiBS/uq4y8+ojuEVVvTNPX4=
 github.com/anacrolix/publicip v0.2.0/go.mod h1:67G1lVkLo8UjdEcJkwScWVTvlJ35OCDsRJoWXl/wi4g=
 github.com/anacrolix/squirrel v0.1.0/go.mod h1:YzgVvikMdFD441oTWlNG189bpKabO9Sbf3uCSVgca04=
-github.com/anacrolix/squirrel v0.1.1-0.20210914065657-81bc5ecdc43a h1:8LAUQgDPqnzuF/WrGQzTY6i+bVO/FpA90Hi6jXA+2vQ=
 github.com/anacrolix/squirrel v0.1.1-0.20210914065657-81bc5ecdc43a/go.mod h1:YzgVvikMdFD441oTWlNG189bpKabO9Sbf3uCSVgca04=
+github.com/anacrolix/squirrel v0.2.1-0.20211119092713-2efaee06d169 h1:OFAU76N1th2tW6EGi/FvT7EYP+xcpgN9ZqA8/rE09/0=
+github.com/anacrolix/squirrel v0.2.1-0.20211119092713-2efaee06d169/go.mod h1:dJyE7VefQvX0KAKMkOQDGOVEs91a+LvXQ2BjEKl/DIw=
 github.com/anacrolix/stm v0.1.0/go.mod h1:ZKz7e7ERWvP0KgL7WXfRjBXHNRhlVRlbBQecqFtPq+A=
 github.com/anacrolix/stm v0.1.1-0.20191106051447-e749ba3531cf/go.mod h1:zoVQRvSiGjGoTmbM0vSLIiaKjWtNPeTvXUSdJQA4hsg=
 github.com/anacrolix/stm v0.2.0/go.mod h1:zoVQRvSiGjGoTmbM0vSLIiaKjWtNPeTvXUSdJQA4hsg=
@@ -515,7 +514,9 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
 github.com/mattn/go-sqlite3 v1.7.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v1.13.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
 github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
+github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
 github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
@@ -1027,6 +1028,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211023085530-d6a326fbbf70 h1:SeSEfdIxyvwGJliREIJhRPPXvW6sDlLT+UQ3B0hD0NA=
 golang.org/x/sys v0.0.0-20211023085530-d6a326fbbf70/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
@@ -1229,22 +1231,94 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
 honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
+modernc.org/cc/v3 v3.31.5-0.20210308123301-7a3e9dab9009/go.mod h1:0R6jl1aZlIl2avnYfbfHBS1QB6/f+16mihBObaBC878=
 modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
 modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
 modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
 modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/ccgo/v3 v3.9.0/go.mod h1:nQbgkn8mwzPdp4mm6BT6+p85ugQ7FrGgIcYaE7nSrpY=
 modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60=
 modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw=
 modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI=
 modernc.org/ccgo/v3 v3.11.1/go.mod h1:lWHxfsn13L3f7hgGsGlU28D9eUOf6y3ZYHKoPaKU0ag=
 modernc.org/ccgo/v3 v3.11.2/go.mod h1:6kii3AptTDI+nUrM9RFBoIEUEisSWCbdczD9ZwQH2FE=
+modernc.org/ccgo/v3 v3.11.3/go.mod h1:0oHunRBMBiXOKdaglfMlRPBALQqsfrCKXgw9okQ3GEw=
+modernc.org/ccgo/v3 v3.12.4/go.mod h1:Bk+m6m2tsooJchP/Yk5ji56cClmN6R1cqc9o/YtbgBQ=
+modernc.org/ccgo/v3 v3.12.6/go.mod h1:0Ji3ruvpFPpz+yu+1m0wk68pdr/LENABhTrDkMDWH6c=
+modernc.org/ccgo/v3 v3.12.8/go.mod h1:Hq9keM4ZfjCDuDXxaHptpv9N24JhgBZmUG5q60iLgUo=
+modernc.org/ccgo/v3 v3.12.11/go.mod h1:0jVcmyDwDKDGWbcrzQ+xwJjbhZruHtouiBEvDfoIsdg=
+modernc.org/ccgo/v3 v3.12.14/go.mod h1:GhTu1k0YCpJSuWwtRAEHAol5W7g1/RRfS4/9hc9vF5I=
+modernc.org/ccgo/v3 v3.12.18/go.mod h1:jvg/xVdWWmZACSgOiAhpWpwHWylbJaSzayCqNOJKIhs=
+modernc.org/ccgo/v3 v3.12.20/go.mod h1:aKEdssiu7gVgSy/jjMastnv/q6wWGRbszbheXgWRHc8=
+modernc.org/ccgo/v3 v3.12.21/go.mod h1:ydgg2tEprnyMn159ZO/N4pLBqpL7NOkJ88GT5zNU2dE=
+modernc.org/ccgo/v3 v3.12.22/go.mod h1:nyDVFMmMWhMsgQw+5JH6B6o4MnZ+UQNw1pp52XYFPRk=
+modernc.org/ccgo/v3 v3.12.25/go.mod h1:UaLyWI26TwyIT4+ZFNjkyTbsPsY3plAEB6E7L/vZV3w=
+modernc.org/ccgo/v3 v3.12.29/go.mod h1:FXVjG7YLf9FetsS2OOYcwNhcdOLGt8S9bQ48+OP75cE=
+modernc.org/ccgo/v3 v3.12.36/go.mod h1:uP3/Fiezp/Ga8onfvMLpREq+KUjUmYMxXPO8tETHtA8=
+modernc.org/ccgo/v3 v3.12.38/go.mod h1:93O0G7baRST1vNj4wnZ49b1kLxt0xCW5Hsa2qRaZPqc=
+modernc.org/ccgo/v3 v3.12.43/go.mod h1:k+DqGXd3o7W+inNujK15S5ZYuPoWYLpF5PYougCmthU=
+modernc.org/ccgo/v3 v3.12.46/go.mod h1:UZe6EvMSqOxaJ4sznY7b23/k13R8XNlyWsO5bAmSgOE=
+modernc.org/ccgo/v3 v3.12.47/go.mod h1:m8d6p0zNps187fhBwzY/ii6gxfjob1VxWb919Nk1HUk=
+modernc.org/ccgo/v3 v3.12.50/go.mod h1:bu9YIwtg+HXQxBhsRDE+cJjQRuINuT9PUK4orOco/JI=
+modernc.org/ccgo/v3 v3.12.51/go.mod h1:gaIIlx4YpmGO2bLye04/yeblmvWEmE4BBBls4aJXFiE=
+modernc.org/ccgo/v3 v3.12.53/go.mod h1:8xWGGTFkdFEWBEsUmi+DBjwu/WLy3SSOrqEmKUjMeEg=
+modernc.org/ccgo/v3 v3.12.54/go.mod h1:yANKFTm9llTFVX1FqNKHE0aMcQb1fuPJx6p8AcUx+74=
+modernc.org/ccgo/v3 v3.12.55/go.mod h1:rsXiIyJi9psOwiBkplOaHye5L4MOOaCjHg1Fxkj7IeU=
+modernc.org/ccgo/v3 v3.12.56/go.mod h1:ljeFks3faDseCkr60JMpeDb2GSO3TKAmrzm7q9YOcMU=
+modernc.org/ccgo/v3 v3.12.57/go.mod h1:hNSF4DNVgBl8wYHpMvPqQWDQx8luqxDnNGCMM4NFNMc=
+modernc.org/ccgo/v3 v3.12.60/go.mod h1:k/Nn0zdO1xHVWjPYVshDeWKqbRWIfif5dtsIOCUVMqM=
+modernc.org/ccgo/v3 v3.12.65/go.mod h1:D6hQtKxPNZiY6wDBtehSGKFKmyXn53F8nGTpH+POmS4=
+modernc.org/ccgo/v3 v3.12.66/go.mod h1:jUuxlCFZTUZLMV08s7B1ekHX5+LIAurKTTaugUr/EhQ=
+modernc.org/ccgo/v3 v3.12.67/go.mod h1:Bll3KwKvGROizP2Xj17GEGOTrlvB1XcVaBrC90ORO84=
+modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3cQ=
 modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
+modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
+modernc.org/libc v1.8.0/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
 modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
 modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q=
 modernc.org/libc v1.11.0/go.mod h1:2lOfPmj7cz+g1MrPNmX65QCzVxgNq2C5o0jdLY2gAYg=
 modernc.org/libc v1.11.2/go.mod h1:ioIyrl3ETkugDO3SGZ+6EOKvlP3zSOycUETe4XM4n8M=
-modernc.org/libc v1.11.3 h1:q//spBhqp23lC/if8/o8hlyET57P8mCZqrqftzT2WmY=
 modernc.org/libc v1.11.3/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU=
+modernc.org/libc v1.11.5/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU=
+modernc.org/libc v1.11.6/go.mod h1:ddqmzR6p5i4jIGK1d/EiSw97LBcE3dK24QEwCFvgNgE=
+modernc.org/libc v1.11.11/go.mod h1:lXEp9QOOk4qAYOtL3BmMve99S5Owz7Qyowzvg6LiZso=
+modernc.org/libc v1.11.13/go.mod h1:ZYawJWlXIzXy2Pzghaf7YfM8OKacP3eZQI81PDLFdY8=
+modernc.org/libc v1.11.16/go.mod h1:+DJquzYi+DMRUtWI1YNxrlQO6TcA5+dRRiq8HWBWRC8=
+modernc.org/libc v1.11.19/go.mod h1:e0dgEame6mkydy19KKaVPBeEnyJB4LGNb0bBH1EtQ3I=
+modernc.org/libc v1.11.24/go.mod h1:FOSzE0UwookyT1TtCJrRkvsOrX2k38HoInhw+cSCUGk=
+modernc.org/libc v1.11.26/go.mod h1:SFjnYi9OSd2W7f4ct622o/PAYqk7KHv6GS8NZULIjKY=
+modernc.org/libc v1.11.27/go.mod h1:zmWm6kcFXt/jpzeCgfvUNswM0qke8qVwxqZrnddlDiE=
+modernc.org/libc v1.11.28/go.mod h1:Ii4V0fTFcbq3qrv3CNn+OGHAvzqMBvC7dBNyC4vHZlg=
+modernc.org/libc v1.11.31/go.mod h1:FpBncUkEAtopRNJj8aRo29qUiyx5AvAlAxzlx9GNaVM=
+modernc.org/libc v1.11.34/go.mod h1:+Tzc4hnb1iaX/SKAutJmfzES6awxfU1BPvrrJO0pYLg=
+modernc.org/libc v1.11.37/go.mod h1:dCQebOwoO1046yTrfUE5nX1f3YpGZQKNcITUYWlrAWo=
+modernc.org/libc v1.11.39/go.mod h1:mV8lJMo2S5A31uD0k1cMu7vrJbSA3J3waQJxpV4iqx8=
+modernc.org/libc v1.11.42/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ=
+modernc.org/libc v1.11.44/go.mod h1:KFq33jsma7F5WXiYelU8quMJasCCTnHK0mkri4yPHgA=
+modernc.org/libc v1.11.45/go.mod h1:Y192orvfVQQYFzCNsn+Xt0Hxt4DiO4USpLNXBlXg/tM=
+modernc.org/libc v1.11.47/go.mod h1:tPkE4PzCTW27E6AIKIR5IwHAQKCAtudEIeAV1/SiyBg=
+modernc.org/libc v1.11.49/go.mod h1:9JrJuK5WTtoTWIFQ7QjX2Mb/bagYdZdscI3xrvHbXjE=
+modernc.org/libc v1.11.51/go.mod h1:R9I8u9TS+meaWLdbfQhq2kFknTW0O3aw3kEMqDDxMaM=
+modernc.org/libc v1.11.53/go.mod h1:5ip5vWYPAoMulkQ5XlSJTy12Sz5U6blOQiYasilVPsU=
+modernc.org/libc v1.11.54/go.mod h1:S/FVnskbzVUrjfBqlGFIPA5m7UwB3n9fojHhCNfSsnw=
+modernc.org/libc v1.11.55/go.mod h1:j2A5YBRm6HjNkoSs/fzZrSxCuwWqcMYTDPLNx0URn3M=
+modernc.org/libc v1.11.56/go.mod h1:pakHkg5JdMLt2OgRadpPOTnyRXm/uzu+Yyg/LSLdi18=
+modernc.org/libc v1.11.58/go.mod h1:ns94Rxv0OWyoQrDqMFfWwka2BcaF6/61CqJRK9LP7S8=
+modernc.org/libc v1.11.70/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw=
+modernc.org/libc v1.11.71/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw=
+modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0=
+modernc.org/libc v1.11.82 h1:CSl/6n4odvPYWKKqBtFb8e0ZWVTjxDqwxTjaoee9V7E=
+modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI=
 modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
 modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
 modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
@@ -1254,12 +1328,20 @@ modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
 modernc.org/memory v1.0.5 h1:XRch8trV7GgvTec2i7jc33YlUI0RKVDBvZ5eZ5m8y14=
 modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM=
 modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
-modernc.org/sqlite v1.13.0 h1:cwhUj0jTBgPjk/demWheV+T6xi6ifTfsGIFKFq0g3Ck=
+modernc.org/sqlite v1.10.0/go.mod h1:PGzq6qlhyYjL6uVbSgS6WoF7ZopTW/sI7+7p+mb4ZVU=
 modernc.org/sqlite v1.13.0/go.mod h1:2qO/6jZJrcQaxFUHxOwa6Q6WfiGSsiVj6GXX0Ker+Jg=
+modernc.org/sqlite v1.14.2-0.20211125151325-d4ed92c0a70f h1:yQwkmqKCIgLzFIfjfPfZAAxLZernckpo7zGTv37Ahv0=
+modernc.org/sqlite v1.14.2-0.20211125151325-d4ed92c0a70f/go.mod h1:YT5XFRKOueohjppHO4cHb54eQlnaUGsZMHoryaCpNo4=
+modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
 modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
+modernc.org/tcl v1.5.0/go.mod h1:gb57hj4pO8fRrK54zveIfFXBaMHK3SKJNWcmRw1cRzc=
 modernc.org/tcl v1.5.9/go.mod h1:bcwjvBJ2u0exY6K35eAmxXBBij5kXb1dHlAWmfhqThE=
+modernc.org/tcl v1.8.13/go.mod h1:V+q/Ef0IJaNUSECieLU4o+8IScapxnMyFV6i/7uQlAY=
 modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
+modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
+modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
 modernc.org/z v1.1.2/go.mod h1:sj9T1AGBG0dm6SCVzldPOHWrif6XBpooJtbttMn1+Js=
+modernc.org/z v1.2.19/go.mod h1:+ZpP0pc4zz97eukOzW3xagV/lS82IpPN9NGG5pNF9vY=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
@@ -1267,5 +1349,6 @@ sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
 sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
 sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
 sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
+zombiezen.com/go/sqlite v0.2.0/go.mod h1:VyBqNtpcF4vdvYgdwTSHJlwxyvTYCDQAZM9/qmGPyLg=
 zombiezen.com/go/sqlite v0.8.0 h1:fgbFUVLlkDnrNjWV4M28QbHjHvNMCoKjDMWiUYs0R2g=
 zombiezen.com/go/sqlite v0.8.0/go.mod h1:EMNzBZwTS5Yg6nwujgJdEo0brNm2a6f8Y4zoGiWZ5RU=
index 0646946174a5c1603352d7d500b850782a852401..003e32c57821fd135613ca370219170bb3828405 100644 (file)
@@ -1525,7 +1525,7 @@ func (cn *Peer) netGoodPiecesDirtied() int64 {
 
 func (c *Peer) peerHasWantedPieces() bool {
        if all, _ := c.peerHasAllPieces(); all {
-               return !c.t.haveAllPieces()
+               return !c.t.haveAllPieces() && !c.t._pendingPieces.IsEmpty()
        }
        if !c.t.haveInfo() {
                return !c.peerPieces().IsEmpty()
index 3d0e4ca61670197b989ce64629ccbb10ac2723fb..dcb1faf19fb95b206aff8862b276a08b87213a7a 100644 (file)
@@ -1,33 +1,50 @@
 package torrent
 
+import (
+       rbm "github.com/RoaringBitmap/roaring"
+       roaring "github.com/RoaringBitmap/roaring/BitSliceIndexing"
+)
+
 type pendingRequests struct {
-       m []int
+       m *roaring.BSI
 }
 
 func (p *pendingRequests) Dec(r RequestIndex) {
-       prev := p.m[r]
+       _r := uint64(r)
+       prev, _ := p.m.GetValue(_r)
        if prev <= 0 {
                panic(prev)
        }
-       p.m[r]--
+       p.m.SetValue(_r, prev-1)
 }
 
 func (p *pendingRequests) Inc(r RequestIndex) {
-       p.m[r]++
+       _r := uint64(r)
+       prev, _ := p.m.GetValue(_r)
+       p.m.SetValue(_r, prev+1)
 }
 
 func (p *pendingRequests) Init(maxIndex RequestIndex) {
-       p.m = make([]int, maxIndex)
+       p.m = roaring.NewDefaultBSI()
+}
+
+var allBits rbm.Bitmap
+
+func init() {
+       allBits.AddRange(0, rbm.MaxRange)
 }
 
 func (p *pendingRequests) AssertEmpty() {
-       for _, count := range p.m {
-               if count != 0 {
-                       panic(count)
-               }
+       if p.m == nil {
+               panic(p.m)
+       }
+       sum, _ := p.m.Sum(&allBits)
+       if sum != 0 {
+               panic(sum)
        }
 }
 
 func (p *pendingRequests) Get(r RequestIndex) int {
-       return p.m[r]
+       count, _ := p.m.GetValue(uint64(r))
+       return int(count)
 }
index 5f0debdca0408fe42926f1328627f286ca75e3bd..6c9572e0921088e16e39af71656b9bfa1dda2d4a 100644 (file)
@@ -1,19 +1,12 @@
 package torrent
 
-import (
-       "testing"
-
-       qt "github.com/frankban/quicktest"
-       "github.com/google/go-cmp/cmp"
-)
-
-// Ensure that cmp.Diff will detect errors as required.
-func TestPendingRequestsDiff(t *testing.T) {
-       var a, b pendingRequests
-       c := qt.New(t)
-       diff := func() string { return cmp.Diff(a.m, b.m) }
-       c.Check(diff(), qt.ContentEquals, "")
-       a.m = []int{1, 3}
-       b.m = []int{1, 2, 3}
-       c.Check(diff(), qt.Not(qt.Equals), "")
-}
+// // Ensure that cmp.Diff will detect errors as required.
+// func TestPendingRequestsDiff(t *testing.T) {
+//     var a, b pendingRequests
+//     c := qt.New(t)
+//     diff := func() string { return cmp.Diff(a.m, b.m) }
+//     c.Check(diff(), qt.ContentEquals, "")
+//     a.m = []int{1, 3}
+//     b.m = []int{1, 2, 3}
+//     c.Check(diff(), qt.Not(qt.Equals), "")
+// }
index 58d06b422553f698cad657e918ffee5340319664..1e4228680c303e56cc087c0281e0fa9ac508d43a 100644 (file)
@@ -2,12 +2,10 @@ package request_strategy
 
 import (
        "bytes"
-       "fmt"
        "sort"
        "sync"
 
        "github.com/anacrolix/multiless"
-       "github.com/anacrolix/torrent/metainfo"
        "github.com/anacrolix/torrent/storage"
 
        "github.com/anacrolix/torrent/types"
@@ -165,54 +163,6 @@ type Input struct {
        MaxUnverifiedBytes int64
 }
 
-// TODO: We could do metainfo requests here.
-func Run(input Input) map[PeerId]PeerNextRequestState {
-       var requestPieces []requestablePiece
-       GetRequestablePieces(input, func(t *Torrent, piece *Piece, pieceIndex int) {
-               requestPieces = append(requestPieces, requestablePiece{
-                       index:             pieceIndex,
-                       t:                 t,
-                       NumPendingChunks:  piece.NumPendingChunks,
-                       IterPendingChunks: piece.iterPendingChunksWrapper,
-                       alwaysReallocate:  piece.Priority >= types.PiecePriorityNext,
-               })
-       })
-       torrents := input.Torrents
-       allPeers := make(map[metainfo.Hash][]*requestsPeer, len(torrents))
-       for _, t := range torrents {
-               peers := make([]*requestsPeer, 0, len(t.Peers))
-               for _, p := range t.Peers {
-                       peers = append(peers, &requestsPeer{
-                               Peer: p,
-                       })
-               }
-               allPeers[t.InfoHash] = peers
-       }
-       for _, piece := range requestPieces {
-               for _, peer := range allPeers[piece.t.InfoHash] {
-                       if peer.canRequestPiece(piece.index) {
-                               peer.requestablePiecesRemaining++
-                       }
-               }
-       }
-       for _, piece := range requestPieces {
-               allocatePendingChunks(piece, allPeers[piece.t.InfoHash])
-       }
-       ret := make(map[PeerId]PeerNextRequestState)
-       for _, peers := range allPeers {
-               for _, rp := range peers {
-                       if rp.requestablePiecesRemaining != 0 {
-                               panic(rp.requestablePiecesRemaining)
-                       }
-                       if _, ok := ret[rp.Id]; ok {
-                               panic(fmt.Sprintf("duplicate peer id: %v", rp.Id))
-                       }
-                       ret[rp.Id] = rp.nextState
-               }
-       }
-       return ret
-}
-
 // Checks that a sorted peersForPiece slice makes sense.
 func ensureValidSortedPeersForPieceRequests(peers *peersForPieceSorter) {
        if !sort.IsSorted(peers) {
index ce4a4e1a6ca45912adf99b4c6097551065c3640a..bcac41d1b3b9289ef251d2855b1ca0b91bef39cf 100644 (file)
@@ -2,7 +2,6 @@ package request_strategy
 
 import (
        "encoding/gob"
-       "math"
        "testing"
 
        "github.com/RoaringBitmap/roaring"
@@ -55,261 +54,19 @@ var hasAllRequests = func() (all roaring.Bitmap) {
        return
 }()
 
-func TestStealingFromSlowerPeer(t *testing.T) {
-       c := qt.New(t)
-       basePeer := Peer{
-               MaxRequests:  math.MaxInt16,
-               DownloadRate: 2,
-       }
-       basePeer.Pieces.Add(0)
-       // Slower than the stealers, but has all requests already.
-       stealee := basePeer
-       stealee.DownloadRate = 1
-       stealee.ExistingRequests = hasAllRequests
-       stealee.Id = intPeerId(1)
-       firstStealer := basePeer
-       firstStealer.Id = intPeerId(2)
-       secondStealer := basePeer
-       secondStealer.Id = intPeerId(3)
-       results := Run(Input{Torrents: []Torrent{{
-               ChunksPerPiece: 9,
-               Pieces: []Piece{{
-                       Request:           true,
-                       NumPendingChunks:  5,
-                       IterPendingChunks: chunkIterRange(5),
-               }},
-               Peers: []Peer{
-                       stealee,
-                       firstStealer,
-                       secondStealer,
-               },
-       }}})
-
-       c.Assert(results, qt.HasLen, 3)
-       check := func(p PeerId, l uint64) {
-               addressableBm := results[p].Requests
-               c.Check(addressableBm.GetCardinality(), qt.ContentEquals, l)
-               c.Check(results[p].Interested, qt.Equals, l > 0)
-       }
-       check(stealee.Id, 1)
-       check(firstStealer.Id, 2)
-       check(secondStealer.Id, 2)
-}
-
 func checkNumRequestsAndInterest(c *qt.C, next PeerNextRequestState, num uint64, interest bool) {
        addressableBm := next.Requests
        c.Check(addressableBm.GetCardinality(), qt.ContentEquals, num)
        c.Check(next.Interested, qt.Equals, interest)
 }
 
-func TestStealingFromSlowerPeersBasic(t *testing.T) {
-       c := qt.New(t)
-       basePeer := Peer{
-               MaxRequests:  math.MaxInt16,
-               DownloadRate: 2,
-       }
-       basePeer.Pieces.Add(0)
-       stealee := basePeer
-       stealee.DownloadRate = 1
-       stealee.ExistingRequests = hasAllRequests
-       stealee.Id = intPeerId(1)
-       firstStealer := basePeer
-       firstStealer.Id = intPeerId(2)
-       secondStealer := basePeer
-       secondStealer.Id = intPeerId(3)
-       results := Run(Input{Torrents: []Torrent{{
-               ChunksPerPiece: 9,
-               Pieces: []Piece{{
-                       Request:           true,
-                       NumPendingChunks:  2,
-                       IterPendingChunks: chunkIter(0, 1),
-               }},
-               Peers: []Peer{
-                       stealee,
-                       firstStealer,
-                       secondStealer,
-               },
-       }}})
-
-       checkNumRequestsAndInterest(c, results[firstStealer.Id], 1, true)
-       checkNumRequestsAndInterest(c, results[secondStealer.Id], 1, true)
-       checkNumRequestsAndInterest(c, results[stealee.Id], 0, false)
-}
-
 func checkResultsRequestsLen(t *testing.T, reqs roaring.Bitmap, l uint64) {
        qt.Check(t, reqs.GetCardinality(), qt.Equals, l)
 }
 
-func TestPeerKeepsExistingIfReasonable(t *testing.T) {
-       c := qt.New(t)
-       basePeer := Peer{
-               MaxRequests:  math.MaxInt16,
-               DownloadRate: 2,
-       }
-       basePeer.Pieces.Add(0)
-       // Slower than the stealers, but has all requests already.
-       stealee := basePeer
-       stealee.DownloadRate = 1
-       keepReq := RequestIndex(0)
-       stealee.ExistingRequests = requestSetFromSlice(keepReq)
-       stealee.Id = intPeerId(1)
-       firstStealer := basePeer
-       firstStealer.Id = intPeerId(2)
-       secondStealer := basePeer
-       secondStealer.Id = intPeerId(3)
-       results := Run(Input{Torrents: []Torrent{{
-               ChunksPerPiece: 9,
-               Pieces: []Piece{{
-                       Request:           true,
-                       NumPendingChunks:  4,
-                       IterPendingChunks: chunkIter(0, 1, 3, 4),
-               }},
-               Peers: []Peer{
-                       stealee,
-                       firstStealer,
-                       secondStealer,
-               },
-       }}})
-
-       c.Assert(results, qt.HasLen, 3)
-       check := func(p PeerId, l uint64) {
-               checkResultsRequestsLen(t, results[p].Requests, l)
-               c.Check(results[p].Interested, qt.Equals, l > 0)
-       }
-       check(firstStealer.Id, 2)
-       check(secondStealer.Id, 1)
-       c.Check(
-               results[stealee.Id],
-               peerNextRequestStateChecker,
-               PeerNextRequestState{
-                       Interested: true,
-                       Requests:   requestSetFromSlice(keepReq),
-               },
-       )
-}
-
 var peerNextRequestStateChecker = qt.CmpEquals(
        cmp.Transformer(
                "bitmap",
                func(bm roaring.Bitmap) []uint32 {
                        return bm.ToArray()
                }))
-
-func TestDontStealUnnecessarily(t *testing.T) {
-       c := qt.New(t)
-       basePeer := Peer{
-               MaxRequests:  math.MaxInt16,
-               DownloadRate: 2,
-       }
-       basePeer.Pieces.AddRange(0, 5)
-       // Slower than the stealers, but has all requests already.
-       stealee := basePeer
-       stealee.DownloadRate = 1
-       r := func(i, c RequestIndex) RequestIndex {
-               return i*9 + c
-       }
-       keepReqs := requestSetFromSlice(
-               r(3, 2), r(3, 4), r(3, 6), r(3, 8),
-               r(4, 0), r(4, 1), r(4, 7), r(4, 8))
-       stealee.ExistingRequests = keepReqs
-       stealee.Id = intPeerId(1)
-       firstStealer := basePeer
-       firstStealer.Id = intPeerId(2)
-       secondStealer := basePeer
-       secondStealer.Id = intPeerId(3)
-       secondStealer.Pieces = roaring.Bitmap{}
-       secondStealer.Pieces.Add(1)
-       secondStealer.Pieces.Add(3)
-       results := Run(Input{Torrents: []Torrent{{
-               ChunksPerPiece: 9,
-               Pieces: []Piece{
-                       {
-                               Request:           true,
-                               NumPendingChunks:  0,
-                               IterPendingChunks: chunkIterRange(9),
-                       },
-                       {
-                               Request:           true,
-                               NumPendingChunks:  7,
-                               IterPendingChunks: chunkIterRange(7),
-                       },
-                       {
-                               Request:           true,
-                               NumPendingChunks:  0,
-                               IterPendingChunks: chunkIterRange(0),
-                       },
-                       {
-                               Request:           true,
-                               NumPendingChunks:  9,
-                               IterPendingChunks: chunkIterRange(9),
-                       },
-                       {
-                               Request:           true,
-                               NumPendingChunks:  9,
-                               IterPendingChunks: chunkIterRange(9),
-                       },
-               },
-               Peers: []Peer{
-                       firstStealer,
-                       stealee,
-                       secondStealer,
-               },
-       }}})
-
-       c.Assert(results, qt.HasLen, 3)
-       check := func(p PeerId, l uint64) {
-               checkResultsRequestsLen(t, results[p].Requests, l)
-               c.Check(results[p].Interested, qt.Equals, l > 0)
-       }
-       check(firstStealer.Id, 5)
-       check(secondStealer.Id, 7+9)
-       c.Check(
-               results[stealee.Id],
-               peerNextRequestStateChecker,
-               PeerNextRequestState{
-                       Interested: true,
-                       Requests:   requestSetFromSlice(r(4, 0), r(4, 1), r(4, 7), r(4, 8)),
-               },
-       )
-}
-
-// This tests a situation where multiple peers had the same existing request, due to "actual" and
-// "next" request states being out of sync. This reasonable occurs when a peer hasn't fully updated
-// its actual request state since the last request strategy run.
-func TestDuplicatePreallocations(t *testing.T) {
-       peer := func(id int, downloadRate float64) Peer {
-               p := Peer{
-                       ExistingRequests: hasAllRequests,
-                       MaxRequests:      2,
-                       Id:               intPeerId(id),
-                       DownloadRate:     downloadRate,
-               }
-               p.Pieces.AddRange(0, roaring.MaxRange)
-               return p
-       }
-       results := Run(Input{
-               Torrents: []Torrent{{
-                       ChunksPerPiece: 1,
-                       Pieces: []Piece{{
-                               Request:           true,
-                               NumPendingChunks:  1,
-                               IterPendingChunks: chunkIterRange(1),
-                       }, {
-                               Request:           true,
-                               NumPendingChunks:  1,
-                               IterPendingChunks: chunkIterRange(1),
-                       }},
-                       Peers: []Peer{
-                               // The second peer was be marked as the preallocation, clobbering the first. The
-                               // first peer is preferred, and the piece isn't striped, so it gets preallocated a
-                               // request, and then gets reallocated from the peer the same request.
-                               peer(1, 2),
-                               peer(2, 1),
-                       },
-               }},
-       })
-       c := qt.New(t)
-       req1 := results[intPeerId(1)].Requests
-       req2 := results[intPeerId(2)].Requests
-       c.Assert(uint64(2), qt.Equals, req1.GetCardinality()+req2.GetCardinality())
-}
index ff0261a3eb6944a3c99f6fee98f74cb23a54fee0..f547e1d780b4c7d38e9dbfb4a6cc73fc574143ff 100644 (file)
@@ -8,9 +8,7 @@ import (
 type Torrent struct {
        Pieces   []Piece
        Capacity storage.TorrentCapacity
-       // Unclosed Peers. Not necessary for getting requestable piece ordering.
-       Peers []Peer
-       // Some value that's unique and stable between runs. Could even use the infohash?
+       // Some value that's unique and stable between runs.
        InfoHash       metainfo.Hash
        ChunksPerPiece uint32
 
index 4a0f6a29a374370db9dfebaefba69658c294d8e9..06dc376c0602318ce8e75035e6e1e3b6207fba10 100644 (file)
@@ -44,28 +44,6 @@ func (cl *Client) getRequestStrategyInput() request_strategy.Input {
                                IterPendingChunks: &p.undirtiedChunksIter,
                        })
                }
-               t.iterPeers(func(p *Peer) {
-                       if p.closed.IsSet() {
-                               return
-                       }
-                       if p.piecesReceivedSinceLastRequestUpdate > p.maxPiecesReceivedBetweenRequestUpdates {
-                               p.maxPiecesReceivedBetweenRequestUpdates = p.piecesReceivedSinceLastRequestUpdate
-                       }
-                       p.piecesReceivedSinceLastRequestUpdate = 0
-                       rst.Peers = append(rst.Peers, request_strategy.Peer{
-                               Pieces:           *p.newPeerPieces(),
-                               MaxRequests:      p.nominalMaxRequests(),
-                               ExistingRequests: p.actualRequestState.Requests,
-                               Choking:          p.peerChoking,
-                               PieceAllowedFast: p.peerAllowedFast,
-                               DownloadRate:     p.downloadRate(),
-                               Age:              time.Since(p.completedHandshake),
-                               Id: peerId{
-                                       Peer: p,
-                                       ptr:  uintptr(unsafe.Pointer(p)),
-                               },
-                       })
-               })
                ts = append(ts, rst)
        }
        return request_strategy.Input{
index 5730f7793379b23745f69af59f918f655372afbe..a1b1df1482361cc4a42cae3894c23dbd3fcef251 100644 (file)
@@ -1,5 +1,3 @@
-//go:build cgo
-
 package sqliteStorage
 
 import (
index 3d51fd316b27385948feab321fc9015d48038c8d..02b4cd79f7333ee572bd827a525d33c3da84521a 100644 (file)
@@ -1,13 +1,10 @@
-//go:build cgo
-// +build cgo
-
 package sqliteStorage
 
 import (
        "io"
 
-       "crawshaw.io/sqlite"
        "github.com/anacrolix/squirrel"
+       "zombiezen.com/go/sqlite"
 
        "github.com/anacrolix/torrent/metainfo"
        "github.com/anacrolix/torrent/storage"
index 66293cfad3258172f8b75b2b77c2e2f46522a396..2116c01b35471f4d561eca691c15b35e82b04777 100644 (file)
@@ -1,6 +1,3 @@
-//go:build cgo
-// +build cgo
-
 package sqliteStorage
 
 import (
index cd8d273d4e2b117b142c4d6316c0b56337eed285..2550f539f944b11ad8370b0f70a72c6008625ee6 100644 (file)
@@ -28,7 +28,6 @@ import (
        "github.com/anacrolix/multiless"
        "github.com/anacrolix/sync"
        "github.com/davecgh/go-spew/spew"
-       "github.com/google/go-cmp/cmp"
        "github.com/pion/datachannel"
 
        "github.com/anacrolix/torrent/bencode"
@@ -258,8 +257,14 @@ func (t *Torrent) addrActive(addr string) bool {
 }
 
 func (t *Torrent) appendUnclosedConns(ret []*PeerConn) []*PeerConn {
+       return t.appendConns(ret, func(conn *PeerConn) bool {
+               return !conn.closed.IsSet()
+       })
+}
+
+func (t *Torrent) appendConns(ret []*PeerConn, f func(*PeerConn) bool) []*PeerConn {
        for c := range t.conns {
-               if !c.closed.IsSet() {
+               if f(c) {
                        ret = append(ret, c)
                }
        }
@@ -909,7 +914,7 @@ func (t *Torrent) hashPiece(piece pieceIndex) (ret metainfo.Hash, err error) {
 }
 
 func (t *Torrent) haveAnyPieces() bool {
-       return t._completedPieces.GetCardinality() != 0
+       return !t._completedPieces.IsEmpty()
 }
 
 func (t *Torrent) haveAllPieces() bool {
@@ -970,21 +975,23 @@ func (t *Torrent) wantPieceIndex(index pieceIndex) bool {
 // conns (which is a map).
 var peerConnSlices sync.Pool
 
+func getPeerConnSlice(cap int) []*PeerConn {
+       getInterface := peerConnSlices.Get()
+       if getInterface == nil {
+               return make([]*PeerConn, 0, cap)
+       } else {
+               return getInterface.([]*PeerConn)[:0]
+       }
+}
+
 // The worst connection is one that hasn't been sent, or sent anything useful for the longest. A bad
 // connection is one that usually sends us unwanted pieces, or has been in the worse half of the
 // established connections for more than a minute. This is O(n log n). If there was a way to not
 // consider the position of a conn relative to the total number, it could be reduced to O(n).
 func (t *Torrent) worstBadConn() (ret *PeerConn) {
-       var sl []*PeerConn
-       getInterface := peerConnSlices.Get()
-       if getInterface == nil {
-               sl = make([]*PeerConn, 0, len(t.conns))
-       } else {
-               sl = getInterface.([]*PeerConn)[:0]
-       }
-       sl = t.appendUnclosedConns(sl)
-       defer peerConnSlices.Put(sl)
-       wcs := worseConnSlice{sl}
+       wcs := worseConnSlice{conns: t.appendUnclosedConns(getPeerConnSlice(len(t.conns)))}
+       defer peerConnSlices.Put(wcs.conns)
+       wcs.initKeys()
        heap.Init(&wcs)
        for wcs.Len() != 0 {
                c := heap.Pop(&wcs).(*PeerConn)
@@ -1224,6 +1231,7 @@ func (t *Torrent) updatePieceCompletion(piece pieceIndex) bool {
        x := uint32(piece)
        if complete {
                t._completedPieces.Add(x)
+               t.openNewConns()
        } else {
                t._completedPieces.Remove(x)
        }
@@ -1381,20 +1389,20 @@ func (t *Torrent) assertPendingRequests() {
        if !check {
                return
        }
-       var actual pendingRequests
-       if t.haveInfo() {
-               actual.m = make([]int, t.numRequests())
-       }
-       t.iterPeers(func(p *Peer) {
-               p.actualRequestState.Requests.Iterate(func(x uint32) bool {
-                       actual.Inc(x)
-                       return true
-               })
-       })
-       diff := cmp.Diff(actual.m, t.pendingRequests.m)
-       if diff != "" {
-               panic(diff)
-       }
+       // var actual pendingRequests
+       // if t.haveInfo() {
+       //      actual.m = make([]int, t.numRequests())
+       // }
+       // t.iterPeers(func(p *Peer) {
+       //      p.actualRequestState.Requests.Iterate(func(x uint32) bool {
+       //              actual.Inc(x)
+       //              return true
+       //      })
+       // })
+       // diff := cmp.Diff(actual.m, t.pendingRequests.m)
+       // if diff != "" {
+       //      panic(diff)
+       // }
 }
 
 func (t *Torrent) dropConnection(c *PeerConn) {
@@ -1405,6 +1413,7 @@ func (t *Torrent) dropConnection(c *PeerConn) {
        }
 }
 
+// Peers as in contact information for dialing out.
 func (t *Torrent) wantPeers() bool {
        if t.closed.IsSet() {
                return false
@@ -1412,7 +1421,7 @@ func (t *Torrent) wantPeers() bool {
        if t.peers.Len() > t.cl.config.TorrentPeersLowWater {
                return false
        }
-       return t.needData() || t.seeding()
+       return t.wantConns()
 }
 
 func (t *Torrent) updateWantPeersEvent() {
@@ -1670,7 +1679,10 @@ func (t *Torrent) dhtAnnouncer(s DhtServer) {
                        if t.closed.IsSet() {
                                return
                        }
-                       if !t.wantPeers() {
+                       // We're also announcing ourselves as a listener, so we don't just want peer addresses.
+                       // TODO: We can include the announce_peer step depending on whether we can receive
+                       // inbound connections. We should probably only announce once every 15 mins too.
+                       if !t.wantConns() {
                                goto wait
                        }
                        // TODO: Determine if there's a listener on the port we're announcing.
@@ -1812,13 +1824,10 @@ func (t *Torrent) wantConns() bool {
        if t.closed.IsSet() {
                return false
        }
-       if !t.seeding() && !t.needData() {
+       if !t.needData() && (!t.seeding() || !t.haveAnyPieces()) {
                return false
        }
-       if len(t.conns) < t.maxEstablishedConns {
-               return true
-       }
-       return t.worstBadConn() != nil
+       return len(t.conns) < t.maxEstablishedConns || t.worstBadConn() != nil
 }
 
 func (t *Torrent) SetMaxEstablishedConns(max int) (oldMax int) {
@@ -1826,11 +1835,15 @@ func (t *Torrent) SetMaxEstablishedConns(max int) (oldMax int) {
        defer t.cl.unlock()
        oldMax = t.maxEstablishedConns
        t.maxEstablishedConns = max
-       wcs := slices.HeapInterface(slices.FromMapKeys(t.conns), func(l, r *PeerConn) bool {
-               return worseConn(&l.Peer, &r.Peer)
-       })
+       wcs := worseConnSlice{
+               conns: t.appendConns(nil, func(*PeerConn) bool {
+                       return true
+               }),
+       }
+       wcs.initKeys()
+       heap.Init(&wcs)
        for len(t.conns) > t.maxEstablishedConns && wcs.Len() > 0 {
-               t.dropConnection(wcs.Pop().(*PeerConn))
+               t.dropConnection(heap.Pop(&wcs).(*PeerConn))
        }
        t.openNewConns()
        return oldMax
diff --git a/worse-conns.go b/worse-conns.go
new file mode 100644 (file)
index 0000000..b0e0b4f
--- /dev/null
@@ -0,0 +1,114 @@
+package torrent
+
+import (
+       "container/heap"
+       "fmt"
+       "time"
+       "unsafe"
+
+       "github.com/anacrolix/multiless"
+       "github.com/anacrolix/sync"
+)
+
+type worseConnInput struct {
+       Useful              bool
+       LastHelpful         time.Time
+       CompletedHandshake  time.Time
+       GetPeerPriority     func() (peerPriority, error)
+       getPeerPriorityOnce sync.Once
+       peerPriority        peerPriority
+       peerPriorityErr     error
+       Pointer             uintptr
+}
+
+func (me *worseConnInput) doGetPeerPriority() {
+       me.peerPriority, me.peerPriorityErr = me.GetPeerPriority()
+}
+
+func (me *worseConnInput) doGetPeerPriorityOnce() {
+       me.getPeerPriorityOnce.Do(me.doGetPeerPriority)
+}
+
+func worseConnInputFromPeer(p *Peer) worseConnInput {
+       ret := worseConnInput{
+               Useful:             p.useful(),
+               LastHelpful:        p.lastHelpful(),
+               CompletedHandshake: p.completedHandshake,
+               Pointer:            uintptr(unsafe.Pointer(p)),
+               GetPeerPriority:    p.peerPriority,
+       }
+       return ret
+}
+
+func worseConn(_l, _r *Peer) bool {
+       // TODO: Use generics for ptr to
+       l := worseConnInputFromPeer(_l)
+       r := worseConnInputFromPeer(_r)
+       return l.Less(&r)
+}
+
+func (l *worseConnInput) Less(r *worseConnInput) bool {
+       less, ok := multiless.New().Bool(
+               l.Useful, r.Useful).CmpInt64(
+               l.LastHelpful.Sub(r.LastHelpful).Nanoseconds()).CmpInt64(
+               l.CompletedHandshake.Sub(r.CompletedHandshake).Nanoseconds()).LazySameLess(
+               func() (same, less bool) {
+                       l.doGetPeerPriorityOnce()
+                       if l.peerPriorityErr != nil {
+                               same = true
+                               return
+                       }
+                       r.doGetPeerPriorityOnce()
+                       if r.peerPriorityErr != nil {
+                               same = true
+                               return
+                       }
+                       same = l.peerPriority == r.peerPriority
+                       less = l.peerPriority < r.peerPriority
+                       return
+               }).Uintptr(
+               l.Pointer, r.Pointer,
+       ).LessOk()
+       if !ok {
+               panic(fmt.Sprintf("cannot differentiate %#v and %#v", l, r))
+       }
+       return less
+}
+
+type worseConnSlice struct {
+       conns []*PeerConn
+       keys  []worseConnInput
+}
+
+func (me *worseConnSlice) initKeys() {
+       me.keys = make([]worseConnInput, len(me.conns))
+       for i, c := range me.conns {
+               me.keys[i] = worseConnInputFromPeer(&c.Peer)
+       }
+}
+
+var _ heap.Interface = &worseConnSlice{}
+
+func (me worseConnSlice) Len() int {
+       return len(me.conns)
+}
+
+func (me worseConnSlice) Less(i, j int) bool {
+       return me.keys[i].Less(&me.keys[j])
+}
+
+func (me *worseConnSlice) Pop() interface{} {
+       i := len(me.conns) - 1
+       ret := me.conns[i]
+       me.conns = me.conns[:i]
+       return ret
+}
+
+func (me *worseConnSlice) Push(x interface{}) {
+       panic("not implemented")
+}
+
+func (me worseConnSlice) Swap(i, j int) {
+       me.conns[i], me.conns[j] = me.conns[j], me.conns[i]
+       me.keys[i], me.keys[j] = me.keys[j], me.keys[i]
+}
diff --git a/worse-conns_test.go b/worse-conns_test.go
new file mode 100644 (file)
index 0000000..3865b64
--- /dev/null
@@ -0,0 +1,44 @@
+package torrent
+
+import (
+       "testing"
+       "time"
+
+       qt "github.com/frankban/quicktest"
+)
+
+func TestWorseConnLastHelpful(t *testing.T) {
+       c := qt.New(t)
+       c.Check((&worseConnInput{}).Less(&worseConnInput{LastHelpful: time.Now()}), qt.IsTrue)
+       c.Check((&worseConnInput{}).Less(&worseConnInput{CompletedHandshake: time.Now()}), qt.IsTrue)
+       c.Check((&worseConnInput{LastHelpful: time.Now()}).Less(&worseConnInput{CompletedHandshake: time.Now()}), qt.IsFalse)
+       c.Check((&worseConnInput{
+               LastHelpful: time.Now(),
+       }).Less(&worseConnInput{
+               LastHelpful:        time.Now(),
+               CompletedHandshake: time.Now(),
+       }), qt.IsTrue)
+       now := time.Now()
+       c.Check((&worseConnInput{
+               LastHelpful: now,
+       }).Less(&worseConnInput{
+               LastHelpful:        now.Add(-time.Nanosecond),
+               CompletedHandshake: now,
+       }), qt.IsFalse)
+       readyPeerPriority := func() (peerPriority, error) {
+               return 42, nil
+       }
+       c.Check((&worseConnInput{
+               GetPeerPriority: readyPeerPriority,
+       }).Less(&worseConnInput{
+               GetPeerPriority: readyPeerPriority,
+               Pointer:         1,
+       }), qt.IsTrue)
+       c.Check((&worseConnInput{
+               GetPeerPriority: readyPeerPriority,
+               Pointer:         2,
+       }).Less(&worseConnInput{
+               GetPeerPriority: readyPeerPriority,
+               Pointer:         1,
+       }), qt.IsFalse)
+}
diff --git a/worst_conns.go b/worst_conns.go
deleted file mode 100644 (file)
index 00a9b90..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-package torrent
-
-import (
-       "container/heap"
-       "fmt"
-       "unsafe"
-
-       "github.com/anacrolix/multiless"
-)
-
-func worseConn(l, r *Peer) bool {
-       less, ok := multiless.New().Bool(
-               l.useful(), r.useful()).CmpInt64(
-               l.lastHelpful().Sub(r.lastHelpful()).Nanoseconds()).CmpInt64(
-               l.completedHandshake.Sub(r.completedHandshake).Nanoseconds()).LazySameLess(
-               func() (same, less bool) {
-                       lpp, err := l.peerPriority()
-                       if err != nil {
-                               same = true
-                               return
-                       }
-                       rpp, err := r.peerPriority()
-                       if err != nil {
-                               same = true
-                               return
-                       }
-                       return lpp == rpp, lpp < rpp
-               }).Uintptr(
-               uintptr(unsafe.Pointer(l)), uintptr(unsafe.Pointer(r)),
-       ).LessOk()
-       if !ok {
-               panic(fmt.Sprintf("cannot differentiate %#v and %#v", l, r))
-       }
-       return less
-}
-
-type worseConnSlice struct {
-       conns []*PeerConn
-}
-
-var _ heap.Interface = &worseConnSlice{}
-
-func (me worseConnSlice) Len() int {
-       return len(me.conns)
-}
-
-func (me worseConnSlice) Less(i, j int) bool {
-       return worseConn(&me.conns[i].Peer, &me.conns[j].Peer)
-}
-
-func (me *worseConnSlice) Pop() interface{} {
-       i := len(me.conns) - 1
-       ret := me.conns[i]
-       me.conns = me.conns[:i]
-       return ret
-}
-
-func (me *worseConnSlice) Push(x interface{}) {
-       me.conns = append(me.conns, x.(*PeerConn))
-}
-
-func (me worseConnSlice) Swap(i, j int) {
-       me.conns[i], me.conns[j] = me.conns[j], me.conns[i]
-}