/
cache_bbolt.go
138 lines (112 loc) · 2.82 KB
/
cache_bbolt.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// /home/krylon/go/src/github.com/blicero/guang/generator/cache_bbolt.go
// -*- mode: go; coding: utf-8; -*-
// Created on 25. 11. 2022 by Benjamin Walkenhorst
// (c) 2022 Benjamin Walkenhorst
// Time-stamp: <2022-12-16 18:35:37 krylon>
package generator
import (
"fmt"
"log"
"sync"
"time"
"github.com/blicero/guang/common"
"github.com/blicero/krylib"
"go.etcd.io/bbolt"
)
// Re-Implementation of the host cache, but with bbolt.
var openLock sync.Mutex
type bboltCache struct {
path string
log *log.Logger
cache *bbolt.DB
}
func openBoltCache(path string) (cache, error) { // nolint: unused
var (
err error
exists bool
opt bbolt.Options
c = &bboltCache{path: path}
)
// path = path + ".blt"
// common.HostCachePath = path
openLock.Lock()
defer openLock.Unlock()
if exists, err = krylib.Fexists(path); err != nil {
return nil, err
}
opt = bbolt.Options{
Timeout: time.Second * 90,
FreelistType: "hashmap",
}
if c.log, err = common.GetLogger("Generator/Cache"); err != nil {
return nil, err
} else if c.cache, err = bbolt.Open(path, 0600, &opt); err != nil {
c.log.Printf("[ERROR] Cannot open host cache at %q: %s\n",
path,
err.Error())
return nil, err
}
if !exists {
c.log.Printf("[INFO] Initializing host cache at %s\n",
path)
err = c.cache.Update(func(tx *bbolt.Tx) error {
var x error
if _, x = tx.CreateBucket(bs("ip")); x != nil {
c.log.Printf("[ERROR] Cannot create bucket ip: %s\n",
x.Error())
return x
} else if _, x = tx.CreateBucket(bs("name")); x != nil {
c.log.Printf("[ERROR] Cannot create bucket name: %s\n",
x.Error())
return x
}
return nil
})
if err != nil {
c.log.Printf("[ERROR] Failed to initialize host cache: %s\n",
err.Error())
return nil, err
}
}
return c, nil
} // func openBoltCache(path string) (*bboltCache, error)
func (c *bboltCache) HasKey(s string) (bool, error) {
var (
err error
exists bool
)
err = c.cache.View(func(tx *bbolt.Tx) error {
var (
x error
bucket *bbolt.Bucket
)
if bucket = tx.Bucket(bs("ip")); bucket == nil {
return fmt.Errorf("Did not find bucket 'ip' in cache, to check address %q",
s)
} else if r := bucket.Get(bs(s)); r != nil {
exists = true
}
return x
})
return exists, err
} // func (c *bboltCache) HasKey(s string) (bool, error)
func (c *bboltCache) AddKey(s string) error {
return c.cache.Update(func(tx *bbolt.Tx) error {
var (
x error
b *bbolt.Bucket
)
if b = tx.Bucket(bs("ip")); b == nil {
x = fmt.Errorf("Did not find Bucket 'ip' to add key %q",
s)
} else if x = b.Put(bs(s), bs("1")); x != nil {
c.log.Printf("[ERROR] Cannot add IP %q to host cache: %s\n",
s,
x.Error())
}
return x
})
} // func (c *bboltCache) AddKey(s string) error
func bs(s string) []byte {
return []byte(s)
}