summaryrefslogtreecommitdiff
path: root/vendor/github.com/cilium/ebpf/asm/metadata.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/cilium/ebpf/asm/metadata.go')
-rw-r--r--vendor/github.com/cilium/ebpf/asm/metadata.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/vendor/github.com/cilium/ebpf/asm/metadata.go b/vendor/github.com/cilium/ebpf/asm/metadata.go
new file mode 100644
index 000000000..dd368a936
--- /dev/null
+++ b/vendor/github.com/cilium/ebpf/asm/metadata.go
@@ -0,0 +1,80 @@
+package asm
+
+// Metadata contains metadata about an instruction.
+type Metadata struct {
+ head *metaElement
+}
+
+type metaElement struct {
+ next *metaElement
+ key, value interface{}
+}
+
+// Find the element containing key.
+//
+// Returns nil if there is no such element.
+func (m *Metadata) find(key interface{}) *metaElement {
+ for e := m.head; e != nil; e = e.next {
+ if e.key == key {
+ return e
+ }
+ }
+ return nil
+}
+
+// Remove an element from the linked list.
+//
+// Copies as many elements of the list as necessary to remove r, but doesn't
+// perform a full copy.
+func (m *Metadata) remove(r *metaElement) {
+ current := &m.head
+ for e := m.head; e != nil; e = e.next {
+ if e == r {
+ // We've found the element we want to remove.
+ *current = e.next
+
+ // No need to copy the tail.
+ return
+ }
+
+ // There is another element in front of the one we want to remove.
+ // We have to copy it to be able to change metaElement.next.
+ cpy := &metaElement{key: e.key, value: e.value}
+ *current = cpy
+ current = &cpy.next
+ }
+}
+
+// Set a key to a value.
+//
+// If value is nil, the key is removed. Avoids modifying old metadata by
+// copying if necessary.
+func (m *Metadata) Set(key, value interface{}) {
+ if e := m.find(key); e != nil {
+ if e.value == value {
+ // Key is present and the value is the same. Nothing to do.
+ return
+ }
+
+ // Key is present with a different value. Create a copy of the list
+ // which doesn't have the element in it.
+ m.remove(e)
+ }
+
+ // m.head is now a linked list that doesn't contain key.
+ if value == nil {
+ return
+ }
+
+ m.head = &metaElement{key: key, value: value, next: m.head}
+}
+
+// Get the value of a key.
+//
+// Returns nil if no value with the given key is present.
+func (m *Metadata) Get(key interface{}) interface{} {
+ if e := m.find(key); e != nil {
+ return e.value
+ }
+ return nil
+}