-
Notifications
You must be signed in to change notification settings - Fork 66
/
storage.go
271 lines (236 loc) · 12.8 KB
/
storage.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package storage provides the abstraction to build drivers for BadWolf.
package storage
import (
"bytes"
"context"
"fmt"
"strconv"
"sync"
"time"
"github.com/google/badwolf/bql/planner/filter"
"github.com/google/badwolf/triple"
"github.com/google/badwolf/triple/node"
"github.com/google/badwolf/triple/predicate"
"github.com/pborman/uuid"
)
// bufPool keeps a pool of bytes.Buffer for usage in String().
var bufPool = sync.Pool{New: func() interface{} { return &bytes.Buffer{} }}
// LookupOptions allows to specify the behavior of the lookup operations.
type LookupOptions struct {
// MaxElements list the maximum number of elements to return. If not
// set it returns all the lookup results.
MaxElements int
// LowerAnchor, if provided, represents the lower time anchor to be considered.
LowerAnchor *time.Time
// UpperAnchor, if provided, represents the upper time anchor to be considered.
UpperAnchor *time.Time
// LatestAnchor only. If set, it will ignore the time boundaries provided and
// just use the last available anchor.
LatestAnchor bool
// FilterOptions, if provided, represent the specifications for the filtering to be executed.
FilterOptions *filter.StorageOptions
// Offset, if provided, represents the offset of the ordered set of triples returned.
Offset int
}
// String returns a readable version of the LookupOptions instance.
func (l *LookupOptions) String() string {
b := bufPool.Get().(*bytes.Buffer)
b.Reset()
defer bufPool.Put(b)
b.WriteString("<limit=")
b.WriteString(strconv.Itoa(l.MaxElements))
b.WriteString(", lower_anchor=")
if l.LowerAnchor != nil {
b.WriteString(l.LowerAnchor.Format(time.RFC3339Nano))
} else {
b.WriteString("nil")
}
b.WriteString(", upper_anchor=")
if l.UpperAnchor != nil {
b.WriteString(l.UpperAnchor.Format(time.RFC3339Nano))
} else {
b.WriteString("nil")
}
b.WriteString(fmt.Sprintf(", LatestAnchor=%v", l.LatestAnchor))
b.WriteString(fmt.Sprintf(", FilterOptions=%s>", l.FilterOptions))
return b.String()
}
// UUID return the UUID of the lookup option.
func (l *LookupOptions) UUID() uuid.UUID {
return uuid.NewSHA1(uuid.NIL, []byte(l.String()))
}
// DefaultLookup provides the default lookup behavior.
var DefaultLookup = &LookupOptions{}
// Store interface describes the low lever API that allows to create new graphs.
type Store interface {
// Name returns the ID of the backend being used.
Name(ctx context.Context) string
// Version returns the version of the driver implementation.
Version(ctx context.Context) string
// NewGraph creates a new graph. Creating an already existing graph
// should return an error.
NewGraph(ctx context.Context, id string) (Graph, error)
// Graph returns an existing graph if available. Getting a non existing
// graph should return an error.
Graph(ctx context.Context, id string) (Graph, error)
// DeleteGraph deletes an existing graph. Deleting a non existing graph
// should return an error.
DeleteGraph(ctx context.Context, id string) error
// GraphNames returns the current available graph names in the store.
GraphNames(ctx context.Context, names chan<- string) error
}
// Graph interface describes the low level API that storage drivers need
// to implement to provide a compliant graph storage that can be used with
// BadWolf.
//
// If you are implementing a driver or just using a low lever driver directly
// it is important for you to keep in mind that you will need to drain the
// provided channel. Otherwise you run the risk of leaking go routines.
type Graph interface {
// ID returns the id for this graph.
ID(ctx context.Context) string
// AddTriples adds the triples to the storage. Adding a triple that already
// exists should not fail.
AddTriples(ctx context.Context, ts []*triple.Triple) error
// RemoveTriples removes the triples from the storage. Removing triples that
// are not present on the store should not fail.
RemoveTriples(ctx context.Context, ts []*triple.Triple) error
// Objects pushes to the provided channel the objects for the given object and
// predicate. The function does not return immediately; it closes the channel before returning.
//
// Given a subject and a predicate, this method retrieves the objects of
// triples that match them. By default, if does not limit the maximum number
// of possible objects returned, unless properly specified by provided lookup
// options.
//
// If the provided predicate is immutable it will return all the possible
// subject values or the number of max elements specified. There is no
// requirement on how to sample the returned max elements.
//
// If the predicate is an unanchored temporal triple and no time anchors are
// provided in the lookup options, it will return all the available objects.
// If time anchors are provided, it will return all the values anchored in the
// provided time window. If max elements is also provided as part of the
// lookup options it will return at most max elements. There is no
// specifications on how that sample should be conducted.
Objects(ctx context.Context, s *node.Node, p *predicate.Predicate, lo *LookupOptions, objs chan<- *triple.Object) error
// Subject pushes to the provided channel the subjects for the give predicate
// and object. The function does not return immediately; it closes the channel before returning.
// The caller is expected to detach them into a go routine.
//
// Given a predicate and an object, this method retrieves the subjects of
// triples that matches them. By default, it does not limit the maximum number
// of possible subjects returned, unless properly specified by provided lookup
// options.
//
// If the provided predicate is immutable it will return all the possible
// subject values or the number of max elements specified. There is no
// requirement on how to sample the returned max elements.
//
// If the predicate is an unanchored temporal triple and no time anchors are
// provided in the lookup options, it will return all the available subjects.
// If time anchors are provided, it will return all the values anchored in the
// provided time window. If max elements is also provided as part of the
// lookup options it will return the at most max elements. There is no
// specifications on how that sample should be conducted.
Subjects(ctx context.Context, p *predicate.Predicate, o *triple.Object, lo *LookupOptions, subs chan<- *node.Node) error
// PredicatesForSubject pushes to the provided channel all the predicates
// known for the given subject. The function does not return immediately; it closes the channel before returning.
// The caller is expected to detach them into a go routine.
//
// If the lookup options provide a max number of elements the function will
// return a sample of the available predicates. If time anchor bounds are
// provided in the lookup options, only predicates matching the provided
// type window would be return. Same sampling consideration apply if max
// element is provided.
PredicatesForSubject(ctx context.Context, s *node.Node, lo *LookupOptions, prds chan<- *predicate.Predicate) error
// PredicatesForObject pushes to the provided channel all the predicates known
// for the given object. The function does not return immediately; it closes the channel before returning.
// The caller is expected to detach them into a go routine.
//
// If the lookup options provide a max number of elements the function will
// return a sample of the available predicates. If time anchor bounds are
// provided in the lookup options, only predicates matching the provided type
// window would be return. Same sampling consideration apply if max element
// is provided.
PredicatesForObject(ctx context.Context, o *triple.Object, lo *LookupOptions, prds chan<- *predicate.Predicate) error
// PredicatesForSubjectAndObject pushes to the provided channel all predicates
// available for the given subject and object. The function does not return immediately; it closes the channel before returning.
// The caller is expected to detach them into a go routine.
//
// If the lookup options provide a max number of elements the function will
// return a sample of the available predicates. If time anchor bounds are
// provided in the lookup options, only predicates matching the provided type
// window would be return. Same sampling consideration apply if max element is
// provided.
PredicatesForSubjectAndObject(ctx context.Context, s *node.Node, o *triple.Object, lo *LookupOptions, prds chan<- *predicate.Predicate) error
// TriplesForSubject pushes to the provided channel all triples available for
// the given subject. The function does not return immediately; it closes the channel before returning.
// The caller is expected to detach them into a go routine.
//
// If the lookup options provide a max number of elements the function will
// return a sample of the available triples. If time anchor bounds are
// provided in the lookup options, only predicates matching the provided type
// window would be return. Same sampling consideration apply if max element is
// provided.
TriplesForSubject(ctx context.Context, s *node.Node, lo *LookupOptions, trpls chan<- *triple.Triple) error
// TriplesForPredicate pushes to the provided channel all triples available
// for the given predicate.The function does not return immediately; it closes the channel before returning.
// The caller is expected to detach them into a go routine.
//
// If the lookup options provide a max number of elements the function will
// return a sample of the available triples. If time anchor bounds are
// provided in the lookup options, only predicates matching the provided type
// window would be return. Same sampling consideration apply if max element is
// provided.
TriplesForPredicate(ctx context.Context, p *predicate.Predicate, lo *LookupOptions, trpls chan<- *triple.Triple) error
// TriplesForObject pushes to the provided channel all triples available for
// the given object. The function does not return immediately; it closes the channel before returning.
// The caller is expected to detach them into a go routine.
//
// If the lookup options provide a max number of elements the function will
// return a sample of the available triples. If time anchor bounds are
// provided in the lookup options, only predicates matching the provided type
// window would be return. Same sampling consideration apply if max element is
// provided.
TriplesForObject(ctx context.Context, o *triple.Object, lo *LookupOptions, trpls chan<- *triple.Triple) error
// TriplesForSubjectAndPredicate pushes to the provided channel all triples
// available for the given subject and predicate. The function does not return immediately; it closes the channel before returning.
// The caller is expected to detach them into a go routine.
//
// If the lookup options provide a max number of elements the function will
// return a sample of the available triples. If time anchor bounds are
// provided in the lookup options, only predicates matching the provided type
// window would be return. Same sampling consideration apply if max element is
// provided.
TriplesForSubjectAndPredicate(ctx context.Context, s *node.Node, p *predicate.Predicate, lo *LookupOptions, trpls chan<- *triple.Triple) error
// TriplesForPredicateAndObject pushes to the provided channel all triples
// available for the given predicate and object. The function does not return immediately; it closes the channel before returning.
// The caller is expected to detach them into a go routine.
//
// If the lookup options provide a max number of elements the function will
// return a sample of the available triples. If time anchor bounds are
// provided in the lookup options, only predicates matching the provided type
// window would be return. Same sampling consideration apply if max element is
// provided.
TriplesForPredicateAndObject(ctx context.Context, p *predicate.Predicate, o *triple.Object, lo *LookupOptions, trpls chan<- *triple.Triple) error
// Exist checks if the provided triple exists on the store.
Exist(ctx context.Context, t *triple.Triple) (bool, error)
// Triples pushes to the provided channel all available triples in the graph.
// The function does not return immediately but spawns a goroutine to satisfy
// elements in the channel.
Triples(ctx context.Context, lo *LookupOptions, trpls chan<- *triple.Triple) error
}