Mercurial > gemma
comparison pkg/octree/slice.go @ 2572:7686c7c23506
Morphological differences: Moved some code into octree package.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 11 Mar 2019 14:00:49 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2571:eec11d3d74f9 | 2572:7686c7c23506 |
---|---|
1 // This is Free Software under GNU Affero General Public License v >= 3.0 | |
2 // without warranty, see README.md and license for details. | |
3 // | |
4 // SPDX-License-Identifier: AGPL-3.0-or-later | |
5 // License-Filename: LICENSES/AGPL-3.0.txt | |
6 // | |
7 // Copyright (C) 2018, 2019 by via donau | |
8 // – Österreichische Wasserstraßen-Gesellschaft mbH | |
9 // Software engineering by Intevation GmbH | |
10 // | |
11 // Author(s): | |
12 // * Sascha L. Teichmann <sascha.teichmann@intevation.de> | |
13 | |
14 package octree | |
15 | |
16 import ( | |
17 "runtime" | |
18 "sync" | |
19 ) | |
20 | |
21 type PointMap map[Point]float64 | |
22 | |
23 func (pm PointMap) Triangulate() (*Triangulation, error) { | |
24 vertices := make([]Vertex, len(pm)) | |
25 var i int | |
26 for p, z := range pm { | |
27 vertices[i] = Vertex{X: p.X, Y: p.Y, Z: z} | |
28 i++ | |
29 } | |
30 return Triangulate(vertices) | |
31 } | |
32 | |
33 func sliceWork( | |
34 vs []Vertex, | |
35 dst PointMap, | |
36 fn func([]Vertex, func([]Vertex) []Vertex), | |
37 ) { | |
38 n := runtime.NumCPU() | |
39 | |
40 wg := new(sync.WaitGroup) | |
41 | |
42 slices := make(chan []Vertex) | |
43 out := make(chan []Vertex) | |
44 | |
45 pool := make(chan []Vertex, n) | |
46 | |
47 const pageSize = 2048 | |
48 | |
49 turn := func(p []Vertex) []Vertex { | |
50 if p != nil { | |
51 out <- p | |
52 } | |
53 select { | |
54 case p = <-pool: | |
55 default: | |
56 p = make([]Vertex, 0, pageSize) | |
57 } | |
58 return p | |
59 } | |
60 | |
61 for i := 0; i < n; i++ { | |
62 wg.Add(1) | |
63 go func() { | |
64 defer wg.Done() | |
65 for slice := range slices { | |
66 fn(slice, turn) | |
67 } | |
68 }() | |
69 } | |
70 done := make(chan struct{}) | |
71 go func() { | |
72 defer close(done) | |
73 for s := range out { | |
74 for i := range s { | |
75 v := &s[i] | |
76 key := Point{X: v.X, Y: v.Y} | |
77 if z, found := dst[key]; found { | |
78 dst[key] = (z + v.Z) * 0.5 | |
79 } else { | |
80 dst[key] = v.Z | |
81 } | |
82 } | |
83 select { | |
84 case pool <- s[:0:pageSize]: | |
85 default: | |
86 } | |
87 } | |
88 }() | |
89 | |
90 size := len(vs)/n + 1 | |
91 for len(vs) > 0 { | |
92 var l int | |
93 if len(vs) < size { | |
94 l = len(vs) | |
95 } else { | |
96 l = size | |
97 } | |
98 slices <- vs[:l] | |
99 vs = vs[l:] | |
100 } | |
101 close(slices) | |
102 wg.Wait() | |
103 close(out) | |
104 <-done | |
105 } |