github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/segment/range.go (about)

     1  // Copyright 2018 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 segment
    16  
    17  // T is a required type parameter that must be an integral type.
    18  type T uint64
    19  
    20  // A Range represents a contiguous range of T.
    21  //
    22  // +stateify savable
    23  type Range struct {
    24  	// Start is the inclusive start of the range.
    25  	Start T
    26  
    27  	// End is the exclusive end of the range.
    28  	End T
    29  }
    30  
    31  // WellFormed returns true if r.Start <= r.End. All other methods on a Range
    32  // require that the Range is well-formed.
    33  //
    34  //go:nosplit
    35  func (r Range) WellFormed() bool {
    36  	return r.Start <= r.End
    37  }
    38  
    39  // Length returns the length of the range.
    40  //
    41  //go:nosplit
    42  func (r Range) Length() T {
    43  	return r.End - r.Start
    44  }
    45  
    46  // Contains returns true if r contains x.
    47  //
    48  //go:nosplit
    49  func (r Range) Contains(x T) bool {
    50  	return r.Start <= x && x < r.End
    51  }
    52  
    53  // Overlaps returns true if r and r2 overlap.
    54  //
    55  //go:nosplit
    56  func (r Range) Overlaps(r2 Range) bool {
    57  	return r.Start < r2.End && r2.Start < r.End
    58  }
    59  
    60  // IsSupersetOf returns true if r is a superset of r2; that is, the range r2 is
    61  // contained within r.
    62  //
    63  //go:nosplit
    64  func (r Range) IsSupersetOf(r2 Range) bool {
    65  	return r.Start <= r2.Start && r.End >= r2.End
    66  }
    67  
    68  // Intersect returns a range consisting of the intersection between r and r2.
    69  // If r and r2 do not overlap, Intersect returns a range with unspecified
    70  // bounds, but for which Length() == 0.
    71  //
    72  //go:nosplit
    73  func (r Range) Intersect(r2 Range) Range {
    74  	if r.Start < r2.Start {
    75  		r.Start = r2.Start
    76  	}
    77  	if r.End > r2.End {
    78  		r.End = r2.End
    79  	}
    80  	if r.End < r.Start {
    81  		r.End = r.Start
    82  	}
    83  	return r
    84  }
    85  
    86  // CanSplitAt returns true if it is legal to split a segment spanning the range
    87  // r at x; that is, splitting at x would produce two ranges, both of which have
    88  // non-zero length.
    89  //
    90  //go:nosplit
    91  func (r Range) CanSplitAt(x T) bool {
    92  	return r.Contains(x) && r.Start < x
    93  }