-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmulti.go
More file actions
79 lines (71 loc) · 1.69 KB
/
multi.go
File metadata and controls
79 lines (71 loc) · 1.69 KB
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
package stored
import (
"errors"
"github.com/apple/foundationdb/bindings/go/src/fdb"
"github.com/apple/foundationdb/bindings/go/src/fdb/subspace"
)
type multiNeed struct {
multi *MultiChain
object *Object
subspace subspace.Subspace
res *Value
}
// MultiChain allow to select multiple objects simultaniusly
type MultiChain struct {
db fdb.Database
needed map[string]multiNeed
unprocessed int
}
func (m *MultiChain) init() {
m.needed = map[string]multiNeed{}
}
func (m *MultiChain) execute() {
m.db.ReadTransact(func(tr fdb.ReadTransaction) (interface{}, error) {
tr = tr.Snapshot()
results := map[string]*needObject{}
for k, needObj := range m.needed {
results[k] = needObj.object.need(tr, needObj.subspace)
}
for k, needObj := range m.needed {
value, err := results[k].fetch()
if err != nil {
needObj.res.err = err
} else {
needObj.res.object = value.object
needObj.res.raw = value.raw
needObj.res.decoded = value.decoded
}
}
return nil, nil
})
m.unprocessed = 0
}
// Need means this object should be fetched
func (m *MultiChain) Need(o *Object, objOrID interface{}) *Value {
sub := o.subspace(objOrID)
needed := multiNeed{
multi: m,
object: o,
subspace: sub,
}
m.unprocessed++
val := Value{
fetch: func() {
if m.unprocessed > 0 {
m.execute()
}
},
}
needed.res = &val
m.needed[string(sub.Bytes())] = needed
return &val
}
// Get wiil get all objects with this object
func (m *MultiChain) Get(o *Object, objOrID interface{}) *Value {
sub := o.subspace(objOrID)
needed, ok := m.needed[string(sub.Bytes())]
if !ok {
return &Value{err: errors.New("multiget object was not needed")}
}
return needed.res
}