]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Add internal panicif, check and nestedmaps packages
authorMatt Joiner <anacrolix@gmail.com>
Tue, 2 May 2023 07:47:47 +0000 (17:47 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Tue, 9 May 2023 05:46:52 +0000 (15:46 +1000)
Fuckit I'm sick of reinventing the wheel.

client.go
internal/check/check.go [new file with mode: 0644]
internal/check/check_testing.go [new file with mode: 0644]
internal/nestedmaps/nestedmaps.go [new file with mode: 0644]
internal/nestedmaps/nestedmaps_test.go [new file with mode: 0644]
internal/panicif/panicif.go [new file with mode: 0644]
torrent.go

index 342025ac554d6220931d1224dcf18ecb2d211812..eaf3d677f42d3562627c236c0f24f8c5816b3d38 100644 (file)
--- a/client.go
+++ b/client.go
@@ -37,6 +37,7 @@ import (
        "golang.org/x/time/rate"
 
        "github.com/anacrolix/torrent/bencode"
+       "github.com/anacrolix/torrent/internal/check"
        "github.com/anacrolix/torrent/internal/limiter"
        "github.com/anacrolix/torrent/iplist"
        "github.com/anacrolix/torrent/metainfo"
@@ -1075,10 +1076,8 @@ func (cl *Client) runHandshookConn(c *PeerConn, t *Torrent) error {
        return nil
 }
 
-const check = false
-
 func (p *Peer) initUpdateRequestsTimer() {
-       if check {
+       if check.Enabled {
                if p.updateRequestsTimer != nil {
                        panic(p.updateRequestsTimer)
                }
diff --git a/internal/check/check.go b/internal/check/check.go
new file mode 100644 (file)
index 0000000..aa75e59
--- /dev/null
@@ -0,0 +1,5 @@
+package check
+
+// A flag for doing extra checks at runtime that are potentially expensive. Should be enabled for
+// testing and debugging.
+var Enabled = false
diff --git a/internal/check/check_testing.go b/internal/check/check_testing.go
new file mode 100644 (file)
index 0000000..3ec404e
--- /dev/null
@@ -0,0 +1,11 @@
+//go:build go1.21
+
+package check
+
+import "testing"
+
+func init() {
+       if testing.Testing() {
+               Enabled = true
+       }
+}
diff --git a/internal/nestedmaps/nestedmaps.go b/internal/nestedmaps/nestedmaps.go
new file mode 100644 (file)
index 0000000..62ebdcc
--- /dev/null
@@ -0,0 +1,73 @@
+package nestedmaps
+
+type next[NK comparable, M ~map[NK]NV, NV any] struct {
+       last Path[M]
+       key  NK
+}
+
+func (me next[NK, CV, NV]) Exists() bool {
+       _, ok := me.last.Get()[me.key]
+       return ok
+}
+
+func (me next[NK, CV, NV]) Get() NV {
+       return me.last.Get()[me.key]
+}
+
+func (me next[NK, CV, NV]) Set(value NV) {
+       if me.last.Get() == nil {
+               me.last.Set(make(CV))
+       }
+       me.last.Get()[me.key] = value
+}
+
+func (me next[NK, CV, NV]) Delete() {
+       m := me.last.Get()
+       delete(m, me.key)
+       if len(m) == 0 {
+               me.last.Delete()
+       }
+}
+
+func Next[K comparable, M ~map[K]V, V any](
+       last Path[M],
+       key K,
+) Path[V] {
+       ret := next[K, M, V]{}
+       ret.last = last
+       ret.key = key
+       return ret
+}
+
+type root[K comparable, V any, M ~map[K]V] struct {
+       m *M
+}
+
+func (me root[K, V, M]) Exists() bool {
+       return *me.m != nil
+}
+
+func (me root[K, V, M]) Get() M {
+       return *me.m
+}
+
+func (me root[K, V, M]) Set(value M) {
+       *me.m = value
+}
+
+func (me root[K, V, M]) Delete() {
+       *me.m = nil
+}
+
+func Begin[K comparable, M ~map[K]V, V any](m *M) Path[M] {
+       ret := root[K, V, M]{}
+       ret.m = m
+       return ret
+}
+
+type Path[V any] interface {
+       Set(V)
+       Get() V
+       Exists() bool
+       Delete()
+}
diff --git a/internal/nestedmaps/nestedmaps_test.go b/internal/nestedmaps/nestedmaps_test.go
new file mode 100644 (file)
index 0000000..af808eb
--- /dev/null
@@ -0,0 +1,42 @@
+package nestedmaps
+
+import (
+       "testing"
+
+       qt "github.com/frankban/quicktest"
+
+       g "github.com/anacrolix/generics"
+)
+
+func TestNestedMaps(t *testing.T) {
+       c := qt.New(t)
+       var nest map[string]map[*int]map[byte][]int64
+       intKey := g.PtrTo(420)
+       var root = Begin(&nest)
+       var first = Next(root, "answer")
+       var second = Next(first, intKey)
+       var last = Next(second, 69)
+       c.Assert(root.Exists(), qt.IsFalse)
+       c.Assert(first.Exists(), qt.IsFalse)
+       c.Assert(second.Exists(), qt.IsFalse)
+       c.Assert(last.Exists(), qt.IsFalse)
+       last.Set([]int64{4, 8, 15, 16, 23, 42})
+       c.Assert(root.Exists(), qt.IsTrue)
+       c.Assert(first.Exists(), qt.IsTrue)
+       c.Assert(second.Exists(), qt.IsTrue)
+       c.Assert(last.Exists(), qt.IsTrue)
+       c.Assert(Next(second, 70).Exists(), qt.IsFalse)
+       secondIntKey := g.PtrTo(1337)
+       secondPath := Next(Next(Next(Begin(&nest), "answer"), secondIntKey), 42)
+       secondPath.Set(nil)
+       c.Assert(secondPath.Exists(), qt.IsTrue)
+       last.Delete()
+       c.Assert(last.Exists(), qt.IsFalse)
+       c.Assert(second.Exists(), qt.IsFalse)
+       c.Assert(root.Exists(), qt.IsTrue)
+       c.Assert(first.Exists(), qt.IsTrue)
+       // See if we get panics deleting an already deleted item.
+       last.Delete()
+       secondPath.Delete()
+       c.Assert(root.Exists(), qt.IsFalse)
+}
diff --git a/internal/panicif/panicif.go b/internal/panicif/panicif.go
new file mode 100644 (file)
index 0000000..8cfb0ef
--- /dev/null
@@ -0,0 +1,9 @@
+package panicif
+
+import "fmt"
+
+func NotEqual[T comparable](a, b T) {
+       if a != b {
+               panic(fmt.Sprintf("%v != %v", a, b))
+       }
+}
index c7ca2549230cfd5e2ae6bc9cd0b0bec9f0997213..3dd47cd5508756db5d7446041b4c052359ab96f1 100644 (file)
@@ -37,6 +37,7 @@ import (
 
        "github.com/anacrolix/torrent/bencode"
        "github.com/anacrolix/torrent/common"
+       "github.com/anacrolix/torrent/internal/check"
        "github.com/anacrolix/torrent/metainfo"
        pp "github.com/anacrolix/torrent/peer_protocol"
        utHolepunch "github.com/anacrolix/torrent/peer_protocol/ut-holepunch"
@@ -1557,7 +1558,7 @@ func (t *Torrent) decPeerPieceAvailability(p *Peer) {
 }
 
 func (t *Torrent) assertPendingRequests() {
-       if !check {
+       if !check.Enabled {
                return
        }
        // var actual pendingRequests