go-hep.org/x/hep@v0.38.1/groot/riofs/plugin/http/span.go (about)

     1  // Copyright ©2022 The go-hep 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 http
     6  
     7  import (
     8  	"slices"
     9  	"sort"
    10  )
    11  
    12  type span struct {
    13  	off int64
    14  	len int64
    15  }
    16  
    17  func split(sp span, sps []span) []span {
    18  	if len(sps) == 0 {
    19  		return []span{sp}
    20  	}
    21  
    22  	var o []span
    23  
    24  	for _, v := range sps {
    25  		b1 := v.off
    26  		e1 := v.off + v.len
    27  		b2 := sp.off
    28  		e2 := sp.off + sp.len
    29  		switch {
    30  		case e1 <= b2:
    31  			//  [ s1=v ]
    32  			//         [  s2=sp ]
    33  			continue
    34  		case e2 <= b1:
    35  			//         [ s1 ]
    36  			// [ s2=sp ]
    37  			o = append(o, sp)
    38  			sp.len = 0
    39  		case b2 < b1 && e1 <= e2:
    40  			//   [ s1=v ]
    41  			//  [  s2=sp ]
    42  			len := b1 - b2
    43  			o = append(o, span{
    44  				off: b2,
    45  				len: len,
    46  			})
    47  			sp.off = e1
    48  			sp.len -= v.len + len
    49  		case b2 < b1 && b1 < e2 && e2 < e1:
    50  			//   [ s1=v   ]
    51  			//  [  s2=sp ]
    52  			len := b1 - b2
    53  			o = append(o, span{
    54  				off: b2,
    55  				len: len,
    56  			})
    57  			sp.len = 0
    58  		case b1 <= b2 && e2 <= e1:
    59  			//  [  s1=v   ]
    60  			//    [s2=sp]
    61  			sp.len = 0
    62  		case b1 <= b2 && e1 < e2:
    63  			//  [  s1=v  ]
    64  			//    [s2=sp  ]
    65  			sp.off = e1
    66  			sp.len = e2 - e1
    67  		}
    68  		if sp.len == 0 {
    69  			break
    70  		}
    71  	}
    72  	if sp.len != 0 {
    73  		o = append(o, sp)
    74  	}
    75  
    76  	return o
    77  }
    78  
    79  type spans []span
    80  
    81  func (p *spans) consolidate() {
    82  	for i := len(*p) - 1; i >= 1; i-- {
    83  		ii := &(*p)[i]
    84  		jj := &(*p)[i-1]
    85  		jend := jj.off + jj.len
    86  		iend := ii.off + ii.len
    87  		if jend < ii.off {
    88  			continue
    89  		}
    90  		if iend >= jend {
    91  			jj.len += iend - jend
    92  		}
    93  		p.remove(i)
    94  	}
    95  }
    96  
    97  func (p *spans) remove(i int) {
    98  	list := *p
    99  	*p = slices.Delete(list, i, i+1)
   100  }
   101  
   102  func (p *spans) add(sp span) {
   103  	*p = append(*p, sp)
   104  	sort.Slice(*p, func(i, j int) bool {
   105  		pi := (*p)[i]
   106  		pj := (*p)[j]
   107  		if pi.off < pj.off {
   108  			return true
   109  		}
   110  		if pi.off == pj.off {
   111  			return pi.off+pi.len < pj.off+pj.len
   112  		}
   113  		return false
   114  	})
   115  	p.consolidate()
   116  }