github.com/cayleygraph/cayley@v0.7.7/graph/memstore/all_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 memstore 16 17 import ( 18 "context" 19 20 "github.com/cayleygraph/cayley/graph" 21 ) 22 23 var _ graph.IteratorFuture = (*AllIterator)(nil) 24 25 type AllIterator struct { 26 it *allIterator 27 graph.Iterator 28 } 29 30 func newAllIterator(qs *QuadStore, nodes bool, maxid int64) *AllIterator { 31 it := &AllIterator{ 32 it: newAllIterator2(qs, nodes, maxid), 33 } 34 it.Iterator = graph.NewLegacy(it.it, it) 35 return it 36 } 37 38 func (it *AllIterator) AsShape() graph.IteratorShape { 39 it.Close() 40 return it.it 41 } 42 43 var _ graph.IteratorShape = (*allIterator)(nil) 44 45 type allIterator struct { 46 qs *QuadStore 47 all []*primitive 48 maxid int64 // id of last observed insert (prim id) 49 nodes bool 50 } 51 52 func newAllIterator2(qs *QuadStore, nodes bool, maxid int64) *allIterator { 53 return &allIterator{ 54 qs: qs, all: qs.cloneAll(), nodes: nodes, 55 maxid: maxid, 56 } 57 } 58 59 func (it *allIterator) Iterate() graph.Scanner { 60 return newAllIteratorNext(it.qs, it.nodes, it.maxid, it.all) 61 } 62 63 func (it *allIterator) Lookup() graph.Index { 64 return newAllIteratorContains(it.qs, it.nodes, it.maxid) 65 } 66 67 func (it *allIterator) AsLegacy() graph.Iterator { 68 it2 := &AllIterator{it: it} 69 it2.Iterator = graph.NewLegacy(it, it2) 70 return it2 71 } 72 73 func (it *allIterator) SubIterators() []graph.IteratorShape { return nil } 74 func (it *allIterator) Optimize(ctx context.Context) (graph.IteratorShape, bool) { 75 return it, false 76 } 77 78 func (it *allIterator) String() string { 79 return "MemStoreAll" 80 } 81 82 func (it *allIterator) Stats(ctx context.Context) (graph.IteratorCosts, error) { 83 return graph.IteratorCosts{ 84 NextCost: 1, 85 ContainsCost: 1, 86 Size: graph.Size{ 87 // TODO(dennwc): use maxid? 88 Size: int64(len(it.all)), 89 Exact: true, 90 }, 91 }, nil 92 } 93 94 func (p *primitive) filter(isNode bool, maxid int64) bool { 95 if p.ID > maxid { 96 return false 97 } else if isNode && p.Value != nil { 98 return true 99 } else if !isNode && !p.Quad.Zero() { 100 return true 101 } 102 return false 103 } 104 105 type allIteratorNext struct { 106 qs *QuadStore 107 all []*primitive 108 maxid int64 // id of last observed insert (prim id) 109 nodes bool 110 111 i int // index into qs.all 112 cur *primitive 113 done bool 114 } 115 116 func newAllIteratorNext(qs *QuadStore, nodes bool, maxid int64, all []*primitive) *allIteratorNext { 117 return &allIteratorNext{ 118 qs: qs, all: all, nodes: nodes, 119 i: -1, maxid: maxid, 120 } 121 } 122 123 func (it *allIteratorNext) ok(p *primitive) bool { 124 return p.filter(it.nodes, it.maxid) 125 } 126 127 func (it *allIteratorNext) Next(ctx context.Context) bool { 128 it.cur = nil 129 if it.done { 130 return false 131 } 132 all := it.all 133 if it.i >= len(all) { 134 it.done = true 135 return false 136 } 137 it.i++ 138 for ; it.i < len(all); it.i++ { 139 p := all[it.i] 140 if p.ID > it.maxid { 141 break 142 } 143 if it.ok(p) { 144 it.cur = p 145 return true 146 } 147 } 148 it.done = true 149 return false 150 } 151 152 func (it *allIteratorNext) Result() graph.Ref { 153 if it.cur == nil { 154 return nil 155 } 156 if !it.cur.Quad.Zero() { 157 return qprim{p: it.cur} 158 } 159 return bnode(it.cur.ID) 160 } 161 162 func (it *allIteratorNext) Err() error { return nil } 163 func (it *allIteratorNext) Close() error { 164 it.done = true 165 it.all = nil 166 return nil 167 } 168 169 func (it *allIteratorNext) TagResults(dst map[string]graph.Ref) {} 170 171 func (it *allIteratorNext) String() string { 172 return "MemStoreAllNext" 173 } 174 func (it *allIteratorNext) NextPath(ctx context.Context) bool { return false } 175 176 type allIteratorContains struct { 177 qs *QuadStore 178 maxid int64 // id of last observed insert (prim id) 179 nodes bool 180 181 cur *primitive 182 done bool 183 } 184 185 func newAllIteratorContains(qs *QuadStore, nodes bool, maxid int64) *allIteratorContains { 186 return &allIteratorContains{ 187 qs: qs, nodes: nodes, 188 maxid: maxid, 189 } 190 } 191 192 func (it *allIteratorContains) ok(p *primitive) bool { 193 return p.filter(it.nodes, it.maxid) 194 } 195 196 func (it *allIteratorContains) Contains(ctx context.Context, v graph.Ref) bool { 197 it.cur = nil 198 if it.done { 199 return false 200 } 201 id, ok := asID(v) 202 if !ok { 203 return false 204 } 205 p := it.qs.prim[id] 206 if p.ID > it.maxid { 207 return false 208 } 209 if !it.ok(p) { 210 return false 211 } 212 it.cur = p 213 return true 214 } 215 func (it *allIteratorContains) Result() graph.Ref { 216 if it.cur == nil { 217 return nil 218 } 219 if !it.cur.Quad.Zero() { 220 return qprim{p: it.cur} 221 } 222 return bnode(it.cur.ID) 223 } 224 225 func (it *allIteratorContains) Err() error { return nil } 226 func (it *allIteratorContains) Close() error { 227 it.done = true 228 return nil 229 } 230 231 func (it *allIteratorContains) TagResults(dst map[string]graph.Ref) {} 232 233 func (it *allIteratorContains) String() string { 234 return "MemStoreAllContains" 235 } 236 func (it *allIteratorContains) NextPath(ctx context.Context) bool { return false }