comparison 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
comparison
equal deleted inserted replaced
2391:123e7f43b676 2465:86c7a023400e
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 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 main
15
16 import (
17 "context"
18 "database/sql"
19 "flag"
20 "fmt"
21 "log"
22 "runtime"
23 "sync"
24 "time"
25
26 "gemma.intevation.de/gemma/pkg/common"
27 "gemma.intevation.de/gemma/pkg/octree"
28 )
29
30 var (
31 bottleneck = flag.String("bottleneck", "", "name of the bottleneck")
32 first = flag.String("first", "", "date of the first sounding result")
33 second = flag.String("second", "", "date of the second sounding result")
34 )
35
36 const (
37 loadOctreeSQL = `
38 SELECT sr.octree_index
39 FROM waterway.sounding_results sr JOIN waterway.bottlenecks bn
40 ON sr.bottleneck_id = bn.id
41 WHERE bn.bottleneck_id = $1 AND sr.date_info = $2::date
42 AND sr.octree_index IS NOT NULL`
43 )
44
45 func check(err error) {
46 if err != nil {
47 log.Fatalf("error: %v\n", err)
48 }
49 }
50
51 func process(bottleneck string, firstDate, secondDate time.Time) error {
52 start := time.Now()
53 defer func() { log.Printf("processing took %v\n", time.Since(start)) }()
54
55 ctx := context.Background()
56
57 return run(func(db *sql.DB) error {
58
59 conn, err := db.Conn(ctx)
60 if err != nil {
61 return err
62 }
63 defer conn.Close()
64
65 type load struct {
66 date time.Time
67 data []byte
68 err *error
69 dst **octree.Tree
70 }
71
72 out := make(chan *load)
73 wg := new(sync.WaitGroup)
74
75 n := runtime.NumCPU()
76 if n > 2 {
77 n = 2
78 }
79
80 for i := 0; i < n; i++ {
81 wg.Add(1)
82 go func() {
83 defer wg.Done()
84 for l := range out {
85 if *l.err == nil {
86 *l.dst, *l.err = octree.Deserialize(l.data)
87 }
88 }
89 }()
90 }
91
92 var firstErr, secondErr error
93 var first, second *octree.Tree
94
95 for _, l := range []*load{
96 {date: firstDate, dst: &first, err: &firstErr},
97 {date: secondDate, dst: &second, err: &secondErr},
98 } {
99 var data []byte
100 if err := conn.QueryRowContext(
101 ctx,
102 loadOctreeSQL,
103 bottleneck,
104 l.date,
105 ).Scan(&data); err != nil {
106 *l.err = err
107 } else {
108 l.data = data
109 }
110 out <- l
111 }
112 close(out)
113
114 wg.Wait()
115
116 if firstErr != nil || secondErr != nil {
117 if firstErr != nil && secondErr != nil {
118 return fmt.Errorf("%v, %v", firstErr, secondErr)
119 }
120 if firstErr != nil {
121 return firstErr
122 }
123 return secondErr
124 }
125
126 log.Printf("loading took %v\n", time.Since(start))
127
128 // TODO: Do the diff.
129 _, _ = first, second
130
131 return nil
132 })
133 }
134
135 func main() {
136
137 flag.Parse()
138
139 firstDate, err := time.Parse(common.DateFormat, *first)
140 check(err)
141 secondDate, err := time.Parse(common.DateFormat, *second)
142 check(err)
143
144 if *bottleneck == "" {
145 log.Fatalln("Missing bottleneck name")
146 }
147
148 check(process(*bottleneck, firstDate, secondDate))
149 }