// getTailFromRing returns the oldest ring element that contains the beginning of // our sequence range (start - end) and whose range of ring segments all // have their Reassembly.Skip value set to 0 (zero). func getTailFromRing(head *types.Ring, end types.Sequence) *types.Ring { var ret *types.Ring for r := head; r != head.Prev(); r = r.Next() { if r.Reassembly == nil { ret = r.Prev() break } if len(r.Reassembly.Bytes) == 0 { log.Print("getTailFromRing: zero payload ring segment encountered.") ret = r.Prev() break } if r.Reassembly.Skip != 0 { log.Print("getTailFromRing: stream skip encountered.") ret = r.Prev() break } diff := r.Reassembly.Seq.Difference(end) if diff < 0 { return r.Prev() } } // XXX // prevent bug where the above sets ret to head.Prev() if ret == head.Prev() { return nil } else { return ret } return nil }
// getHeadFromRing returns a pointer to the oldest ring element that // contains the beginning of our sequence range (start - end) AND // whose Reassembly.Skip value is 0 (zero). func getHeadFromRing(ringPtr *types.Ring, start, end types.Sequence) *types.Ring { var head *types.Ring current := ringPtr.Prev() if current.Reassembly == nil { return nil } if start.Difference(current.Reassembly.Seq.Add(len(current.Reassembly.Bytes)-1)) < 0 { log.Printf("lastestSeq %d < newStartSeq %d\n", current.Reassembly.Seq.Add(len(current.Reassembly.Bytes)-1), start) return nil } head = nil var candidate *types.Ring = nil for current := ringPtr.Prev(); current != ringPtr && current.Reassembly != nil; current = current.Prev() { if len(current.Reassembly.Bytes) == 0 { continue } startDiff := current.Reassembly.Seq.Difference(start) if startDiff == 0 { return current } if startDiff < 0 { finishEndDiff := current.Reassembly.Seq.Difference(end) if finishEndDiff >= 0 { candidate = current } continue } else { endDiff := start.Difference(current.Reassembly.Seq.Add(len(current.Reassembly.Bytes) - 1)) if endDiff >= 0 { head = current break } } } if head == nil && candidate != nil { head = candidate } return head }