Eine schnelle Implementierung von Sequenzpuffern, die in diesem Blogbeitrag von Glenn Fiedler in Go beschrieben wird, mit 100 % Unit-Test-Abdeckung.
Dies wurde mit dem Ziel entwickelt, zuverlässige UDP-Netzwerkprotokolle zu erstellen, bei denen Sequenzpuffer als effiziente, belastbare Rollpuffer mit fester Größe verwendet werden können für:
Die zum Puffern von Einträgen verwendeten Sequenznummern sind auf vorzeichenlose 16-Bit-Ganzzahlen festgelegt, da größere Mengen an Einträgen redundant sind und eine vernachlässigbare Verbesserung Ihres Paketbestätigungssystems darstellen würden.
Die Größe des Puffers muss durch den Maximalwert einer vorzeichenlosen 16-Bit-Ganzzahl (65536) teilbar sein, andernfalls würden durch Sequenznummern gepufferte Daten nicht den gesamten Puffer umschließen. Dies ist beim Schreiben von Tests für diese Bibliothek aufgetreten.
Die Methode RemoveRange
wurde anhand der Sequenzpufferimplementierung in der Referenz-C-Codebasis „reliable.io“ einem Benchmarking unterzogen und optimiert, um einige memcpy
-Aufrufe über for-Schleifen zu verwenden.
Die tatsächlichen Sequenzen und gepufferten Daten werden in zwei separaten, zusammenhängenden Slices gespeichert, sodass Einträge, die aus dem rollierenden Puffer entnommen wurden, als veralteter Speicher verbleiben, der optional später durch Müll gesammelt werden kann.
go get github.com/lithdew/seq
$ go test -bench=. -benchtime=10s
goos: linux
goarch: amd64
pkg: github.com/lithdew/seq
BenchmarkTestBufferInsert-8 327525945 35.6 ns/op 0 B/op 0 allocs/op
BenchmarkTestBufferRemoveRange-8 243091503 51.3 ns/op 0 B/op 0 allocs/op
BenchmarkTestBufferGenerateBitset32-8 84982886 137 ns/op 0 B/op 0 allocs/op