func checkIteratorContains(ts graph.TripleStore, it graph.Iterator, expected []string, t *testing.T) { var actual []string actual = nil for { val, ok := it.Next() if !ok { break } actual = append(actual, ts.GetNameFor(val)) } actualSet := actual[:] for _, a := range expected { found := false for j, b := range actualSet { if a == b { actualSet = append(actualSet[:j], actualSet[j+1:]...) found = true break } } if !found { t.Error("Couldn't find", a, "in actual output.\nActual:", actual, "\nExpected: ", expected, "\nRemainder: ", actualSet) return } } if len(actualSet) != 0 { t.Error("Actual output has more than expected.\nActual:", actual, "\nExpected: ", expected, "\nRemainder: ", actualSet) } }
func runIteratorWithCallback(it graph.Iterator, ses *Session, callback otto.Value, this otto.FunctionCall, limit int) { count := 0 it, _ = it.Optimize() for { if ses.doHalt { return } _, ok := graph.Next(it) if !ok { break } tags := make(map[string]graph.Value) it.TagResults(tags) val, _ := this.Otto.ToValue(tagsToValueMap(tags, ses)) val, _ = callback.Call(this.This, val) count++ if limit >= 0 && count >= limit { break } for it.NextResult() == true { if ses.doHalt { return } tags := make(map[string]graph.Value) it.TagResults(tags) val, _ := this.Otto.ToValue(tagsToValueMap(tags, ses)) val, _ = callback.Call(this.This, val) count++ if limit >= 0 && count >= limit { break } } } it.Close() }
func runIteratorToArray(it graph.Iterator, ses *Session, limit int) []map[string]string { output := make([]map[string]string, 0) count := 0 it, _ = it.Optimize() for { if ses.doHalt { return nil } _, ok := graph.Next(it) if !ok { break } tags := make(map[string]graph.Value) it.TagResults(tags) output = append(output, tagsToValueMap(tags, ses)) count++ if limit >= 0 && count >= limit { break } for it.NextResult() == true { if ses.doHalt { return nil } tags := make(map[string]graph.Value) it.TagResults(tags) output = append(output, tagsToValueMap(tags, ses)) count++ if limit >= 0 && count >= limit { break } } } it.Close() return output }
func iterated(it graph.Iterator) []int { var res []int for graph.Next(it) { res = append(res, it.Result().(int)) } return res }
func TestIterators(t *testing.T) { qs, opts, closer := makeGAE(t) defer closer() graphtest.MakeWriter(t, qs, opts, graphtest.MakeQuadSet()...) require.Equal(t, int64(11), qs.Size(), "Incorrect number of quads") var expected = []quad.Quad{ quad.Make("C", "follows", "B", ""), quad.Make("C", "follows", "D", ""), } it := qs.QuadIterator(quad.Subject, qs.ValueOf(quad.Raw("C"))) graphtest.ExpectIteratedQuads(t, qs, it, expected) // Test contains it = qs.QuadIterator(quad.Label, qs.ValueOf(quad.Raw("status_graph"))) gqs := qs.(*QuadStore) key := gqs.createKeyForQuad(quad.Make("G", "status", "cool", "status_graph")) token := &Token{quadKind, key.StringID()} require.True(t, it.Contains(token), "Contains failed") // Test cloning an iterator var it2 graph.Iterator it2 = it.Clone() x := it2.Describe() y := it.Describe() require.Equal(t, y.Name, x.Name, "Iterator Clone was not successful") }
func (ts *QuadStore) OptimizeIterator(it graph.Iterator) (graph.Iterator, bool) { switch it.Type() { case graph.LinksTo: return ts.optimizeLinksTo(it.(*iterator.LinksTo)) } return it, false }
func (ts *MongoTripleStore) OptimizeIterator(it graph.Iterator) (graph.Iterator, bool) { switch it.Type() { case "linksto": return ts.optimizeLinksTo(it.(*graph.LinksToIterator)) } return it, false }
func iteratedNames(qs graph.QuadStore, it graph.Iterator) []string { var res []string for graph.Next(it) { res = append(res, qs.NameOf(it.Result())) } sort.Strings(res) return res }
func iteratedQuads(qs graph.QuadStore, it graph.Iterator) []quad.Quad { var res ordered for graph.Next(it) { res = append(res, qs.Quad(it.Result())) } sort.Sort(res) return res }
func IteratedRawStrings(t testing.TB, qs graph.QuadStore, it graph.Iterator) []string { var res []string for graph.Next(it) { res = append(res, qs.NameOf(it.Result()).String()) } require.Nil(t, it.Err()) sort.Strings(res) return res }
func IteratedValues(t testing.TB, qs graph.QuadStore, it graph.Iterator) []quad.Value { var res []quad.Value for graph.Next(it) { res = append(res, qs.NameOf(it.Result())) } require.Nil(t, it.Err()) sort.Sort(quad.ByValueString(res)) return res }
func IteratedQuads(t testing.TB, qs graph.QuadStore, it graph.Iterator) []quad.Quad { var res quad.ByQuadString for graph.Next(it) { res = append(res, qs.Quad(it.Result())) } require.Nil(t, it.Err()) sort.Sort(res) return res }
func (it *Iterator) Clone() graph.Iterator { var newM graph.Iterator if it.isAll { newM = NewAllIterator(it.ts, it.collection) } else { newM = NewIterator(it.ts, it.collection, it.dir, it.hash) } newM.CopyTagsFrom(it) return newM }
func (it *Base) CopyTagsFrom(other_it graph.Iterator) { for _, tag := range other_it.Tags() { it.AddTag(tag) } for k, v := range other_it.FixedTags() { it.AddFixedTag(k, v) } }
func (qs *QuadStore) OptimizeIterator(it graph.Iterator) (graph.Iterator, bool) { switch it.Type() { case graph.LinksTo: return qs.optimizeLinksTo(it.(*iterator.LinksTo)) case graph.HasA: return qs.optimizeHasA(it.(*iterator.HasA)) case graph.And: return qs.optimizeAnd(it.(*iterator.And)) } return it, false }
func OutputQueryShapeForIterator(it graph.Iterator, ts graph.TripleStore, outputMap map[string]interface{}) { qs := &queryShape{ ts: ts, nodeId: 1, } node := qs.MakeNode(it.Clone()) qs.AddNode(node) outputMap["nodes"] = qs.nodes outputMap["links"] = qs.links }
func extractNumbersFromIterator(it graph.Iterator) []int { var outputNumbers []int for { val, ok := it.Next() if !ok { break } outputNumbers = append(outputNumbers, val.(int)) } return outputNumbers }
// moveTagsTo() gets the tags for all of the src's subiterators and the // src itself, and moves them to dst. func moveTagsTo(dst graph.Iterator, src *And) { tags := src.getSubTags() for _, tag := range dst.Tags() { if _, ok := tags[tag]; ok { delete(tags, tag) } } for k := range tags { dst.AddTag(k) } }
func (qs *QuadStore) OptimizeIterator(it graph.Iterator) (graph.Iterator, bool) { switch it.Type() { case graph.LinksTo: return qs.optimizeLinksTo(it.(*iterator.LinksTo)) case graph.And: return qs.optimizeAndIterator(it.(*iterator.And)) case graph.Comparison: return qs.optimizeComparison(it.(*iterator.Comparison)) } return it, false }
func iterated(it graph.Iterator) []int { var res []int for { val, ok := it.Next() if !ok { break } res = append(res, val.(int)) } return res }
func OutputQueryShapeForIterator(it graph.Iterator, qs graph.QuadStore, outputMap map[string]interface{}) { s := &queryShape{ qs: qs, nodeId: 1, } node := s.MakeNode(it.Clone()) s.AddNode(node) outputMap["nodes"] = s.nodes outputMap["links"] = s.links }
func extractValuesFromIterator(ts graph.TripleStore, it graph.Iterator) []string { var output []string for { val, ok := it.Next() if !ok { break } output = append(output, ts.GetNameFor(val)) } return output }
func extractTripleFromIterator(ts graph.TripleStore, it graph.Iterator) []string { var output []string for { val, ok := it.Next() if !ok { break } output = append(output, ts.GetTriple(val).ToString()) } return output }
func iteratedNames(ts graph.TripleStore, it graph.Iterator) []string { var res []string for { val, ok := it.Next() if !ok { break } res = append(res, ts.NameOf(val)) } sort.Strings(res) return res }
func iteratedTriples(ts graph.TripleStore, it graph.Iterator) []*graph.Triple { var res ordered for { val, ok := it.Next() if !ok { break } res = append(res, ts.Triple(val)) } sort.Sort(res) return res }
func TestOptimize(t *testing.T) { var ts *LevelDBTripleStore var lto graph.Iterator var tmpDir string Convey("Given a prepared database", t, func() { tmpDir, _ = ioutil.TempDir(os.TempDir(), "cayley_test") t.Log(tmpDir) defer os.RemoveAll(tmpDir) ok := CreateNewLevelDB(tmpDir) So(ok, ShouldBeTrue) ts = NewDefaultLevelDBTripleStore(tmpDir, nil) ts.AddTripleSet(makeTripleSet()) Convey("With an linksto-fixed pair", func() { fixed := ts.MakeFixed() fixed.AddValue(ts.GetIdFor("F")) fixed.AddTag("internal") lto = graph.NewLinksToIterator(ts, fixed, "o") Convey("Creates an appropriate iterator", func() { oldIt := lto.Clone() newIt, ok := lto.Optimize() So(ok, ShouldBeTrue) So(newIt.Type(), ShouldEqual, "leveldb") Convey("Containing the right things", func() { afterOp := extractTripleFromIterator(ts, newIt) beforeOp := extractTripleFromIterator(ts, oldIt) sort.Strings(afterOp) sort.Strings(beforeOp) So(afterOp, ShouldResemble, beforeOp) }) Convey("With the correct tags", func() { oldIt.Next() newIt.Next() oldResults := make(map[string]graph.TSVal) oldIt.TagResults(&oldResults) newResults := make(map[string]graph.TSVal) oldIt.TagResults(&newResults) So(newResults, ShouldResemble, oldResults) }) }) }) }) }
func (q *Query) buildIteratorTreeInternal(query interface{}, path Path) (graph.Iterator, error) { var it graph.Iterator var err error err = nil switch t := query.(type) { case bool: // for JSON booleans // Treat the bool as a string and call it a day. // Things which are really bool-like are special cases and will be dealt with separately. if t { it = q.buildFixed("true") } it = q.buildFixed("false") case float64: // for JSON numbers // Damn you, Javascript, and your lack of integer values. if math.Floor(t) == t { // Treat it like an integer. it = q.buildFixed(fmt.Sprintf("%d", t)) } else { it = q.buildFixed(fmt.Sprintf("%f", t)) } case string: // for JSON strings it = q.buildFixed(t) case []interface{}: // for JSON arrays q.isRepeated[path] = true if len(t) == 0 { it = q.buildResultIterator(path) } else if len(t) == 1 { it, err = q.buildIteratorTreeInternal(t[0], path) } else { err = errors.New(fmt.Sprintf("Multiple fields at location root%s", path.DisplayString())) } case map[string]interface{}: // for JSON objects it, err = q.buildIteratorTreeMapInternal(t, path) case nil: it = q.buildResultIterator(path) default: log.Fatal("Unknown JSON type?", query) } if err != nil { return nil, err } it.AddTag(string(path)) return it, nil }
func TestIterators(t *testing.T) { glog.Info("\n-----------\n") inst, opts, err := createInstance() defer inst.Close() if err != nil { t.Fatalf("failed to create instance: %v", err) } qs, _, _ := makeTestStore(simpleGraph, opts) if qs.Size() != 11 { t.Fatal("Incorrect number of quads") } var expected = []string{ quad.Quad{"C", "follows", "B", ""}.String(), quad.Quad{"C", "follows", "D", ""}.String(), } it := qs.QuadIterator(quad.Subject, qs.ValueOf("C")) if got, ok := compareResults(qs, it, expected); !ok { t.Errorf("Unexpected iterated result, got:%v expect:%v", got, expected) } // Test contains it = qs.QuadIterator(quad.Label, qs.ValueOf("status_graph")) gqs := qs.(*QuadStore) key := gqs.createKeyForQuad(quad.Quad{"G", "status", "cool", "status_graph"}) token := &Token{quadKind, key.StringID()} if !it.Contains(token) { t.Error("Contains failed") } // Test cloning an iterator var it2 graph.Iterator it2 = it.Clone() x := it2.Describe() y := it.Describe() if x.Name != y.Name { t.Errorf("Iterator Clone was not successful got: %v, expected: %v", x.Name, y.Name) } }
func runIteratorToArrayNoTags(it graph.Iterator, ses *Session, limit int) []string { output := make([]string, 0) count := 0 it, _ = it.Optimize() for { if ses.doHalt { return nil } val, ok := graph.Next(it) if !ok { break } output = append(output, ses.ts.NameOf(val)) count++ if limit >= 0 && count >= limit { break } } it.Close() return output }
func buildInOutIterator(obj *otto.Object, ts graph.TripleStore, base graph.Iterator, isReverse bool) graph.Iterator { argList, _ := obj.Get("_gremlin_values") if argList.Class() != "GoArray" { glog.Errorln("How is arglist not an array? Return nothing.", argList.Class()) return graph.NewNullIterator() } argArray := argList.Object() lengthVal, _ := argArray.Get("length") length, _ := lengthVal.ToInteger() var predicateNodeIterator graph.Iterator if length == 0 { predicateNodeIterator = ts.GetNodesAllIterator() } else { zero, _ := argArray.Get("0") predicateNodeIterator = buildIteratorFromValue(zero, ts) } if length >= 2 { var tags []string one, _ := argArray.Get("1") if one.IsString() { s, _ := one.ToString() tags = append(tags, s) } else if one.Class() == "Array" { tags = makeListOfStringsFromArrayValue(one.Object()) } for _, tag := range tags { predicateNodeIterator.AddTag(tag) } } in, out := graph.Subject, graph.Object if isReverse { in, out = out, in } lto := graph.NewLinksToIterator(ts, base, in) and := graph.NewAndIterator() and.AddSubIterator(graph.NewLinksToIterator(ts, predicateNodeIterator, graph.Predicate)) and.AddSubIterator(lto) return graph.NewHasaIterator(ts, and, out) }