Mercurial > gemma
view pkg/octree/slice.go @ 3827:6028326b88d6 sld-colors
go fmt'ed
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 03 Jul 2019 17:48:47 +0200 |
parents | 7686c7c23506 |
children |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2018, 2019 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> package octree import ( "runtime" "sync" ) type PointMap map[Point]float64 func (pm PointMap) Triangulate() (*Triangulation, error) { vertices := make([]Vertex, len(pm)) var i int for p, z := range pm { vertices[i] = Vertex{X: p.X, Y: p.Y, Z: z} i++ } return Triangulate(vertices) } func sliceWork( vs []Vertex, dst PointMap, fn func([]Vertex, func([]Vertex) []Vertex), ) { n := runtime.NumCPU() wg := new(sync.WaitGroup) slices := make(chan []Vertex) out := make(chan []Vertex) pool := make(chan []Vertex, n) const pageSize = 2048 turn := func(p []Vertex) []Vertex { if p != nil { out <- p } select { case p = <-pool: default: p = make([]Vertex, 0, pageSize) } return p } for i := 0; i < n; i++ { wg.Add(1) go func() { defer wg.Done() for slice := range slices { fn(slice, turn) } }() } done := make(chan struct{}) go func() { defer close(done) for s := range out { for i := range s { v := &s[i] key := Point{X: v.X, Y: v.Y} if z, found := dst[key]; found { dst[key] = (z + v.Z) * 0.5 } else { dst[key] = v.Z } } select { case pool <- s[:0:pageSize]: default: } } }() size := len(vs)/n + 1 for len(vs) > 0 { var l int if len(vs) < size { l = len(vs) } else { l = size } slices <- vs[:l] vs = vs[l:] } close(slices) wg.Wait() close(out) <-done }