forked from quic-go/quic-go
optimize window update generation, reducing profiler footprint by 8%
This commit is contained in:
@@ -106,25 +106,15 @@ func (f *flowControlManager) AddBytesRead(streamID protocol.StreamID, n protocol
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// streamID must not be 0 here
|
func (f *flowControlManager) GetWindowUpdates() (res []WindowUpdate) {
|
||||||
func (f *flowControlManager) MaybeTriggerStreamWindowUpdate(streamID protocol.StreamID) (bool, protocol.ByteCount, error) {
|
|
||||||
f.mutex.Lock()
|
f.mutex.Lock()
|
||||||
defer f.mutex.Unlock()
|
defer f.mutex.Unlock()
|
||||||
|
for id, fc := range f.streamFlowController {
|
||||||
streamFlowController, err := f.getFlowController(streamID)
|
if necessary, offset := fc.MaybeTriggerWindowUpdate(); necessary {
|
||||||
if err != nil {
|
res = append(res, WindowUpdate{StreamID: id, Offset: offset})
|
||||||
return false, 0, err
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
doIt, offset := streamFlowController.MaybeTriggerWindowUpdate()
|
return res
|
||||||
return doIt, offset, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *flowControlManager) MaybeTriggerConnectionWindowUpdate() (bool, protocol.ByteCount) {
|
|
||||||
f.mutex.Lock()
|
|
||||||
defer f.mutex.Unlock()
|
|
||||||
|
|
||||||
return f.streamFlowController[0].MaybeTriggerWindowUpdate()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// streamID must not be 0 here
|
// streamID must not be 0 here
|
||||||
|
|||||||
@@ -95,10 +95,10 @@ var _ = Describe("Flow Control Manager", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
err = fcm.AddBytesRead(4, 0x100-0x10)
|
err = fcm.AddBytesRead(4, 0x100-0x10)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
doIt, offset, err := fcm.MaybeTriggerStreamWindowUpdate(4)
|
updates := fcm.GetWindowUpdates()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(updates).To(HaveLen(1))
|
||||||
Expect(doIt).To(BeTrue())
|
Expect(updates[0].StreamID).To(Equal(protocol.StreamID(4)))
|
||||||
Expect(offset).ToNot(Equal(protocol.ByteCount(0x100)))
|
Expect(updates[0].Offset).To(Equal(protocol.ByteCount(0x1f0)))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("gets connection level window updates", func() {
|
It("gets connection level window updates", func() {
|
||||||
@@ -110,10 +110,15 @@ var _ = Describe("Flow Control Manager", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
err = fcm.AddBytesRead(6, 0x100-0x10)
|
err = fcm.AddBytesRead(6, 0x100-0x10)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
doIt, offset := fcm.MaybeTriggerConnectionWindowUpdate()
|
updates := fcm.GetWindowUpdates()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(updates).To(HaveLen(3))
|
||||||
Expect(doIt).To(BeTrue())
|
if updates[0].StreamID == 0 {
|
||||||
Expect(offset).ToNot(Equal(protocol.ByteCount(0x200)))
|
Expect(updates[0].Offset).ToNot(Equal(protocol.ByteCount(0x200)))
|
||||||
|
} else if updates[1].StreamID == 0 {
|
||||||
|
Expect(updates[1].Offset).ToNot(Equal(protocol.ByteCount(0x200)))
|
||||||
|
} else {
|
||||||
|
Expect(updates[2].Offset).ToNot(Equal(protocol.ByteCount(0x200)))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,6 +2,12 @@ package flowcontrol
|
|||||||
|
|
||||||
import "github.com/lucas-clemente/quic-go/protocol"
|
import "github.com/lucas-clemente/quic-go/protocol"
|
||||||
|
|
||||||
|
// WindowUpdate provides the data for WindowUpdateFrames.
|
||||||
|
type WindowUpdate struct {
|
||||||
|
StreamID protocol.StreamID
|
||||||
|
Offset protocol.ByteCount
|
||||||
|
}
|
||||||
|
|
||||||
// A FlowControlManager manages the flow control
|
// A FlowControlManager manages the flow control
|
||||||
type FlowControlManager interface {
|
type FlowControlManager interface {
|
||||||
NewStream(streamID protocol.StreamID, contributesToConnectionFlow bool)
|
NewStream(streamID protocol.StreamID, contributesToConnectionFlow bool)
|
||||||
@@ -9,8 +15,7 @@ type FlowControlManager interface {
|
|||||||
// methods needed for receiving data
|
// methods needed for receiving data
|
||||||
UpdateHighestReceived(streamID protocol.StreamID, byteOffset protocol.ByteCount) error
|
UpdateHighestReceived(streamID protocol.StreamID, byteOffset protocol.ByteCount) error
|
||||||
AddBytesRead(streamID protocol.StreamID, n protocol.ByteCount) error
|
AddBytesRead(streamID protocol.StreamID, n protocol.ByteCount) error
|
||||||
MaybeTriggerStreamWindowUpdate(streamID protocol.StreamID) (bool, protocol.ByteCount, error)
|
GetWindowUpdates() []WindowUpdate
|
||||||
MaybeTriggerConnectionWindowUpdate() (bool, protocol.ByteCount)
|
|
||||||
// methods needed for sending data
|
// methods needed for sending data
|
||||||
AddBytesSent(streamID protocol.StreamID, n protocol.ByteCount) error
|
AddBytesSent(streamID protocol.StreamID, n protocol.ByteCount) error
|
||||||
SendWindowSize(streamID protocol.StreamID) (protocol.ByteCount, error)
|
SendWindowSize(streamID protocol.StreamID) (protocol.ByteCount, error)
|
||||||
|
|||||||
22
session.go
22
session.go
@@ -659,25 +659,11 @@ func (s *Session) tryDecryptingQueuedPackets() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) getWindowUpdateFrames() ([]*frames.WindowUpdateFrame, error) {
|
func (s *Session) getWindowUpdateFrames() ([]*frames.WindowUpdateFrame, error) {
|
||||||
var res []*frames.WindowUpdateFrame
|
updates := s.flowControlManager.GetWindowUpdates()
|
||||||
|
res := make([]*frames.WindowUpdateFrame, len(updates))
|
||||||
s.streamsMap.Iterate(func(str *stream) (bool, error) {
|
for i, u := range updates {
|
||||||
id := str.StreamID()
|
res[i] = &frames.WindowUpdateFrame{StreamID: u.StreamID, ByteOffset: u.Offset}
|
||||||
doUpdate, offset, err := s.flowControlManager.MaybeTriggerStreamWindowUpdate(id)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
}
|
||||||
if doUpdate {
|
|
||||||
res = append(res, &frames.WindowUpdateFrame{StreamID: id, ByteOffset: offset})
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
doUpdate, offset := s.flowControlManager.MaybeTriggerConnectionWindowUpdate()
|
|
||||||
if doUpdate {
|
|
||||||
res = append(res, &frames.WindowUpdateFrame{StreamID: 0, ByteOffset: offset})
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,12 +44,14 @@ func (m *mockFlowControlHandler) RemoveStream(streamID protocol.StreamID) {
|
|||||||
delete(m.sendWindowSizes, streamID)
|
delete(m.sendWindowSizes, streamID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockFlowControlHandler) MaybeTriggerStreamWindowUpdate(streamID protocol.StreamID) (bool, protocol.ByteCount, error) {
|
func (m *mockFlowControlHandler) GetWindowUpdates() (res []flowcontrol.WindowUpdate) {
|
||||||
return m.triggerStreamWindowUpdate, 0x1337, nil
|
if m.triggerStreamWindowUpdate {
|
||||||
}
|
res = append(res, flowcontrol.WindowUpdate{StreamID: 42, Offset: 0x1337})
|
||||||
|
}
|
||||||
func (m *mockFlowControlHandler) MaybeTriggerConnectionWindowUpdate() (bool, protocol.ByteCount) {
|
if m.triggerConnectionWindowUpdate {
|
||||||
return m.triggerConnectionWindowUpdate, 0x1337
|
res = append(res, flowcontrol.WindowUpdate{StreamID: 0, Offset: 0x1337})
|
||||||
|
}
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockFlowControlHandler) AddBytesRead(streamID protocol.StreamID, n protocol.ByteCount) error {
|
func (m *mockFlowControlHandler) AddBytesRead(streamID protocol.StreamID, n protocol.ByteCount) error {
|
||||||
|
|||||||
Reference in New Issue
Block a user