forked from antsmartian/go_concurrency_tutorial
-
Notifications
You must be signed in to change notification settings - Fork 0
/
simple_db.go
104 lines (85 loc) · 1.45 KB
/
simple_db.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
package main
import (
"sync"
"fmt"
"time"
)
type DB struct {
mu sync.RWMutex
data map[string]string
}
func Create() (*DB) {
db := &DB{
data : make(map[string]string),
}
return db
}
type Tx struct {
db *DB
writable bool
}
func (tx *Tx) lock() {
if tx.writable {
tx.db.mu.Lock()
} else {
tx.db.mu.RLock()
}
}
func (tx *Tx) unlock() {
if tx.writable {
tx.db.mu.Unlock()
} else {
tx.db.mu.RUnlock()
}
}
func (tx *Tx) Set(key, value string) {
fmt.Println("Setting value... " , key , value)
tx.db.data[key] = value
}
func (tx *Tx) Get(key string) string {
return tx.db.data[key]
}
func (db * DB) View(fn func (tx *Tx) error) error {
return db.managed(false, fn)
}
func (db * DB) Update(fn func (tx *Tx) error) error {
return db.managed(true, fn)
}
func (db *DB) Begin(writable bool) (*Tx) {
tx := &Tx {
db : db,
writable: writable,
}
tx.lock()
return tx
}
func (db *DB) managed(writable bool, fn func(tx *Tx) error) (err error) {
var tx *Tx
tx = db.Begin(writable)
defer func() {
if writable {
fmt.Println("Write Unlocking...")
tx.unlock()
} else {
fmt.Println("Read Unlocking...")
tx.unlock()
}
}()
fn(tx)
return
}
func main() {
db := Create()
go db.Update(func(tx *Tx) error {
tx.Set("mykey", "go")
tx.Set("mykey2", "is")
tx.Set("mykey3", "awesome")
return nil
})
go db.View(func(tx *Tx) error {
fmt.Println("value is")
fmt.Println(tx.Get("mykey3"))
return nil
})
time.Sleep(20000000000)
}