github.com/cayleygraph/cayley@v0.7.7/graph/iterator/save.go (about)

     1  package iterator
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/cayleygraph/cayley/graph"
     8  )
     9  
    10  var (
    11  	_ graph.IteratorFuture = (*Save)(nil)
    12  	_ graph.Tagger         = (*Save)(nil)
    13  )
    14  
    15  func Tag(it graph.Iterator, tag string) graph.Iterator {
    16  	if s, ok := it.(graph.Tagger); ok {
    17  		s.AddTags(tag)
    18  		return s
    19  	} else if s, ok := graph.AsShape(it).(graph.TaggerShape); ok {
    20  		s.AddTags(tag)
    21  		return graph.AsLegacy(s)
    22  	}
    23  	return NewSave(it, tag)
    24  }
    25  
    26  func TagShape(it graph.IteratorShape, tag string) graph.IteratorShape {
    27  	if s, ok := it.(graph.TaggerShape); ok {
    28  		s.AddTags(tag)
    29  		return s
    30  	} else if s, ok := graph.AsLegacy(it).(graph.Tagger); ok {
    31  		s.AddTags(tag)
    32  		return graph.AsShape(s)
    33  	}
    34  	return newSave(it, tag)
    35  }
    36  
    37  func NewSave(on graph.Iterator, tags ...string) *Save {
    38  	it := &Save{
    39  		it: newSave(graph.AsShape(on), tags...),
    40  	}
    41  	it.Iterator = graph.NewLegacy(it.it, it)
    42  	return it
    43  }
    44  
    45  type Save struct {
    46  	it *save
    47  	graph.Iterator
    48  }
    49  
    50  func (it *Save) AsShape() graph.IteratorShape {
    51  	it.Close()
    52  	return it.it
    53  }
    54  
    55  // Add a tag to the iterator.
    56  func (it *Save) AddTags(tag ...string) {
    57  	it.it.AddTags(tag...)
    58  }
    59  
    60  func (it *Save) AddFixedTag(tag string, value graph.Ref) {
    61  	it.it.AddFixedTag(tag, value)
    62  }
    63  
    64  // Tags returns the tags held in the tagger. The returned value must not be mutated.
    65  func (it *Save) Tags() []string {
    66  	return it.it.Tags()
    67  }
    68  
    69  // Fixed returns the fixed tags held in the tagger. The returned value must not be mutated.
    70  func (it *Save) FixedTags() map[string]graph.Ref {
    71  	return it.it.FixedTags()
    72  }
    73  
    74  func (it *Save) CopyFromTagger(st graph.TaggerBase) {
    75  	it.it.CopyFromTagger(st)
    76  }
    77  
    78  var (
    79  	_ graph.IteratorShapeCompat = (*save)(nil)
    80  	_ graph.TaggerShape         = (*save)(nil)
    81  )
    82  
    83  func newSave(on graph.IteratorShape, tags ...string) *save {
    84  	s := &save{it: on}
    85  	s.AddTags(tags...)
    86  	return s
    87  }
    88  
    89  type save struct {
    90  	it        graph.IteratorShape
    91  	tags      []string
    92  	fixedTags map[string]graph.Ref
    93  }
    94  
    95  func (it *save) Iterate() graph.Scanner {
    96  	return newSaveNext(it.it.Iterate(), it.tags, it.fixedTags)
    97  }
    98  
    99  func (it *save) Lookup() graph.Index {
   100  	return newSaveContains(it.it.Lookup(), it.tags, it.fixedTags)
   101  }
   102  
   103  func (it *save) AsLegacy() graph.Iterator {
   104  	it2 := &Save{it: it}
   105  	it2.Iterator = graph.NewLegacy(it, it2)
   106  	return it2
   107  }
   108  
   109  func (it *save) String() string {
   110  	return fmt.Sprintf("Save(%v, %v)", it.tags, it.fixedTags)
   111  }
   112  
   113  // Add a tag to the iterator.
   114  func (it *save) AddTags(tag ...string) {
   115  	it.tags = append(it.tags, tag...)
   116  }
   117  
   118  func (it *save) AddFixedTag(tag string, value graph.Ref) {
   119  	if it.fixedTags == nil {
   120  		it.fixedTags = make(map[string]graph.Ref)
   121  	}
   122  	it.fixedTags[tag] = value
   123  }
   124  
   125  // Tags returns the tags held in the tagger. The returned value must not be mutated.
   126  func (it *save) Tags() []string {
   127  	return it.tags
   128  }
   129  
   130  // Fixed returns the fixed tags held in the tagger. The returned value must not be mutated.
   131  func (it *save) FixedTags() map[string]graph.Ref {
   132  	return it.fixedTags
   133  }
   134  
   135  func (it *save) CopyFromTagger(st graph.TaggerBase) {
   136  	it.tags = append(it.tags, st.Tags()...)
   137  
   138  	fixed := st.FixedTags()
   139  	if len(fixed) == 0 {
   140  		return
   141  	}
   142  	if it.fixedTags == nil {
   143  		it.fixedTags = make(map[string]graph.Ref, len(fixed))
   144  	}
   145  	for k, v := range fixed {
   146  		it.fixedTags[k] = v
   147  	}
   148  }
   149  
   150  func (it *save) Stats(ctx context.Context) (graph.IteratorCosts, error) {
   151  	return it.it.Stats(ctx)
   152  }
   153  
   154  func (it *save) Optimize(ctx context.Context) (nit graph.IteratorShape, no bool) {
   155  	sub, ok := it.it.Optimize(ctx)
   156  	if len(it.tags) == 0 && len(it.fixedTags) == 0 {
   157  		return sub, true
   158  	}
   159  	if st, ok2 := sub.(graph.TaggerShape); ok2 {
   160  		st.CopyFromTagger(it)
   161  		return st, true
   162  	} else if st, ok2 := graph.AsLegacy(sub).(graph.Tagger); ok2 {
   163  		st.CopyFromTagger(it)
   164  		return graph.AsShape(st), true
   165  	}
   166  	if !ok {
   167  		return it, false
   168  	}
   169  	s := newSave(sub)
   170  	s.CopyFromTagger(it)
   171  	return s, true
   172  }
   173  
   174  func (it *save) SubIterators() []graph.IteratorShape {
   175  	return []graph.IteratorShape{it.it}
   176  }
   177  
   178  func newSaveNext(it graph.Scanner, tags []string, fixed map[string]graph.Ref) *saveNext {
   179  	return &saveNext{it: it, tags: tags, fixedTags: fixed}
   180  }
   181  
   182  type saveNext struct {
   183  	it        graph.Scanner
   184  	tags      []string
   185  	fixedTags map[string]graph.Ref
   186  }
   187  
   188  func (it *saveNext) String() string {
   189  	return fmt.Sprintf("Save(%v, %v)", it.tags, it.fixedTags)
   190  }
   191  
   192  func (it *saveNext) TagResults(dst map[string]graph.Ref) {
   193  	it.it.TagResults(dst)
   194  
   195  	v := it.Result()
   196  	for _, tag := range it.tags {
   197  		dst[tag] = v
   198  	}
   199  
   200  	for tag, value := range it.fixedTags {
   201  		dst[tag] = value
   202  	}
   203  }
   204  
   205  func (it *saveNext) Result() graph.Ref {
   206  	return it.it.Result()
   207  }
   208  
   209  func (it *saveNext) Next(ctx context.Context) bool {
   210  	return it.it.Next(ctx)
   211  }
   212  
   213  func (it *saveNext) NextPath(ctx context.Context) bool {
   214  	return it.it.NextPath(ctx)
   215  }
   216  
   217  func (it *saveNext) Err() error {
   218  	return it.it.Err()
   219  }
   220  
   221  func (it *saveNext) Close() error {
   222  	return it.it.Close()
   223  }
   224  
   225  func newSaveContains(it graph.Index, tags []string, fixed map[string]graph.Ref) *saveContains {
   226  	return &saveContains{it: it, tags: tags, fixed: fixed}
   227  }
   228  
   229  type saveContains struct {
   230  	it    graph.Index
   231  	tags  []string
   232  	fixed map[string]graph.Ref
   233  }
   234  
   235  func (it *saveContains) String() string {
   236  	return fmt.Sprintf("SaveContains(%v, %v)", it.tags, it.fixed)
   237  }
   238  
   239  func (it *saveContains) TagResults(dst map[string]graph.Ref) {
   240  	it.it.TagResults(dst)
   241  
   242  	v := it.Result()
   243  	for _, tag := range it.tags {
   244  		dst[tag] = v
   245  	}
   246  
   247  	for tag, value := range it.fixed {
   248  		dst[tag] = value
   249  	}
   250  }
   251  
   252  func (it *saveContains) Result() graph.Ref {
   253  	return it.it.Result()
   254  }
   255  
   256  func (it *saveContains) NextPath(ctx context.Context) bool {
   257  	return it.it.NextPath(ctx)
   258  }
   259  
   260  func (it *saveContains) Contains(ctx context.Context, v graph.Ref) bool {
   261  	return it.it.Contains(ctx, v)
   262  }
   263  
   264  func (it *saveContains) Err() error {
   265  	return it.it.Err()
   266  }
   267  
   268  func (it *saveContains) Close() error {
   269  	return it.it.Close()
   270  }