This is an automated email from the ASF dual-hosted git repository.

rob pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-trafficcontrol.git

commit 6b61f5d6c670e793d6a2b342b81deb7160b08256
Author: Jan van Doorn <j...@knutsel.com>
AuthorDate: Sun May 27 13:20:08 2018 -0600

    Add overlapping ranges support
---
 grove/plugin/range_req_handler.go | 42 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/grove/plugin/range_req_handler.go 
b/grove/plugin/range_req_handler.go
index 3834b39..2bc4774 100644
--- a/grove/plugin/range_req_handler.go
+++ b/grove/plugin/range_req_handler.go
@@ -19,6 +19,7 @@ import (
        "encoding/json"
        "fmt"
        "net/http"
+       "sort"
        "strconv"
        "strings"
 
@@ -31,6 +32,8 @@ type byteRange struct {
        End   int64
 }
 
+const MAXINT64 = 1<<63 - 1
+
 type rangeRequestConfig struct {
        Mode              string `json:"mode"`
        MultiPartBoundary string // not in the json
@@ -163,7 +166,7 @@ func rangeReqHandleBeforeRespond(icfg interface{}, d 
BeforeRespondData) {
        }
        body := make([]byte, 0)
        for _, thisRange := range ctx {
-               if thisRange.End == -1 || thisRange.End >= totalContentLength { 
// if the end range is "", or too large serve until the end
+               if thisRange.End == MAXINT64 || thisRange.End >= 
totalContentLength { // if the end range is "", or too large serve until the end
                        thisRange.End = totalContentLength - 1
                }
                if thisRange.Start == -1 {
@@ -207,7 +210,7 @@ func parseRange(rangeString string) (byteRange, error) {
                bRange.Start = start
        }
        if parts[1] == "" {
-               bRange.End = -1 // -1 means till the end
+               bRange.End = MAXINT64 // MAXINT64 means till the end
        } else {
                end, err := strconv.ParseInt(parts[1], 10, 64)
                if err != nil {
@@ -233,5 +236,38 @@ func parseRangeHeader(rHdrVal string) []byteRange {
                }
                byteRanges = append(byteRanges, thisRange)
        }
-       return byteRanges
+
+       // if there is just one range, return, and don't incur the overhead of 
determining overlaps
+       if len(byteRanges) <= 1 {
+               return byteRanges
+       }
+
+       // Collapse overlapping byte range requests, first sort the array by 
Start
+       sort.Slice(byteRanges, func(i, j int) bool {
+               return byteRanges[i].Start < byteRanges[j].Start
+       })
+
+       // Then, copy ranges into collapsedRanges if applicable, collapse as 
needed
+       collapsedRanges := make([]byteRange, 0)
+       j := 0
+       collapsedRanges = append(collapsedRanges, byteRanges[j])
+       for i := 1; i < len(byteRanges); i++ {
+               if collapsedRanges[j].End < byteRanges[i].Start {
+                       // Most normal case, the ranges are not overlapping; 
add the range to the collapsedRanges array
+                       collapsedRanges = append(collapsedRanges, byteRanges[i])
+                       j++
+                       continue
+               }
+               if collapsedRanges[j].Start <= byteRanges[i].Start && 
collapsedRanges[j].End >= byteRanges[i].End {
+                       // Don't add the entry at i, it is part of the entry at 
i-1
+                       continue
+               }
+               if collapsedRanges[j].Start <= byteRanges[i].Start && 
collapsedRanges[j].End < byteRanges[i].End {
+                       // Overlapping ranges, combine into one
+                       collapsedRanges[j].End = byteRanges[i].End
+                       continue
+               }
+       }
+
+       return collapsedRanges
 }

-- 
To stop receiving notification emails like this one, please contact
r...@apache.org.

Reply via email to