rewrite most of txQueue.String; move around couple things

This commit is contained in:
soypat
2025-02-05 01:39:26 -03:00
parent c53596166c
commit 23cd71fcc8
2 changed files with 64 additions and 53 deletions
+4 -5
View File
@@ -123,6 +123,7 @@ func (tx *ringTx) MakePacket(b []byte) (int, Value, error) {
if err != nil { if err != nil {
return n, 0, err return n, 0, err
} }
pkt := &tx.packets[nxtpkt]
off := tx.addEnd(tx.unsentoff, n) off := tx.addEnd(tx.unsentoff, n)
tx.unsentoff = off tx.unsentoff = off
@@ -130,17 +131,15 @@ func (tx *ringTx) MakePacket(b []byte) (int, Value, error) {
if off == tx.unsentend { if off == tx.unsentend {
tx.unsentend = 0 // Mark unsent as being empty. tx.unsentend = 0 // Mark unsent as being empty.
} }
pkt := &tx.packets[nxtpkt]
pkt.off = start pkt.off = start
pkt.end = off pkt.end = off
// Sequence number updates. // Sequence number updates.
seq := tx.seq oldseq := tx.seq
newseq := Add(seq, Size(n)) newseq := Add(oldseq, Size(n))
tx.seq = newseq tx.seq = newseq
pkt.seq = newseq pkt.seq = newseq
return n, seq, nil return n, oldseq, nil
} }
// RecvSegment processes an incoming segment and updates the sent packet queue // RecvSegment processes an incoming segment and updates the sent packet queue
+60 -48
View File
@@ -2,6 +2,7 @@ package tcp
import ( import (
"bytes" "bytes"
"fmt"
"math/rand" "math/rand"
"testing" "testing"
) )
@@ -149,17 +150,23 @@ func testTxQueue_SequentialMessages(t *testing.T, rtx *ringTx, msgs [][]byte, bu
} }
func testQueueSanity(t *testing.T, rtx *ringTx) { func testQueueSanity(t *testing.T, rtx *ringTx) {
t.Helper() // t.Helper()
defer func() {
if t.Failed() {
t.Log("\n" + rtx.string())
}
}()
if rtx.emptyRing != (ringidx{}) { if rtx.emptyRing != (ringidx{}) {
t.Fatalf("empty ring not empty") t.Fatalf("empty ring not empty")
} }
free := rtx.Free() free := rtx.Free()
sent := rtx.BufferedSent() sent := rtx.BufferedSent()
unsent := rtx.Buffered() unsent := rtx.Buffered()
sz := rtx.Size() sz := rtx.Size()
gotSz := free + sent + unsent gotSz := free + sent + unsent
if gotSz != sz { if gotSz != sz {
t.Fatal("\n", rtx.string()) t.Fatal("\n" + rtx.string())
t.Fatalf("want size=%d, got size=%d (free+sent+unsent=%d+%d+%d)", sz, gotSz, free, sent, unsent) t.Fatalf("want size=%d, got size=%d (free+sent+unsent=%d+%d+%d)", sz, gotSz, free, sent, unsent)
} }
freeStart, freeEnd, sentEnd := rtx.lims() freeStart, freeEnd, sentEnd := rtx.lims()
@@ -176,18 +183,30 @@ func testQueueSanity(t *testing.T, rtx *ringTx) {
} }
func (rx *ringTx) string() string { func (rx *ringTx) string() string {
return "" sz := rx.Size()
type zone struct { unsent, _ := rx.unsentRing()
name string sent, _ := rx.sentRing()
start, end int all := rx.sentAndUnsentBuffer()
printStart, printEnd bool if all.End == 0 || // Empty buffer, set offset so that free zone occupies whole buffer.
all.Off == 0 { // Buffer offset starts at zero which would set Free.End to 0 making it empty, patch that.
all.Off = sz
}
type zone struct {
name string
start, end int
}
zcontains := func(off int, z *zone) bool {
if z.end == 0 {
return false // Empty
} else if z.end < z.start {
return off < z.end || off >= z.start
}
return off >= z.start && off < z.end
} }
fs, fe, us := rx.lims()
var zones = []zone{ var zones = []zone{
{name: "free", start: fs, end: fe}, {name: "free", start: all.End, end: all.Off},
{name: "usnt", start: us, end: fs}, {name: "usnt", start: unsent.Off, end: unsent.End},
{name: "sent", start: fe, end: us}, {name: "sent", start: sent.Off, end: sent.End},
} }
var wrapZone *zone var wrapZone *zone
for i := range zones { for i := range zones {
@@ -199,43 +218,36 @@ func (rx *ringTx) string() string {
wrapZone = &zones[i] wrapZone = &zones[i]
} }
} }
var currentZone *zone
var b1, b2 bytes.Buffer var lastPrintedZone *zone
b1.WriteByte('|') var l1, l2 bytes.Buffer
b2.WriteByte(' ') changes := 0
b2.WriteByte(' ') for ib := 0; ib < sz; ib++ {
for i := 0; i < len(rx.rawbuf); { currentContainsIdx := currentZone != nil && zcontains(ib, currentZone)
var printedThisline int for iz := 0; !currentContainsIdx && iz < len(zones); iz++ {
var zoneName string z := &zones[iz]
for k := range zones { if zcontains(ib, z) {
z := &zones[k] currentZone = z
if z.end == 0 {
continue // No data in zone.
}
if !z.printStart && i >= z.start {
zoneName = z.name
if printedThisline > 0 {
b2.WriteByte('/')
printedThisline++
}
b2.WriteString(zoneName + "_s")
printedThisline += len(zoneName) + 2
z.printStart = true
}
}
if printedThisline > 0 {
b1.WriteByte('|')
b2.WriteByte(' ')
b2.WriteByte(' ')
for j := 0; j < printedThisline+1; j++ {
b1.WriteByte('-')
} }
} }
b2.WriteByte(' ') if currentZone == lastPrintedZone {
b1.WriteByte('-') continue
}
changes++
if changes > 4 {
panic("found too many zone changes")
}
lastPrintedZone = currentZone
// Change of zone.
top := "|-----" + currentZone.name + "-----"
l2.WriteString(top)
n, _ := fmt.Fprintf(&l1, "%d", currentZone.start)
for i := 0; i < len(top)-n; i++ {
l1.WriteByte(' ')
}
} }
b1.WriteString("|\n") l2.WriteByte('|')
b1.Write(b2.Bytes()) fmt.Fprintf(&l1, "%d\n", currentZone.end)
return b1.String() l2.WriteTo(&l1)
return l1.String()
} }