gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/ilist/ring.go (about)

     1  // Copyright 2023 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package ring is an implementation of an intrusive circular linked list.
    16  package ring
    17  
    18  // Container is the type that holds the list entries.
    19  type Container any
    20  
    21  // Entry is an element in the circular linked list.
    22  //
    23  // +stateify savable
    24  type Entry struct {
    25  	next      *Entry
    26  	prev      *Entry
    27  	container Container
    28  }
    29  
    30  // Init instantiates an Element to be an item in a ring (circularly-linked
    31  // list).
    32  //
    33  //go:nosplit
    34  func (e *Entry) Init(container Container) {
    35  	e.next = e
    36  	e.prev = e
    37  	e.container = container
    38  }
    39  
    40  // Add adds new to old's ring.
    41  //
    42  //go:nosplit
    43  func (e *Entry) Add(new *Entry) {
    44  	next := e.next
    45  	prev := e
    46  
    47  	next.prev = new
    48  	new.next = next
    49  	new.prev = prev
    50  	e.next = new
    51  }
    52  
    53  // Remove removes e from its ring and reinitializes it.
    54  //
    55  //go:nosplit
    56  func (e *Entry) Remove() {
    57  	next := e.next
    58  	prev := e.prev
    59  
    60  	next.prev = prev
    61  	prev.next = next
    62  	e.Init(e.container)
    63  }
    64  
    65  // Empty returns true if there are no other elements in the ring.
    66  //
    67  //go:nosplit
    68  func (e *Entry) Empty() bool {
    69  	return e.next == e
    70  }
    71  
    72  // Next returns the next containing object pointed to by the list.
    73  //
    74  //go:nosplit
    75  func (e *Entry) Next() Container {
    76  	return e.next.container
    77  }
    78  
    79  // Prev returns the previous containing object pointed to by the list.
    80  //
    81  //go:nosplit
    82  func (e *Entry) Prev() Container {
    83  	return e.prev.container
    84  }