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 }