Mercurial > gemma
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 } |