]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Implement pending requests using BSI
authorMatt Joiner <anacrolix@gmail.com>
Sun, 10 Oct 2021 00:19:08 +0000 (11:19 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Tue, 19 Oct 2021 03:08:56 +0000 (14:08 +1100)
pending-requests.go
torrent.go

index 4afefe65027c1d087e1c8f3d26de13b4da73a92e..9e2d120095e855277c4769816e71519a239ad22b 100644 (file)
@@ -1,34 +1,50 @@
 package torrent
 
+import (
+       rbm "github.com/RoaringBitmap/roaring"
+       roaring "github.com/RoaringBitmap/roaring/BitSliceIndexing"
+)
+
 type pendingRequests struct {
-       m map[RequestIndex]int
+       m *roaring.BSI
 }
 
-func (p pendingRequests) Dec(r RequestIndex) {
-       p.m[r]--
-       n := p.m[r]
-       if n == 0 {
-               delete(p.m, r)
-       }
-       if n < 0 {
-               panic(n)
+func (p *pendingRequests) Dec(r RequestIndex) {
+       _r := uint64(r)
+       prev, _ := p.m.GetValue(_r)
+       if prev <= 0 {
+               panic(prev)
        }
+       p.m.SetValue(_r, prev-1)
 }
 
-func (p pendingRequests) Inc(r RequestIndex) {
-       p.m[r]++
+func (p *pendingRequests) Inc(r RequestIndex) {
+       _r := uint64(r)
+       prev, _ := p.m.GetValue(_r)
+       p.m.SetValue(_r, prev+1)
 }
 
 func (p *pendingRequests) Init() {
-       p.m = make(map[RequestIndex]int)
+       p.m = roaring.NewDefaultBSI()
+}
+
+var allBits rbm.Bitmap
+
+func init() {
+       allBits.AddRange(0, rbm.MaxRange)
 }
 
 func (p *pendingRequests) AssertEmpty() {
-       if len(p.m) != 0 {
+       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]
+func (p *pendingRequests) Get(r RequestIndex) int {
+       count, _ := p.m.GetValue(uint64(r))
+       return int(count)
 }
index d2187a054f4633b209d5f17702722a0e17ebdb6e..33376f6c0bf2c880eb213a33b11e697d003f19f7 100644 (file)
@@ -1405,7 +1405,7 @@ func (t *Torrent) deletePeerConn(c *PeerConn) (ret bool) {
        }
        torrent.Add("deleted connections", 1)
        c.deleteAllRequests()
-       if t.numActivePeers() == 0 {
+       if t.numActivePeers() == 0 && t.haveInfo() {
                t.assertNoPendingRequests()
        }
        return