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.