src/pkg/container/ring/ring.go - The Go Programming Language

Golang

Source file src/pkg/container/ring/ring.go

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// Package ring implements operations on circular lists.
     6	package ring
     7	
     8	// A Ring is an element of a circular list, or ring.
     9	// Rings do not have a beginning or end; a pointer to any ring element
    10	// serves as reference to the entire ring. Empty rings are represented
    11	// as nil Ring pointers. The zero value for a Ring is a one-element
    12	// ring with a nil Value.
    13	//
    14	type Ring struct {
    15		next, prev *Ring
    16		Value      interface{} // for use by client; untouched by this library
    17	}
    18	
    19	func (r *Ring) init() *Ring {
    20		r.next = r
    21		r.prev = r
    22		return r
    23	}
    24	
    25	// Next returns the next ring element. r must not be empty.
    26	func (r *Ring) Next() *Ring {
    27		if r.next == nil {
    28			return r.init()
    29		}
    30		return r.next
    31	}
    32	
    33	// Prev returns the previous ring element. r must not be empty.
    34	func (r *Ring) Prev() *Ring {
    35		if r.next == nil {
    36			return r.init()
    37		}
    38		return r.prev
    39	}
    40	
    41	// Move moves n % r.Len() elements backward (n < 0) or forward (n >= 0)
    42	// in the ring and returns that ring element. r must not be empty.
    43	//
    44	func (r *Ring) Move(n int) *Ring {
    45		if r.next == nil {
    46			return r.init()
    47		}
    48		switch {
    49		case n < 0:
    50			for ; n < 0; n++ {
    51				r = r.prev
    52			}
    53		case n > 0:
    54			for ; n > 0; n-- {
    55				r = r.next
    56			}
    57		}
    58		return r
    59	}
    60	
    61	// New creates a ring of n elements.
    62	func New(n int) *Ring {
    63		if n <= 0 {
    64			return nil
    65		}
    66		r := new(Ring)
    67		p := r
    68		for i := 1; i < n; i++ {
    69			p.next = &Ring{prev: p}
    70			p = p.next
    71		}
    72		p.next = r
    73		r.prev = p
    74		return r
    75	}
    76	
    77	// Link connects ring r with with ring s such that r.Next()
    78	// becomes s and returns the original value for r.Next().
    79	// r must not be empty.
    80	//
    81	// If r and s point to the same ring, linking
    82	// them removes the elements between r and s from the ring.
    83	// The removed elements form a subring and the result is a
    84	// reference to that subring (if no elements were removed,
    85	// the result is still the original value for r.Next(),
    86	// and not nil).
    87	//
    88	// If r and s point to different rings, linking
    89	// them creates a single ring with the elements of s inserted
    90	// after r. The result points to the element following the
    91	// last element of s after insertion.
    92	//
    93	func (r *Ring) Link(s *Ring) *Ring {
    94		n := r.Next()
    95		if s != nil {
    96			p := s.Prev()
    97			// Note: Cannot use multiple assignment because
    98			// evaluation order of LHS is not specified.
    99			r.next = s
   100			s.prev = r
   101			n.prev = p
   102			p.next = n
   103		}
   104		return n
   105	}
   106	
   107	// Unlink removes n % r.Len() elements from the ring r, starting
   108	// at r.Next(). If n % r.Len() == 0, r remains unchanged.
   109	// The result is the removed subring. r must not be empty.
   110	//
   111	func (r *Ring) Unlink(n int) *Ring {
   112		if n <= 0 {
   113			return nil
   114		}
   115		return r.Link(r.Move(n + 1))
   116	}
   117	
   118	// Len computes the number of elements in ring r.
   119	// It executes in time proportional to the number of elements.
   120	//
   121	func (r *Ring) Len() int {
   122		n := 0
   123		if r != nil {
   124			n = 1
   125			for p := r.Next(); p != r; p = p.next {
   126				n++
   127			}
   128		}
   129		return n
   130	}
   131	
   132	// Do calls function f on each element of the ring, in forward order.
   133	// The behavior of Do is undefined if f changes *r.
   134	func (r *Ring) Do(f func(interface{})) {
   135		if r != nil {
   136			f(r.Value)
   137			for p := r.Next(); p != r; p = p.next {
   138				f(p.Value)
   139			}
   140		}
   141	}