Skip to content

Commit

Permalink
use Genny to generate typed lists, based on Go standard library code
Browse files Browse the repository at this point in the history
  • Loading branch information
marten-seemann committed Mar 30, 2018
1 parent 51b9820 commit 7346d12
Show file tree
Hide file tree
Showing 13 changed files with 309 additions and 80 deletions.
1 change: 1 addition & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ coverage:
- internal/ackhandler/packet_linkedlist.go
- internal/utils/byteinterval_linkedlist.go
- internal/utils/packetinterval_linkedlist.go
- internal/utils/linkedlist/linkedlist.go
status:
project:
default:
Expand Down
7 changes: 0 additions & 7 deletions internal/ackhandler/_gen.go

This file was deleted.

3 changes: 3 additions & 0 deletions internal/ackhandler/gen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ackhandler

//go:generate genny -pkg ackhandler -in ../utils/linkedlist/linkedlist.go -out packet_linkedlist.go gen Item=Packet
1 change: 0 additions & 1 deletion internal/ackhandler/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
)

// A Packet is a packet
// +gen linkedlist
type Packet struct {
PacketNumber protocol.PacketNumber
PacketType protocol.PacketType
Expand Down
45 changes: 24 additions & 21 deletions internal/ackhandler/packet_linkedlist.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
// Generated by: main
// TypeWriter: linkedlist
// Directive: +gen on Packet
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny

package ackhandler

// List is a modification of http://golang.org/pkg/container/list/
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Linked list implementation from the Go standard library.

// PacketElement is an element of a linked list.
type PacketElement struct {
Expand Down Expand Up @@ -41,8 +38,7 @@ func (e *PacketElement) Prev() *PacketElement {
return nil
}

// PacketList represents a doubly linked list.
// The zero value for PacketList is an empty list ready to use.
// PacketList is a linked list of Packets.
type PacketList struct {
root PacketElement // sentinel list element, only &root, root.prev, and root.next are used
len int // current list length excluding (this) sentinel element
Expand All @@ -63,23 +59,23 @@ func NewPacketList() *PacketList { return new(PacketList).Init() }
// The complexity is O(1).
func (l *PacketList) Len() int { return l.len }

// Front returns the first element of list l or nil.
// Front returns the first element of list l or nil if the list is empty.
func (l *PacketList) Front() *PacketElement {
if l.len == 0 {
return nil
}
return l.root.next
}

// Back returns the last element of list l or nil.
// Back returns the last element of list l or nil if the list is empty.
func (l *PacketList) Back() *PacketElement {
if l.len == 0 {
return nil
}
return l.root.prev
}

// lazyInit lazily initializes a zero PacketList value.
// lazyInit lazily initializes a zero List value.
func (l *PacketList) lazyInit() {
if l.root.next == nil {
l.Init()
Expand All @@ -98,7 +94,7 @@ func (l *PacketList) insert(e, at *PacketElement) *PacketElement {
return e
}

// insertValue is a convenience wrapper for insert(&PacketElement{Value: v}, at).
// insertValue is a convenience wrapper for insert(&Element{Value: v}, at).
func (l *PacketList) insertValue(v Packet, at *PacketElement) *PacketElement {
return l.insert(&PacketElement{Value: v}, at)
}
Expand All @@ -116,10 +112,11 @@ func (l *PacketList) remove(e *PacketElement) *PacketElement {

// Remove removes e from l if e is an element of list l.
// It returns the element value e.Value.
// The element must not be nil.
func (l *PacketList) Remove(e *PacketElement) Packet {
if e.list == l {
// if e.list == l, l must have been initialized when e was inserted
// in l or l == nil (e is a zero PacketElement) and l.remove will crash
// in l or l == nil (e is a zero Element) and l.remove will crash
l.remove(e)
}
return e.Value
Expand All @@ -139,46 +136,51 @@ func (l *PacketList) PushBack(v Packet) *PacketElement {

// InsertBefore inserts a new element e with value v immediately before mark and returns e.
// If mark is not an element of l, the list is not modified.
// The mark must not be nil.
func (l *PacketList) InsertBefore(v Packet, mark *PacketElement) *PacketElement {
if mark.list != l {
return nil
}
// see comment in PacketList.Remove about initialization of l
// see comment in List.Remove about initialization of l
return l.insertValue(v, mark.prev)
}

// InsertAfter inserts a new element e with value v immediately after mark and returns e.
// If mark is not an element of l, the list is not modified.
// The mark must not be nil.
func (l *PacketList) InsertAfter(v Packet, mark *PacketElement) *PacketElement {
if mark.list != l {
return nil
}
// see comment in PacketList.Remove about initialization of l
// see comment in List.Remove about initialization of l
return l.insertValue(v, mark)
}

// MoveToFront moves element e to the front of list l.
// If e is not an element of l, the list is not modified.
// The element must not be nil.
func (l *PacketList) MoveToFront(e *PacketElement) {
if e.list != l || l.root.next == e {
return
}
// see comment in PacketList.Remove about initialization of l
// see comment in List.Remove about initialization of l
l.insert(l.remove(e), &l.root)
}

// MoveToBack moves element e to the back of list l.
// If e is not an element of l, the list is not modified.
// The element must not be nil.
func (l *PacketList) MoveToBack(e *PacketElement) {
if e.list != l || l.root.prev == e {
return
}
// see comment in PacketList.Remove about initialization of l
// see comment in List.Remove about initialization of l
l.insert(l.remove(e), l.root.prev)
}

// MoveBefore moves element e to its new position before mark.
// If e or mark is not an element of l, or e == mark, the list is not modified.
// The element and mark must not be nil.
func (l *PacketList) MoveBefore(e, mark *PacketElement) {
if e.list != l || e == mark || mark.list != l {
return
Expand All @@ -187,7 +189,8 @@ func (l *PacketList) MoveBefore(e, mark *PacketElement) {
}

// MoveAfter moves element e to its new position after mark.
// If e is not an element of l, or e == mark, the list is not modified.
// If e or mark is not an element of l, or e == mark, the list is not modified.
// The element and mark must not be nil.
func (l *PacketList) MoveAfter(e, mark *PacketElement) {
if e.list != l || e == mark || mark.list != l {
return
Expand All @@ -196,7 +199,7 @@ func (l *PacketList) MoveAfter(e, mark *PacketElement) {
}

// PushBackList inserts a copy of an other list at the back of list l.
// The lists l and other may be the same.
// The lists l and other may be the same. They must not be nil.
func (l *PacketList) PushBackList(other *PacketList) {
l.lazyInit()
for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() {
Expand All @@ -205,7 +208,7 @@ func (l *PacketList) PushBackList(other *PacketList) {
}

// PushFrontList inserts a copy of an other list at the front of list l.
// The lists l and other may be the same.
// The lists l and other may be the same. They must not be nil.
func (l *PacketList) PushFrontList(other *PacketList) {
l.lazyInit()
for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() {
Expand Down
7 changes: 0 additions & 7 deletions internal/utils/_gen.go

This file was deleted.

45 changes: 24 additions & 21 deletions internal/utils/byteinterval_linkedlist.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
// Generated by: main
// TypeWriter: linkedlist
// Directive: +gen on ByteInterval
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny

package utils

// List is a modification of http://golang.org/pkg/container/list/
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Linked list implementation from the Go standard library.

// ByteIntervalElement is an element of a linked list.
type ByteIntervalElement struct {
Expand Down Expand Up @@ -41,8 +38,7 @@ func (e *ByteIntervalElement) Prev() *ByteIntervalElement {
return nil
}

// ByteIntervalList represents a doubly linked list.
// The zero value for ByteIntervalList is an empty list ready to use.
// ByteIntervalList is a linked list of ByteIntervals.
type ByteIntervalList struct {
root ByteIntervalElement // sentinel list element, only &root, root.prev, and root.next are used
len int // current list length excluding (this) sentinel element
Expand All @@ -63,23 +59,23 @@ func NewByteIntervalList() *ByteIntervalList { return new(ByteIntervalList).Init
// The complexity is O(1).
func (l *ByteIntervalList) Len() int { return l.len }

// Front returns the first element of list l or nil.
// Front returns the first element of list l or nil if the list is empty.
func (l *ByteIntervalList) Front() *ByteIntervalElement {
if l.len == 0 {
return nil
}
return l.root.next
}

// Back returns the last element of list l or nil.
// Back returns the last element of list l or nil if the list is empty.
func (l *ByteIntervalList) Back() *ByteIntervalElement {
if l.len == 0 {
return nil
}
return l.root.prev
}

// lazyInit lazily initializes a zero ByteIntervalList value.
// lazyInit lazily initializes a zero List value.
func (l *ByteIntervalList) lazyInit() {
if l.root.next == nil {
l.Init()
Expand All @@ -98,7 +94,7 @@ func (l *ByteIntervalList) insert(e, at *ByteIntervalElement) *ByteIntervalEleme
return e
}

// insertValue is a convenience wrapper for insert(&ByteIntervalElement{Value: v}, at).
// insertValue is a convenience wrapper for insert(&Element{Value: v}, at).
func (l *ByteIntervalList) insertValue(v ByteInterval, at *ByteIntervalElement) *ByteIntervalElement {
return l.insert(&ByteIntervalElement{Value: v}, at)
}
Expand All @@ -116,10 +112,11 @@ func (l *ByteIntervalList) remove(e *ByteIntervalElement) *ByteIntervalElement {

// Remove removes e from l if e is an element of list l.
// It returns the element value e.Value.
// The element must not be nil.
func (l *ByteIntervalList) Remove(e *ByteIntervalElement) ByteInterval {
if e.list == l {
// if e.list == l, l must have been initialized when e was inserted
// in l or l == nil (e is a zero ByteIntervalElement) and l.remove will crash
// in l or l == nil (e is a zero Element) and l.remove will crash
l.remove(e)
}
return e.Value
Expand All @@ -139,46 +136,51 @@ func (l *ByteIntervalList) PushBack(v ByteInterval) *ByteIntervalElement {

// InsertBefore inserts a new element e with value v immediately before mark and returns e.
// If mark is not an element of l, the list is not modified.
// The mark must not be nil.
func (l *ByteIntervalList) InsertBefore(v ByteInterval, mark *ByteIntervalElement) *ByteIntervalElement {
if mark.list != l {
return nil
}
// see comment in ByteIntervalList.Remove about initialization of l
// see comment in List.Remove about initialization of l
return l.insertValue(v, mark.prev)
}

// InsertAfter inserts a new element e with value v immediately after mark and returns e.
// If mark is not an element of l, the list is not modified.
// The mark must not be nil.
func (l *ByteIntervalList) InsertAfter(v ByteInterval, mark *ByteIntervalElement) *ByteIntervalElement {
if mark.list != l {
return nil
}
// see comment in ByteIntervalList.Remove about initialization of l
// see comment in List.Remove about initialization of l
return l.insertValue(v, mark)
}

// MoveToFront moves element e to the front of list l.
// If e is not an element of l, the list is not modified.
// The element must not be nil.
func (l *ByteIntervalList) MoveToFront(e *ByteIntervalElement) {
if e.list != l || l.root.next == e {
return
}
// see comment in ByteIntervalList.Remove about initialization of l
// see comment in List.Remove about initialization of l
l.insert(l.remove(e), &l.root)
}

// MoveToBack moves element e to the back of list l.
// If e is not an element of l, the list is not modified.
// The element must not be nil.
func (l *ByteIntervalList) MoveToBack(e *ByteIntervalElement) {
if e.list != l || l.root.prev == e {
return
}
// see comment in ByteIntervalList.Remove about initialization of l
// see comment in List.Remove about initialization of l
l.insert(l.remove(e), l.root.prev)
}

// MoveBefore moves element e to its new position before mark.
// If e or mark is not an element of l, or e == mark, the list is not modified.
// The element and mark must not be nil.
func (l *ByteIntervalList) MoveBefore(e, mark *ByteIntervalElement) {
if e.list != l || e == mark || mark.list != l {
return
Expand All @@ -187,7 +189,8 @@ func (l *ByteIntervalList) MoveBefore(e, mark *ByteIntervalElement) {
}

// MoveAfter moves element e to its new position after mark.
// If e is not an element of l, or e == mark, the list is not modified.
// If e or mark is not an element of l, or e == mark, the list is not modified.
// The element and mark must not be nil.
func (l *ByteIntervalList) MoveAfter(e, mark *ByteIntervalElement) {
if e.list != l || e == mark || mark.list != l {
return
Expand All @@ -196,7 +199,7 @@ func (l *ByteIntervalList) MoveAfter(e, mark *ByteIntervalElement) {
}

// PushBackList inserts a copy of an other list at the back of list l.
// The lists l and other may be the same.
// The lists l and other may be the same. They must not be nil.
func (l *ByteIntervalList) PushBackList(other *ByteIntervalList) {
l.lazyInit()
for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() {
Expand All @@ -205,7 +208,7 @@ func (l *ByteIntervalList) PushBackList(other *ByteIntervalList) {
}

// PushFrontList inserts a copy of an other list at the front of list l.
// The lists l and other may be the same.
// The lists l and other may be the same. They must not be nil.
func (l *ByteIntervalList) PushFrontList(other *ByteIntervalList) {
l.lazyInit()
for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() {
Expand Down
4 changes: 4 additions & 0 deletions internal/utils/gen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package utils

//go:generate genny -pkg utils -in linkedlist/linkedlist.go -out byteinterval_linkedlist.go gen Item=ByteInterval
//go:generate genny -pkg utils -in linkedlist/linkedlist.go -out packetinterval_linkedlist.go gen Item=PacketInterval
11 changes: 11 additions & 0 deletions internal/utils/linkedlist/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Usage

This is the Go standard library implementation of a linked list
(https://golang.org/src/container/list/list.go), modified such that genny
(https://github.com/cheekybits/genny) can be used to generate a typed linked
list.

To generate, run
```
genny -pkg $PACKAGE -in linkedlist.go -out $OUTFILE gen Item=$TYPE
```
Loading

0 comments on commit 7346d12

Please sign in to comment.