Mercurial > gemma
diff cmd/octreediff/main.go @ 2465:86c7a023400e octree-diff
Started experimental octree diff branch.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 25 Feb 2019 17:02:33 +0100 |
parents | |
children | a1e751c08c56 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cmd/octreediff/main.go Mon Feb 25 17:02:33 2019 +0100 @@ -0,0 +1,149 @@ +// 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 by via donau +// – Österreichische Wasserstraßen-Gesellschaft mbH +// Software engineering by Intevation GmbH +// +// Author(s): +// * Sascha L. Teichmann <sascha.teichmann@intevation.de> + +package main + +import ( + "context" + "database/sql" + "flag" + "fmt" + "log" + "runtime" + "sync" + "time" + + "gemma.intevation.de/gemma/pkg/common" + "gemma.intevation.de/gemma/pkg/octree" +) + +var ( + bottleneck = flag.String("bottleneck", "", "name of the bottleneck") + first = flag.String("first", "", "date of the first sounding result") + second = flag.String("second", "", "date of the second sounding result") +) + +const ( + loadOctreeSQL = ` +SELECT sr.octree_index +FROM waterway.sounding_results sr JOIN waterway.bottlenecks bn + ON sr.bottleneck_id = bn.id +WHERE bn.bottleneck_id = $1 AND sr.date_info = $2::date + AND sr.octree_index IS NOT NULL` +) + +func check(err error) { + if err != nil { + log.Fatalf("error: %v\n", err) + } +} + +func process(bottleneck string, firstDate, secondDate time.Time) error { + start := time.Now() + defer func() { log.Printf("processing took %v\n", time.Since(start)) }() + + ctx := context.Background() + + return run(func(db *sql.DB) error { + + conn, err := db.Conn(ctx) + if err != nil { + return err + } + defer conn.Close() + + type load struct { + date time.Time + data []byte + err *error + dst **octree.Tree + } + + out := make(chan *load) + wg := new(sync.WaitGroup) + + n := runtime.NumCPU() + if n > 2 { + n = 2 + } + + for i := 0; i < n; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for l := range out { + if *l.err == nil { + *l.dst, *l.err = octree.Deserialize(l.data) + } + } + }() + } + + var firstErr, secondErr error + var first, second *octree.Tree + + for _, l := range []*load{ + {date: firstDate, dst: &first, err: &firstErr}, + {date: secondDate, dst: &second, err: &secondErr}, + } { + var data []byte + if err := conn.QueryRowContext( + ctx, + loadOctreeSQL, + bottleneck, + l.date, + ).Scan(&data); err != nil { + *l.err = err + } else { + l.data = data + } + out <- l + } + close(out) + + wg.Wait() + + if firstErr != nil || secondErr != nil { + if firstErr != nil && secondErr != nil { + return fmt.Errorf("%v, %v", firstErr, secondErr) + } + if firstErr != nil { + return firstErr + } + return secondErr + } + + log.Printf("loading took %v\n", time.Since(start)) + + // TODO: Do the diff. + _, _ = first, second + + return nil + }) +} + +func main() { + + flag.Parse() + + firstDate, err := time.Parse(common.DateFormat, *first) + check(err) + secondDate, err := time.Parse(common.DateFormat, *second) + check(err) + + if *bottleneck == "" { + log.Fatalln("Missing bottleneck name") + } + + check(process(*bottleneck, firstDate, secondDate)) +}