tx_batch.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package batch
  2. import "net/netip"
  3. const SendBatchCap = 128
  4. // SendBatch accumulates encrypted UDP packets for potential TX offloading.
  5. // One SendBatch is owned by each listenIn goroutine; no locking is needed.
  6. // The backing storage holds up to batchCap packets of slotCap bytes each;
  7. // bufs and dsts are parallel slices of committed slots.
  8. type SendBatch struct {
  9. bufs [][]byte
  10. dsts []netip.AddrPort
  11. backing []byte
  12. slotCap int
  13. batchCap int
  14. nextSlot int
  15. }
  16. func NewSendBatch(batchCap, slotCap int) *SendBatch {
  17. return &SendBatch{
  18. bufs: make([][]byte, 0, batchCap),
  19. dsts: make([]netip.AddrPort, 0, batchCap),
  20. backing: make([]byte, batchCap*slotCap),
  21. slotCap: slotCap,
  22. batchCap: batchCap,
  23. }
  24. }
  25. func (b *SendBatch) Next() []byte {
  26. if b.nextSlot >= b.batchCap {
  27. return nil
  28. }
  29. start := b.nextSlot * b.slotCap
  30. return b.backing[start : start : start+b.slotCap] //set len to 0 but cap to slotCap
  31. }
  32. func (b *SendBatch) Commit(n int, dst netip.AddrPort) {
  33. start := b.nextSlot * b.slotCap
  34. b.bufs = append(b.bufs, b.backing[start:start+n])
  35. b.dsts = append(b.dsts, dst)
  36. b.nextSlot++
  37. }
  38. func (b *SendBatch) Reset() {
  39. b.bufs = b.bufs[:0]
  40. b.dsts = b.dsts[:0]
  41. b.nextSlot = 0
  42. }
  43. func (b *SendBatch) Len() int {
  44. return len(b.bufs)
  45. }
  46. func (b *SendBatch) Cap() int {
  47. return b.batchCap
  48. }
  49. func (b *SendBatch) Get() ([][]byte, []netip.AddrPort) {
  50. return b.bufs, b.dsts
  51. }