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 }