mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 23:18:15 -05:00
Operations pool for BLS-to-execution-changes (#11631)
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
This commit is contained in:
19
container/doubly-linked-list/BUILD.bazel
Normal file
19
container/doubly-linked-list/BUILD.bazel
Normal file
@@ -0,0 +1,19 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["list.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v3/container/doubly-linked-list",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@com_github_pkg_errors//:go_default_library"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["list_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
],
|
||||
)
|
||||
113
container/doubly-linked-list/list.go
Normal file
113
container/doubly-linked-list/list.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package doublylinkedlist
|
||||
|
||||
import "github.com/pkg/errors"
|
||||
|
||||
var (
|
||||
errNextOnNil = errors.New("cannot get next node of nil node")
|
||||
errPrevOnNil = errors.New("cannot get previous node of nil node")
|
||||
errValueOnNil = errors.New("cannot get value of nil node")
|
||||
)
|
||||
|
||||
// List is a generic doubly-linked list whose nodes can store any data type.
|
||||
// It allows retrieving pointers to the first and last nodes.
|
||||
type List[T any] struct {
|
||||
first *Node[T]
|
||||
last *Node[T]
|
||||
len int
|
||||
}
|
||||
|
||||
// Node is a generic data structure that contains three fields:
|
||||
// references to the previous and to the next node in the list, and one data field.
|
||||
type Node[T any] struct {
|
||||
value T
|
||||
prev *Node[T]
|
||||
next *Node[T]
|
||||
}
|
||||
|
||||
// First gets the reference to the first node in the list.
|
||||
func (l *List[T]) First() *Node[T] {
|
||||
return l.first
|
||||
}
|
||||
|
||||
// Last gets the reference to the last node in the list.
|
||||
func (l *List[T]) Last() *Node[T] {
|
||||
return l.last
|
||||
}
|
||||
|
||||
// Len gets the length of the list.
|
||||
func (l *List[T]) Len() int {
|
||||
return l.len
|
||||
}
|
||||
|
||||
// Append adds the passed in node to the end of the list.
|
||||
func (l *List[T]) Append(n *Node[T]) {
|
||||
if l.first == nil {
|
||||
l.first = n
|
||||
} else {
|
||||
n.prev = l.last
|
||||
l.last.next = n
|
||||
}
|
||||
l.last = n
|
||||
l.len++
|
||||
}
|
||||
|
||||
// Remove removes the passed in node from the list.
|
||||
func (l *List[T]) Remove(n *Node[T]) {
|
||||
if n == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if n == l.First() {
|
||||
if n == l.last {
|
||||
l.first = nil
|
||||
l.last = nil
|
||||
} else {
|
||||
n.next.prev = nil
|
||||
l.first = n.next
|
||||
}
|
||||
} else {
|
||||
if n == l.last {
|
||||
n.prev.next = nil
|
||||
l.last = n.prev
|
||||
} else {
|
||||
if n.next == nil || n.prev == nil {
|
||||
// The node is not in the list,
|
||||
// otherwise it would be in the middle of two nodes.
|
||||
return
|
||||
}
|
||||
n.prev.next = n.next
|
||||
n.next.prev = n.prev
|
||||
}
|
||||
}
|
||||
n = nil
|
||||
l.len--
|
||||
}
|
||||
|
||||
// NewNode creates a new node with the passed in value.
|
||||
func NewNode[T any](value T) *Node[T] {
|
||||
return &Node[T]{value: value}
|
||||
}
|
||||
|
||||
// Next gets the node's successor node.
|
||||
func (n *Node[T]) Next() (*Node[T], error) {
|
||||
if n == nil {
|
||||
return nil, errNextOnNil
|
||||
}
|
||||
return n.next, nil
|
||||
}
|
||||
|
||||
// Prev gets the node's predecessor node.
|
||||
func (n *Node[T]) Prev() (*Node[T], error) {
|
||||
if n == nil {
|
||||
return nil, errPrevOnNil
|
||||
}
|
||||
return n.prev, nil
|
||||
}
|
||||
|
||||
// Value gets the value stored in the node.
|
||||
func (n *Node[T]) Value() (T, error) {
|
||||
if n == nil {
|
||||
return *new(T), errValueOnNil
|
||||
}
|
||||
return n.value, nil
|
||||
}
|
||||
125
container/doubly-linked-list/list_test.go
Normal file
125
container/doubly-linked-list/list_test.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package doublylinkedlist
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/require"
|
||||
)
|
||||
|
||||
func TestAppend(t *testing.T) {
|
||||
t.Run("empty list", func(t *testing.T) {
|
||||
list := &List[int]{}
|
||||
i := 1
|
||||
list.Append(NewNode(i))
|
||||
require.Equal(t, i, list.len)
|
||||
require.NotNil(t, list.first)
|
||||
assert.Equal(t, i, list.first.value)
|
||||
require.NotNil(t, list.last)
|
||||
assert.DeepEqual(t, i, list.last.value)
|
||||
})
|
||||
t.Run("one node in list", func(t *testing.T) {
|
||||
list := &List[int]{}
|
||||
old := 1
|
||||
i := 2
|
||||
list.Append(NewNode(old))
|
||||
list.Append(NewNode(i))
|
||||
require.Equal(t, 2, list.len)
|
||||
require.NotNil(t, list.first)
|
||||
assert.DeepEqual(t, old, list.first.value)
|
||||
require.NotNil(t, list.first.next)
|
||||
assert.Equal(t, i, list.first.next.value)
|
||||
require.NotNil(t, list.last)
|
||||
assert.DeepEqual(t, i, list.last.value)
|
||||
require.NotNil(t, list.last.prev)
|
||||
assert.Equal(t, old, list.last.prev.value)
|
||||
})
|
||||
t.Run("multiple nodes in list", func(t *testing.T) {
|
||||
list := &List[int]{}
|
||||
first := 1
|
||||
second := 2
|
||||
i := 3
|
||||
list.Append(NewNode(first))
|
||||
list.Append(NewNode(second))
|
||||
list.Append(NewNode(i))
|
||||
require.Equal(t, 3, list.len)
|
||||
require.NotNil(t, list.first)
|
||||
assert.DeepEqual(t, first, list.first.value)
|
||||
require.NotNil(t, list.first.next)
|
||||
assert.Equal(t, second, list.first.next.value)
|
||||
assert.Equal(t, first, list.first.next.prev.value)
|
||||
require.NotNil(t, list.last)
|
||||
assert.DeepEqual(t, i, list.last.value)
|
||||
require.NotNil(t, list.first.next.next)
|
||||
assert.DeepEqual(t, i, list.first.next.next.value)
|
||||
require.NotNil(t, list.last.prev)
|
||||
assert.Equal(t, second, list.last.prev.value)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRemove(t *testing.T) {
|
||||
t.Run("one node in list", func(t *testing.T) {
|
||||
list := &List[int]{}
|
||||
n := NewNode(1)
|
||||
list.Append(n)
|
||||
list.Remove(n)
|
||||
assert.Equal(t, 0, list.len)
|
||||
assert.Equal(t, (*Node[int])(nil), list.first)
|
||||
assert.Equal(t, (*Node[int])(nil), list.last)
|
||||
})
|
||||
t.Run("first of multiple nodes", func(t *testing.T) {
|
||||
list := &List[int]{}
|
||||
first := NewNode(1)
|
||||
second := NewNode(2)
|
||||
third := NewNode(3)
|
||||
list.Append(first)
|
||||
list.Append(second)
|
||||
list.Append(third)
|
||||
list.Remove(first)
|
||||
require.Equal(t, 2, list.len)
|
||||
require.NotNil(t, list.first)
|
||||
assert.Equal(t, 2, list.first.value)
|
||||
assert.Equal(t, (*Node[int])(nil), list.first.prev)
|
||||
})
|
||||
t.Run("last of multiple nodes", func(t *testing.T) {
|
||||
list := &List[int]{}
|
||||
first := NewNode(1)
|
||||
second := NewNode(2)
|
||||
third := NewNode(3)
|
||||
list.Append(first)
|
||||
list.Append(second)
|
||||
list.Append(third)
|
||||
list.Remove(third)
|
||||
require.Equal(t, 2, list.len)
|
||||
require.NotNil(t, list.last)
|
||||
assert.Equal(t, 2, list.last.value)
|
||||
assert.Equal(t, (*Node[int])(nil), list.last.next)
|
||||
})
|
||||
t.Run("in the middle of multiple nodes", func(t *testing.T) {
|
||||
list := &List[int]{}
|
||||
first := NewNode(1)
|
||||
second := NewNode(2)
|
||||
third := NewNode(3)
|
||||
list.Append(first)
|
||||
list.Append(second)
|
||||
list.Append(third)
|
||||
list.Remove(second)
|
||||
require.Equal(t, 2, list.len)
|
||||
require.NotNil(t, list.first)
|
||||
require.NotNil(t, list.last)
|
||||
assert.Equal(t, 1, list.first.value)
|
||||
assert.Equal(t, 3, list.last.value)
|
||||
assert.Equal(t, 3, list.first.next.value)
|
||||
assert.Equal(t, 1, list.last.prev.value)
|
||||
})
|
||||
t.Run("not in list", func(t *testing.T) {
|
||||
list := &List[int]{}
|
||||
first := NewNode(1)
|
||||
second := NewNode(2)
|
||||
n := NewNode(3)
|
||||
list.Append(first)
|
||||
list.Append(second)
|
||||
list.Remove(n)
|
||||
require.Equal(t, 2, list.len)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user