You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by ro...@apache.org on 2018/06/04 20:49:55 UTC
[incubator-trafficcontrol] 12/15: Add overlapping ranges support
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 <jv...@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
rob@apache.org.