github.com/cayleygraph/cayley@v0.7.7/graph/iterator/iterator.go (about) 1 // Copyright 2014 The Cayley Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package iterator 16 17 // Define the general iterator interface. 18 19 import ( 20 "context" 21 "fmt" 22 23 "github.com/cayleygraph/cayley/graph" 24 ) 25 26 var ( 27 _ graph.Iterator = &Null{} 28 _ graph.Iterator = &Error{} 29 ) 30 31 type Morphism func(graph.Iterator) graph.Iterator 32 type Morphism2 func(graph.IteratorShape) graph.IteratorShape 33 34 func IsNull(it graph.Iterator) bool { 35 if _, ok := it.(*Null); ok { 36 return true 37 } else if _, ok := graph.AsShape(it).(*null); ok { 38 return true 39 } 40 return false 41 } 42 43 func IsNull2(it graph.IteratorShape) bool { 44 if _, ok := it.(*null); ok { 45 return true 46 } else if _, ok := graph.AsLegacy(it).(*Null); ok { 47 return true 48 } 49 return false 50 } 51 52 // Here we define the simplest iterator -- the Null iterator. It contains nothing. 53 // It is the empty set. Often times, queries that contain one of these match nothing, 54 // so it's important to give it a special iterator. 55 type Null struct{} 56 57 // Fairly useless New function. 58 func NewNull() *Null { 59 return &Null{} 60 } 61 62 // Fill the map based on the tags assigned to this iterator. 63 func (it *Null) TagResults(dst map[string]graph.Ref) {} 64 65 func (it *Null) Contains(ctx context.Context, v graph.Ref) bool { 66 return false 67 } 68 69 // A good iterator will close itself when it returns true. 70 // Null has nothing it needs to do. 71 func (it *Null) Optimize() (graph.Iterator, bool) { return it, false } 72 73 func (it *Null) String() string { 74 return "Null" 75 } 76 77 func (it *Null) Next(ctx context.Context) bool { 78 return false 79 } 80 81 func (it *Null) Err() error { 82 return nil 83 } 84 85 func (it *Null) Result() graph.Ref { 86 return nil 87 } 88 89 func (it *Null) SubIterators() []graph.Iterator { 90 return nil 91 } 92 93 func (it *Null) NextPath(ctx context.Context) bool { 94 return false 95 } 96 97 func (it *Null) Size() (int64, bool) { 98 return 0, true 99 } 100 101 func (it *Null) Reset() {} 102 103 func (it *Null) Close() error { 104 return nil 105 } 106 107 // A null iterator costs nothing. Use it! 108 func (it *Null) Stats() graph.IteratorStats { 109 return graph.IteratorStats{} 110 } 111 112 // Error iterator always returns a single error with no other results. 113 type Error struct { 114 err error 115 } 116 117 func NewError(err error) *Error { 118 return &Error{err: err} 119 } 120 121 // Fill the map based on the tags assigned to this iterator. 122 func (it *Error) TagResults(dst map[string]graph.Ref) {} 123 124 func (it *Error) Contains(ctx context.Context, v graph.Ref) bool { 125 return false 126 } 127 128 func (it *Error) Optimize() (graph.Iterator, bool) { return it, false } 129 130 func (it *Error) String() string { 131 return fmt.Sprintf("Error(%v)", it.err) 132 } 133 134 func (it *Error) Next(ctx context.Context) bool { 135 return false 136 } 137 138 func (it *Error) Err() error { 139 return it.err 140 } 141 142 func (it *Error) Result() graph.Ref { 143 return nil 144 } 145 146 func (it *Error) SubIterators() []graph.Iterator { 147 return nil 148 } 149 150 func (it *Error) NextPath(ctx context.Context) bool { 151 return false 152 } 153 154 func (it *Error) Size() (int64, bool) { 155 return 0, true 156 } 157 158 func (it *Error) Reset() {} 159 160 func (it *Error) Close() error { 161 return it.err 162 } 163 164 func (it *Error) Stats() graph.IteratorStats { 165 return graph.IteratorStats{} 166 } 167 168 var ( 169 _ graph.IteratorShapeCompat = &null{} 170 _ graph.IteratorShapeCompat = &error2{} 171 ) 172 173 // Here we define the simplest iterator -- the Null iterator. It contains nothing. 174 // It is the empty set. Often times, queries that contain one of these match nothing, 175 // so it's important to give it a special iterator. 176 type null struct{} 177 178 // Fairly useless New function. 179 func newNull() *null { 180 return &null{} 181 } 182 183 func (it *null) Iterate() graph.Scanner { 184 return it 185 } 186 187 func (it *null) Lookup() graph.Index { 188 return it 189 } 190 191 func (it *null) AsLegacy() graph.Iterator { 192 return NewNull() 193 } 194 195 // Fill the map based on the tags assigned to this iterator. 196 func (it *null) TagResults(dst map[string]graph.Ref) {} 197 198 func (it *null) Contains(ctx context.Context, v graph.Ref) bool { 199 return false 200 } 201 202 // A good iterator will close itself when it returns true. 203 // Null has nothing it needs to do. 204 func (it *null) Optimize(ctx context.Context) (graph.IteratorShape, bool) { return it, false } 205 206 func (it *null) String() string { 207 return "Null" 208 } 209 210 func (it *null) Next(ctx context.Context) bool { 211 return false 212 } 213 214 func (it *null) Err() error { 215 return nil 216 } 217 218 func (it *null) Result() graph.Ref { 219 return nil 220 } 221 222 func (it *null) SubIterators() []graph.IteratorShape { 223 return nil 224 } 225 226 func (it *null) NextPath(ctx context.Context) bool { 227 return false 228 } 229 230 func (it *null) Reset() {} 231 232 func (it *null) Close() error { 233 return nil 234 } 235 236 // A null iterator costs nothing. Use it! 237 func (it *null) Stats(ctx context.Context) (graph.IteratorCosts, error) { 238 return graph.IteratorCosts{}, nil 239 } 240 241 // Error iterator always returns a single error with no other results. 242 type error2 struct { 243 err error 244 } 245 246 func newError2(err error) *error2 { 247 return &error2{err: err} 248 } 249 250 func (it *error2) Iterate() graph.Scanner { 251 return it 252 } 253 254 func (it *error2) Lookup() graph.Index { 255 return it 256 } 257 258 func (it *error2) AsLegacy() graph.Iterator { 259 return NewError(it.err) 260 } 261 262 // Fill the map based on the tags assigned to this iterator. 263 func (it *error2) TagResults(dst map[string]graph.Ref) {} 264 265 func (it *error2) Contains(ctx context.Context, v graph.Ref) bool { 266 return false 267 } 268 269 func (it *error2) Optimize(ctx context.Context) (graph.IteratorShape, bool) { return it, false } 270 271 func (it *error2) String() string { 272 return fmt.Sprintf("Error(%v)", it.err) 273 } 274 275 func (it *error2) Next(ctx context.Context) bool { 276 return false 277 } 278 279 func (it *error2) Err() error { 280 return it.err 281 } 282 283 func (it *error2) Result() graph.Ref { 284 return nil 285 } 286 287 func (it *error2) SubIterators() []graph.IteratorShape { 288 return nil 289 } 290 291 func (it *error2) NextPath(ctx context.Context) bool { 292 return false 293 } 294 295 func (it *error2) Reset() {} 296 297 func (it *error2) Close() error { 298 return it.err 299 } 300 301 func (it *error2) Stats(ctx context.Context) (graph.IteratorCosts, error) { 302 return graph.IteratorCosts{}, nil 303 }