changeset 3467:7265adcc5baa

Simplified code paths of fairway availibilty/depth for streches/sections.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 27 May 2019 11:18:05 +0200
parents dfa97aad1134
children 850e81f13e96
files pkg/controllers/stretches.go
diffstat 1 files changed, 96 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/controllers/stretches.go	Mon May 27 10:49:50 2019 +0200
+++ b/pkg/controllers/stretches.go	Mon May 27 11:18:05 2019 +0200
@@ -60,33 +60,8 @@
 		breaks       []float64
 		access       func(*availMeasurement) float64
 	}
-
-	availResult struct {
-		label       string
-		from, to    time.Time
-		ldc, breaks []time.Duration
-	}
-
-	availCalculation struct {
-		result      *availResult
-		ldc, breaks []time.Duration
-	}
-
-	availJob struct {
-		result *availResult
-		bn     *fullStretchBottleneck
-	}
 )
 
-func (r *availResult) add(c availCalculation) {
-	for i, v := range c.ldc {
-		r.ldc[i] += v
-	}
-	for i, v := range c.breaks {
-		r.breaks[i] += v
-	}
-}
-
 func (bns stretchBottlenecks) contains(limiting string) bool {
 	for i := range bns {
 		if bns[i].limiting == limiting {
@@ -279,46 +254,57 @@
 		n = 1
 	}
 
-	jobCh := make(chan availJob)
-	calcCh := make(chan availCalculation, n)
-	done := make(chan struct{})
+	type result struct {
+		label  string
+		from   time.Time
+		to     time.Time
+		ldc    []time.Duration
+		breaks []time.Duration
+	}
+
+	jobCh := make(chan *result)
 
 	var wg sync.WaitGroup
 
-	go func() {
-		defer close(done)
-		for calc := range calcCh {
-			calc.result.add(calc)
-		}
-	}()
-
 	for i := 0; i < n; i++ {
 		wg.Add(1)
 		go func() {
 			defer wg.Done()
-			for job := range jobCh {
-				bn := job.bn
-				res := job.result
-				ldc := bn.measurements.classify(
-					res.from, res.to,
-					bn.ldc,
-					bn.access,
-				)
-				breaks := bn.measurements.classify(
-					res.from, res.to,
-					bn.breaks,
-					bn.access,
-				)
-				calcCh <- availCalculation{
-					result: res,
-					breaks: breaks,
-					ldc:    ldc,
+			for res := range jobCh {
+
+				var ldc, breaks []time.Duration
+
+				for _, bn := range loaded {
+					l := bn.measurements.classify(
+						res.from, res.to,
+						bn.ldc,
+						bn.access,
+					)
+					b := bn.measurements.classify(
+						res.from, res.to,
+						bn.breaks,
+						bn.access,
+					)
+
+					if ldc == nil {
+						ldc, breaks = l, b
+					} else {
+						for i, v := range l {
+							ldc[i] += v
+						}
+						for i, v := range b {
+							breaks[i] += v
+						}
+					}
 				}
+
+				res.ldc = ldc
+				res.breaks = breaks
 			}
 		}()
 	}
 
-	var results []*availResult
+	var results []*result
 
 	interval := intervals[mode](from, to)
 
@@ -332,24 +318,17 @@
 
 	for pfrom, pto, label := interval(); label != ""; pfrom, pto, label = interval() {
 
-		res := &availResult{
-			label:  label,
-			from:   pfrom,
-			to:     pto,
-			ldc:    make([]time.Duration, 2),
-			breaks: make([]time.Duration, len(breaks)+1),
+		res := &result{
+			label: label,
+			from:  pfrom,
+			to:    pto,
 		}
 		results = append(results, res)
-
-		for _, bn := range loaded {
-			jobCh <- availJob{bn: bn, result: res}
-		}
+		jobCh <- res
 	}
 
 	close(jobCh)
 	wg.Wait()
-	close(calcCh)
-	<-done
 
 	rw.Header().Add("Content-Type", "text/csv")
 
@@ -368,9 +347,9 @@
 			record[i+4] = fmt.Sprintf("# >= break_%d", i+1)
 		} else {
 			if i == 0 {
-				record[3] = fmt.Sprintf("# < %.2f [h]", v)
+				record[3] = fmt.Sprintf("# < %.1f [h]", v)
 			}
-			record[i+4] = fmt.Sprintf("# >= %.2f [h]", v)
+			record[i+4] = fmt.Sprintf("# >= %.1f [h]", v)
 		}
 	}
 
@@ -531,47 +510,60 @@
 		n = 1
 	}
 
-	jobCh := make(chan availJob)
-	calcCh := make(chan availCalculation, n)
-	done := make(chan struct{})
+	type result struct {
+		label  string
+		from   time.Time
+		to     time.Time
+		ldc    []float64
+		breaks []float64
+	}
+
+	jobCh := make(chan *result)
 
 	var wg sync.WaitGroup
 
-	go func() {
-		defer close(done)
-		for calc := range calcCh {
-			calc.result.add(calc)
-		}
-	}()
-
 	for i := 0; i < n; i++ {
 		wg.Add(1)
 		go func() {
 			defer wg.Done()
-			for job := range jobCh {
-				bn := job.bn
-				res := job.result
-				ldc := bn.measurements.classify(
-					from, to,
-					bn.ldc,
-					(*availMeasurement).getValue,
-				)
+			for res := range jobCh {
+				var ldc, breaks []time.Duration
+
+				for _, bn := range loaded {
+					l := bn.measurements.classify(
+						from, to,
+						bn.ldc,
+						(*availMeasurement).getValue,
+					)
+
+					b := bn.measurements.classify(
+						from, to,
+						bn.breaks,
+						bn.access,
+					)
 
-				breaks := bn.measurements.classify(
-					from, to,
-					bn.breaks,
-					bn.access,
-				)
-				calcCh <- availCalculation{
-					result: res,
-					breaks: breaks,
-					ldc:    ldc,
+					if ldc == nil {
+						ldc, breaks = l, b
+					} else {
+						for i, v := range l {
+							ldc[i] += v
+						}
+						for i, v := range b {
+							breaks[i] += v
+						}
+					}
 				}
+
+				duration := res.to.Sub(res.from) * time.Duration(len(loaded))
+
+				res.ldc = durationsToPercentage(duration, ldc)
+				res.breaks = durationsToPercentage(duration, breaks)
+
 			}
 		}()
 	}
 
-	var results []*availResult
+	var results []*result
 
 	interval := intervals[mode](from, to)
 
@@ -585,24 +577,18 @@
 
 	for pfrom, pto, label := interval(); label != ""; pfrom, pto, label = interval() {
 
-		res := &availResult{
-			label:  label,
-			from:   pfrom,
-			to:     pto,
-			ldc:    make([]time.Duration, 2),
-			breaks: make([]time.Duration, len(breaks)+1),
+		res := &result{
+			label: label,
+			from:  pfrom,
+			to:    pto,
 		}
 		results = append(results, res)
 
-		for _, bn := range loaded {
-			jobCh <- availJob{bn: bn, result: res}
-		}
+		jobCh <- res
 	}
 
 	close(jobCh)
 	wg.Wait()
-	close(calcCh)
-	<-done
 
 	rw.Header().Add("Content-Type", "text/csv")
 
@@ -633,19 +619,14 @@
 		return
 	}
 
-	for _, r := range results {
-		duration := r.to.Sub(r.from) * time.Duration(len(loaded))
+	for _, res := range results {
+		record[0] = res.label
 
-		ldcPercents := durationsToPercentage(duration, r.ldc)
-		breaksPercents := durationsToPercentage(duration, r.breaks)
-
-		record[0] = r.label
-
-		for i, v := range ldcPercents {
+		for i, v := range res.ldc {
 			record[2+i] = fmt.Sprintf("%.3f", v)
 		}
 
-		for i, v := range breaksPercents {
+		for i, v := range res.breaks {
 			record[3+i] = fmt.Sprintf("%.3f", v)
 		}