comparison pkg/models/octreecache.go @ 723:7eed7ff3142d

Started with model to load octrees from database.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 21 Sep 2018 18:32:41 +0200
parents
children
comparison
equal deleted inserted replaced
722:815f5e2ed974 723:7eed7ff3142d
1 package models
2
3 import (
4 "context"
5 "database/sql"
6 "sync"
7 "time"
8 )
9
10 type (
11 octreeCacheKey struct {
12 date time.Time
13 bottleneck string
14 }
15
16 octreeCacheEntry struct {
17 checksum string
18 tree *Octree
19 access time.Time
20 }
21 octreeCache struct {
22 sync.Mutex
23 entries map[octreeCacheKey]*octreeCacheEntry
24 }
25 )
26
27 const (
28 cleanupOctreeCacheSleep = 6 * time.Minute
29 maxOctreeCacheAge = 5 * time.Minute
30 maxOctreeCacheEntries = 4
31 )
32
33 const (
34 fetchOctreeSQL = `
35 SELECT checksum, octree_index
36 FROM waterway.octrees ot
37 JOIN waterway.sounding_results sr ON ot.sounding_result_id = sr.id
38 WHERE sr.bottleneck_id = $1 AND sr.date_info = $2::date
39 `
40 checkOctreeSQL = `
41 SELECT CASE
42 WHEN checksum = $3 THEN NULL
43 ELSE ot.octree_index
44 END
45 FROM waterway.octrees ot
46 JOIN waterway.sounding_results sr ON ot.sounding_result_id = sr.id
47 WHERE sr.bottleneck_id = $1 AND sr.date_info = $2::date
48 `
49 )
50
51 var OctreeCache = octreeCache{
52 entries: map[octreeCacheKey]*octreeCacheEntry{},
53 }
54
55 func init() {
56 go OctreeCache.background()
57 }
58
59 func (oc *octreeCache) background() {
60 for {
61 time.Sleep(cleanupOctreeCacheSleep)
62 oc.cleanup()
63 }
64 }
65
66 func (oc *octreeCache) cleanup() {
67 oc.Lock()
68 defer oc.Unlock()
69 good := time.Now().Add(-maxOctreeCacheAge)
70 for k, v := range oc.entries {
71 if v.access.Before(good) {
72 delete(oc.entries, k)
73 }
74 }
75 }
76
77 func (oc *octreeCache) Get(
78 bottleneck string, date time.Time,
79 conn *sql.Conn, ctx context.Context,
80 ) (*Octree, error) {
81 oc.Lock()
82 defer oc.Unlock()
83
84 key := octreeCacheKey{date, bottleneck}
85 entry := oc.entries[key]
86 if entry == nil {
87 // fetch from database
88 var data []byte
89 err := conn.QueryRowContext(ctx, fetchOctreeSQL, bottleneck, date).Scan(&data)
90 switch {
91 case err == sql.ErrNoRows:
92 return nil, nil
93 case err != nil:
94 return nil, err
95 }
96 // TODO: Deserialize!
97 } else {
98 // check if we are not outdated.
99 // TODO: Implement me!
100 }
101
102 return nil, nil
103 }