Merge pull request #88 from kortschak/benchmarks
Add basic integration benchmarks
This commit is contained in:
commit
a81005ba21
14 changed files with 1026 additions and 611 deletions
|
|
@ -19,3 +19,6 @@ install:
|
|||
- go get github.com/syndtr/goleveldb/leveldb/util
|
||||
- go get gopkg.in/mgo.v2
|
||||
- go get gopkg.in/mgo.v2/bson
|
||||
|
||||
script: go test -v -short ./...
|
||||
|
||||
|
|
|
|||
408
cayley_test.go
Normal file
408
cayley_test.go
Normal file
|
|
@ -0,0 +1,408 @@
|
|||
// Copyright 2014 The Cayley Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/google/cayley/config"
|
||||
"github.com/google/cayley/db"
|
||||
"github.com/google/cayley/graph"
|
||||
"github.com/google/cayley/query/gremlin"
|
||||
)
|
||||
|
||||
var benchmarkQueries = []struct {
|
||||
message string
|
||||
long bool
|
||||
query string
|
||||
tag string
|
||||
expect [][]interface{}
|
||||
}{
|
||||
// Easy one to get us started. How quick is the most straightforward retrieval?
|
||||
{
|
||||
message: "name predicate",
|
||||
query: `
|
||||
g.V("Humphrey Bogart").In("name").All()
|
||||
`,
|
||||
expect: [][]interface{}{
|
||||
{map[string]string{"id": "/en/humphrey_bogart"}},
|
||||
},
|
||||
},
|
||||
|
||||
// Grunty queries.
|
||||
// 2014-07-12: This one seems to return in ~20ms in memory;
|
||||
// that's going to be measurably slower for every other backend.
|
||||
{
|
||||
message: "two large sets with no intersection",
|
||||
query: `
|
||||
function getId(x) { return g.V(x).In("name") }
|
||||
var actor_to_film = g.M().In("/film/performance/actor").In("/film/film/starring")
|
||||
|
||||
getId("Oliver Hardy").Follow(actor_to_film).Out("name").Intersect(
|
||||
getId("Mel Blanc").Follow(actor_to_film).Out("name")).All()
|
||||
`,
|
||||
expect: nil,
|
||||
},
|
||||
|
||||
// 2014-07-12: This one takes about 4 whole seconds in memory. This is a behemoth.
|
||||
{
|
||||
message: "three huge sets with small intersection",
|
||||
long: true,
|
||||
query: `
|
||||
function getId(x) { return g.V(x).In("name") }
|
||||
var actor_to_film = g.M().In("/film/performance/actor").In("/film/film/starring")
|
||||
|
||||
var a = getId("Oliver Hardy").Follow(actor_to_film).FollowR(actor_to_film)
|
||||
var b = getId("Mel Blanc").Follow(actor_to_film).FollowR(actor_to_film)
|
||||
var c = getId("Billy Gilbert").Follow(actor_to_film).FollowR(actor_to_film)
|
||||
|
||||
seen = {}
|
||||
|
||||
a.Intersect(b).Intersect(c).ForEach(function (d) {
|
||||
if (!(d.id in seen)) {
|
||||
seen[d.id] = true;
|
||||
g.Emit(d.id)
|
||||
}
|
||||
})
|
||||
`,
|
||||
expect: [][]interface{}{
|
||||
{"/en/billy_gilbert"},
|
||||
{"/en/sterling_holloway"},
|
||||
},
|
||||
},
|
||||
|
||||
// This is more of an optimization problem that will get better over time. This takes a lot
|
||||
// of wrong turns on the walk down to what is ultimately the name, but top AND has it easy
|
||||
// as it has a fixed ID. Exercises Check().
|
||||
{
|
||||
message: "the helpless checker",
|
||||
long: true,
|
||||
query: `
|
||||
g.V().As("person").In("name").In().In().Out("name").Is("Casablanca").All()
|
||||
`,
|
||||
tag: "person",
|
||||
expect: [][]interface{}{
|
||||
{map[string]string{"id": "Casablanca", "person": "Claude Rains"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "Conrad Veidt"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "Dooley Wilson"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "Helmut Dantine"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "Humphrey Bogart"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "Ingrid Bergman"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "John Qualen"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "Joy Page"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "Leonid Kinskey"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "Lou Marcelle"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "Madeleine LeBeau"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "Paul Henreid"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "Peter Lorre"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "Sydney Greenstreet"}},
|
||||
{map[string]string{"id": "Casablanca", "person": "S.Z. Sakall"}},
|
||||
},
|
||||
},
|
||||
|
||||
//Q: Who starred in both "The Net" and "Speed" ?
|
||||
//A: "Sandra Bullock"
|
||||
{
|
||||
message: "Net and Speed",
|
||||
query: common + `m1_actors.Intersect(m2_actors).Out("name").All()
|
||||
`,
|
||||
expect: [][]interface{}{
|
||||
{map[string]string{"id": "Sandra Bullock", "movie1": "The Net", "movie2": "Speed"}},
|
||||
},
|
||||
},
|
||||
|
||||
//Q: Did "Keanu Reeves" star in "The Net" ?
|
||||
//A: No
|
||||
{
|
||||
message: "Keanu in The Net",
|
||||
query: common + `actor2.Intersect(m1_actors).Out("name").All()
|
||||
`,
|
||||
expect: nil,
|
||||
},
|
||||
|
||||
//Q: Did "Keanu Reeves" star in "Speed" ?
|
||||
//A: Yes
|
||||
{
|
||||
message: "Keanu in Speed",
|
||||
query: common + `actor2.Intersect(m2_actors).Out("name").All()
|
||||
`,
|
||||
expect: [][]interface{}{
|
||||
{map[string]string{"id": "Keanu Reeves", "movie2": "Speed"}},
|
||||
},
|
||||
},
|
||||
|
||||
//Q: Has "Keanu Reeves" co-starred with anyone who starred in "The Net" ?
|
||||
//A: "Keanu Reeves" was in "Speed" and "The Lake House" with "Sandra Bullock",
|
||||
// who was in "The Net"
|
||||
{
|
||||
message: "Keanu with other in The Net",
|
||||
long: true,
|
||||
query: common + `actor2.Follow(coStars1).Intersect(m1_actors).Out("name").All()
|
||||
`,
|
||||
expect: [][]interface{}{
|
||||
{map[string]string{"id": "Sandra Bullock", "movie1": "The Net", "costar1_movie": "Speed"}},
|
||||
{map[string]string{"movie1": "The Net", "costar1_movie": "The Lake House", "id": "Sandra Bullock"}},
|
||||
},
|
||||
},
|
||||
|
||||
//Q: Do "Keanu Reeves" and "Sandra Bullock" have any commons co-stars?
|
||||
//A: Yes, many. For example: SB starred with "Steve Martin" in "The Prince
|
||||
// of Egypt", and KR starred with Steven Martin in "Parenthood".
|
||||
{
|
||||
message: "Keanu and Bullock with other",
|
||||
long: true,
|
||||
query: common + `actor1.Save("name","costar1_actor").Follow(coStars1).Intersect(actor2.Save("name","costar2_actor").Follow(coStars2)).Out("name").All()
|
||||
`,
|
||||
expect: [][]interface{}{
|
||||
{map[string]string{"costar2_movie": "Speed", "id": "Alan Ruck", "costar1_actor": "Sandra Bullock", "costar1_movie": "Speed", "costar2_actor": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_movie": "Demolition Man", "costar2_actor": "Keanu Reeves", "costar2_movie": "Thumbsucker", "id": "Benjamin Bratt", "costar1_actor": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Miss Congeniality", "costar2_actor": "Keanu Reeves", "costar2_movie": "Thumbsucker", "id": "Benjamin Bratt"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Speed", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Beth Grant"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Speed", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Carlos Carrasco"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "The Lake House", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Lake House", "id": "Christopher Plummer"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "The Proposal", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Devil's Advocate", "id": "Craig T. Nelson"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Speed", "costar2_actor": "Keanu Reeves", "costar2_movie": "River's Edge", "id": "Dennis Hopper"}},
|
||||
{map[string]string{"costar2_movie": "Speed", "id": "Dennis Hopper", "costar1_actor": "/people/person", "costar1_movie": "Chattahoochee", "costar2_actor": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Practical Magic", "costar2_actor": "Keanu Reeves", "costar2_movie": "Parenthood", "id": "Dianne Wiest"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "The Lake House", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Lake House", "id": "Dylan Walsh"}},
|
||||
{map[string]string{"costar2_movie": "Speed", "id": "Glenn Plummer", "costar1_actor": "Sandra Bullock", "costar1_movie": "Speed", "costar2_actor": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Speed 2: Cruise Control", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Glenn Plummer"}},
|
||||
{map[string]string{"costar1_movie": "While You Were Sleeping", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Replacements", "id": "Jack Warden", "costar1_actor": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Infamous", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Jeff Daniels"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Speed", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Jeff Daniels"}},
|
||||
{map[string]string{"id": "Joe Morton", "costar1_actor": "Sandra Bullock", "costar1_movie": "Speed", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed"}},
|
||||
{map[string]string{"costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Jordan Lund", "costar1_actor": "Sandra Bullock", "costar1_movie": "Speed"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Speed", "costar2_actor": "Keanu Reeves", "costar2_movie": "Flying", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "The Lake House", "costar2_actor": "Keanu Reeves", "costar2_movie": "Flying", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_movie": "The Day the Earth Stood Still", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Animatrix", "id": "Keanu Reeves", "costar1_actor": "/people/person"}},
|
||||
{map[string]string{"id": "Keanu Reeves", "costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Tune in Tomorrow"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Last Time I Committed Suicide", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Constantine", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Permanent Record", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar2_movie": "Dangerous Liaisons", "id": "Keanu Reeves", "costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Private Lives of Pippa Lee", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar2_movie": "A Scanner Darkly", "id": "Keanu Reeves", "costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "A Walk in the Clouds", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Hardball", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Life Under Water", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Much Ado About Nothing", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "My Own Private Idaho", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Parenthood", "id": "Keanu Reeves", "costar1_actor": "/people/person"}},
|
||||
{map[string]string{"costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Point Break", "id": "Keanu Reeves", "costar1_actor": "/people/person"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Providence", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "River's Edge", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar2_movie": "Something's Gotta Give", "id": "Keanu Reeves", "costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves"}},
|
||||
{map[string]string{"costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Keanu Reeves", "costar1_actor": "/people/person", "costar1_movie": "/film/film"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Sweet November", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Lake House", "id": "Keanu Reeves", "costar1_actor": "/people/person"}},
|
||||
{map[string]string{"id": "Keanu Reeves", "costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Matrix Reloaded"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Matrix Revisited", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Prince of Pennsylvania", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar2_actor": "Keanu Reeves", "costar2_movie": "The Replacements", "id": "Keanu Reeves", "costar1_actor": "/people/person", "costar1_movie": "/film/film"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Even Cowgirls Get the Blues", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Youngblood", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar2_movie": "Bill & Ted's Bogus Journey", "id": "Keanu Reeves", "costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Bill & Ted's Excellent Adventure", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"id": "Keanu Reeves", "costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Johnny Mnemonic"}},
|
||||
{map[string]string{"costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Devil's Advocate", "id": "Keanu Reeves", "costar1_actor": "/people/person"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Thumbsucker", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "I Love You to Death", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Bram Stoker's Dracula", "id": "Keanu Reeves", "costar1_actor": "/people/person"}},
|
||||
{map[string]string{"costar2_actor": "Keanu Reeves", "costar2_movie": "The Gift", "id": "Keanu Reeves", "costar1_actor": "/people/person", "costar1_movie": "/film/film"}},
|
||||
{map[string]string{"costar2_movie": "Little Buddha", "id": "Keanu Reeves", "costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Night Watchman", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"id": "Keanu Reeves", "costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Chain Reaction"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "Babes in Toyland", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Day the Earth Stood Still", "id": "Keanu Reeves"}},
|
||||
{map[string]string{"costar2_actor": "Keanu Reeves", "costar2_movie": "The Lake House", "id": "Lynn Collins", "costar1_actor": "Sandra Bullock", "costar1_movie": "The Lake House"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "The Proposal", "costar2_actor": "Keanu Reeves", "costar2_movie": "Parenthood", "id": "Mary Steenburgen"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "The Prince of Egypt", "costar2_actor": "Keanu Reeves", "costar2_movie": "Dangerous Liaisons", "id": "Michelle Pfeiffer"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Premonition", "costar2_actor": "Keanu Reeves", "costar2_movie": "Constantine", "id": "Peter Stormare"}},
|
||||
{map[string]string{"costar2_movie": "Speed", "id": "Richard Lineback", "costar1_actor": "Sandra Bullock", "costar1_movie": "Speed", "costar2_actor": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_movie": "The Thing Called Love", "costar2_actor": "Keanu Reeves", "costar2_movie": "My Own Private Idaho", "id": "River Phoenix", "costar1_actor": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "I Love You to Death", "id": "River Phoenix"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "The Proposal", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Crash", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Gun Shy", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock"}},
|
||||
{map[string]string{"costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock", "costar1_actor": "Sandra Bullock", "costar1_movie": "Demolition Man"}},
|
||||
{map[string]string{"costar2_movie": "Speed", "id": "Sandra Bullock", "costar1_actor": "Sandra Bullock", "costar1_movie": "Divine Secrets of the Ya-Ya Sisterhood", "costar2_actor": "Keanu Reeves"}},
|
||||
{map[string]string{"costar2_movie": "Speed", "id": "Sandra Bullock", "costar1_actor": "Sandra Bullock", "costar1_movie": "A Time to Kill", "costar2_actor": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Forces of Nature", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Hope Floats", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Infamous", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Love Potion No. 9", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock"}},
|
||||
{map[string]string{"id": "Sandra Bullock", "costar1_actor": "Sandra Bullock", "costar1_movie": "Miss Congeniality", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed"}},
|
||||
{map[string]string{"id": "Sandra Bullock", "costar1_actor": "Sandra Bullock", "costar1_movie": "Miss Congeniality 2: Armed and Fabulous", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Murder by Numbers", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock"}},
|
||||
{map[string]string{"id": "Sandra Bullock", "costar1_actor": "Sandra Bullock", "costar1_movie": "Practical Magic", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed"}},
|
||||
{map[string]string{"costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock", "costar1_actor": "Sandra Bullock", "costar1_movie": "Speed"}},
|
||||
{map[string]string{"costar1_movie": "Speed 2: Cruise Control", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock", "costar1_actor": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "The Lake House", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "The Net", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_movie": "The Prince of Egypt", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock", "costar1_actor": "Sandra Bullock"}},
|
||||
{map[string]string{"costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock", "costar1_actor": "Sandra Bullock", "costar1_movie": "Two Weeks Notice"}},
|
||||
{map[string]string{"costar2_movie": "Speed", "id": "Sandra Bullock", "costar1_actor": "Sandra Bullock", "costar1_movie": "While You Were Sleeping", "costar2_actor": "Keanu Reeves"}},
|
||||
{map[string]string{"id": "Sandra Bullock", "costar1_actor": "Sandra Bullock", "costar1_movie": "28 Days", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed"}},
|
||||
{map[string]string{"costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock", "costar1_actor": "Sandra Bullock", "costar1_movie": "Premonition"}},
|
||||
{map[string]string{"costar1_movie": "Wrestling Ernest Hemingway", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock", "costar1_actor": "Sandra Bullock"}},
|
||||
{map[string]string{"costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock", "costar1_actor": "Sandra Bullock", "costar1_movie": "Fire on the Amazon"}},
|
||||
{map[string]string{"costar1_movie": "The Thing Called Love", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock", "costar1_actor": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "In Love and War", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_actor": "/people/person", "costar1_movie": "/film/film", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Lake House", "id": "Sandra Bullock"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Divine Secrets of the Ya-Ya Sisterhood", "costar2_actor": "Keanu Reeves", "costar2_movie": "The Private Lives of Pippa Lee", "id": "Shirley Knight"}},
|
||||
{map[string]string{"costar2_movie": "The Lake House", "id": "Shohreh Aghdashloo", "costar1_actor": "Sandra Bullock", "costar1_movie": "The Lake House", "costar2_actor": "Keanu Reeves"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "The Prince of Egypt", "costar2_actor": "Keanu Reeves", "costar2_movie": "Parenthood", "id": "Steve Martin"}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Speed", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Thomas Rosales, Jr."}},
|
||||
{map[string]string{"costar1_actor": "Sandra Bullock", "costar1_movie": "Speed", "costar2_actor": "Keanu Reeves", "costar2_movie": "Speed", "id": "Hawthorne James"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const common = `
|
||||
var movie1 = g.V().Has("name", "The Net")
|
||||
var movie2 = g.V().Has("name", "Speed")
|
||||
var actor1 = g.V().Has("name", "Sandra Bullock")
|
||||
var actor2 = g.V().Has("name", "Keanu Reeves")
|
||||
|
||||
// (film) -> starring -> (actor)
|
||||
var filmToActor = g.Morphism().Out("/film/film/starring").Out("/film/performance/actor")
|
||||
|
||||
// (actor) -> starring -> [film -> starring -> (actor)]
|
||||
var coStars1 = g.Morphism().In("/film/performance/actor").In("/film/film/starring").Save("name","costar1_movie").Follow(filmToActor)
|
||||
var coStars2 = g.Morphism().In("/film/performance/actor").In("/film/film/starring").Save("name","costar2_movie").Follow(filmToActor)
|
||||
|
||||
// Stars for the movies "The Net" and "Speed"
|
||||
var m1_actors = movie1.Save("name","movie1").Follow(filmToActor)
|
||||
var m2_actors = movie2.Save("name","movie2").Follow(filmToActor)
|
||||
`
|
||||
|
||||
var (
|
||||
once sync.Once
|
||||
cfg = &config.Config{
|
||||
DatabasePath: "30kmoviedata.nq.gz",
|
||||
DatabaseType: "memstore",
|
||||
GremlinTimeout: 300,
|
||||
}
|
||||
|
||||
ts graph.TripleStore
|
||||
)
|
||||
|
||||
func prepare(t testing.TB) {
|
||||
var err error
|
||||
once.Do(func() {
|
||||
ts, err = db.Open(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open %q: %v", cfg.DatabasePath, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestQueries(t *testing.T) {
|
||||
prepare(t)
|
||||
for _, test := range benchmarkQueries {
|
||||
if testing.Short() && test.long {
|
||||
continue
|
||||
}
|
||||
ses := gremlin.NewSession(ts, cfg.GremlinTimeout, true)
|
||||
_, err := ses.InputParses(test.query)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse benchmark gremlin %s: %v", test.message, err)
|
||||
}
|
||||
c := make(chan interface{}, 5)
|
||||
go ses.ExecInput(test.query, c, 100)
|
||||
var (
|
||||
got [][]interface{}
|
||||
timedOut bool
|
||||
)
|
||||
for r := range c {
|
||||
ses.BuildJson(r)
|
||||
j, err := ses.GetJson()
|
||||
if j == nil && err == nil {
|
||||
continue
|
||||
}
|
||||
if err != nil && err.Error() == "Query Timeout" {
|
||||
timedOut = true
|
||||
continue
|
||||
}
|
||||
got = append(got, j)
|
||||
}
|
||||
|
||||
if timedOut {
|
||||
t.Error("Query timed out: skipping validation.")
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO(kortschak) Be more rigorous in this result validation.
|
||||
if len(got) != len(test.expect) {
|
||||
t.Errorf("Unexpected number of results, got:%d expect:%d.", len(got), len(test.expect))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func runBench(n int, b *testing.B) {
|
||||
if testing.Short() && benchmarkQueries[n].long {
|
||||
b.Skip()
|
||||
}
|
||||
prepare(b)
|
||||
ses := gremlin.NewSession(ts, cfg.GremlinTimeout, true)
|
||||
_, err := ses.InputParses(benchmarkQueries[n].query)
|
||||
if err != nil {
|
||||
b.Fatalf("Failed to parse benchmark gremlin %s: %v", benchmarkQueries[n].message, err)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
c := make(chan interface{}, 5)
|
||||
go ses.ExecInput(benchmarkQueries[n].query, c, 100)
|
||||
for _ = range c {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNamePredicate(b *testing.B) {
|
||||
runBench(0, b)
|
||||
}
|
||||
|
||||
func BenchmarkLargeSetsNoIntersection(b *testing.B) {
|
||||
runBench(1, b)
|
||||
}
|
||||
|
||||
func BenchmarkVeryLargeSetsSmallIntersection(b *testing.B) {
|
||||
runBench(2, b)
|
||||
}
|
||||
|
||||
func BenchmarkHelplessChecker(b *testing.B) {
|
||||
runBench(3, b)
|
||||
}
|
||||
|
||||
func BenchmarkNetAndSpeed(b *testing.B) {
|
||||
runBench(4, b)
|
||||
}
|
||||
|
||||
func BenchmarkKeannuAndNet(b *testing.B) {
|
||||
runBench(5, b)
|
||||
}
|
||||
|
||||
func BenchmarkKeannuAndSpeed(b *testing.B) {
|
||||
runBench(6, b)
|
||||
}
|
||||
|
||||
func BenchmarkKeannuOther(b *testing.B) {
|
||||
runBench(7, b)
|
||||
}
|
||||
|
||||
func BenchmarkKeannuBullockOther(b *testing.B) {
|
||||
runBench(8, b)
|
||||
}
|
||||
13
db/repl.go
13
db/repl.go
|
|
@ -25,10 +25,11 @@ import (
|
|||
|
||||
"github.com/google/cayley/config"
|
||||
"github.com/google/cayley/graph"
|
||||
"github.com/google/cayley/graph/sexp"
|
||||
"github.com/google/cayley/quad/cquads"
|
||||
"github.com/google/cayley/query"
|
||||
"github.com/google/cayley/query/gremlin"
|
||||
"github.com/google/cayley/query/mql"
|
||||
"github.com/google/cayley/query/sexp"
|
||||
)
|
||||
|
||||
func trace(s string) (string, time.Time) {
|
||||
|
|
@ -41,7 +42,7 @@ func un(s string, startTime time.Time) {
|
|||
fmt.Printf(s, float64(endTime.UnixNano()-startTime.UnixNano())/float64(1E6))
|
||||
}
|
||||
|
||||
func Run(query string, ses graph.Session) {
|
||||
func Run(query string, ses query.Session) {
|
||||
nResults := 0
|
||||
startTrace, startTime := trace("Elapsed time: %g ms\n\n")
|
||||
defer func() {
|
||||
|
|
@ -62,7 +63,7 @@ func Run(query string, ses graph.Session) {
|
|||
}
|
||||
|
||||
func Repl(ts graph.TripleStore, queryLanguage string, cfg *config.Config) error {
|
||||
var ses graph.Session
|
||||
var ses query.Session
|
||||
switch queryLanguage {
|
||||
case "sexp":
|
||||
ses = sexp.NewSession(ts)
|
||||
|
|
@ -140,13 +141,13 @@ func Repl(ts graph.TripleStore, queryLanguage string, cfg *config.Config) error
|
|||
}
|
||||
result, err := ses.InputParses(string(line))
|
||||
switch result {
|
||||
case graph.Parsed:
|
||||
case query.Parsed:
|
||||
Run(string(line), ses)
|
||||
line = line[:0]
|
||||
case graph.ParseFail:
|
||||
case query.ParseFail:
|
||||
fmt.Println("Error: ", err)
|
||||
line = line[:0]
|
||||
case graph.ParseMore:
|
||||
case query.ParseMore:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
|
||||
"github.com/google/cayley/graph"
|
||||
"github.com/google/cayley/query"
|
||||
"github.com/google/cayley/query/gremlin"
|
||||
"github.com/google/cayley/query/mql"
|
||||
)
|
||||
|
|
@ -47,7 +47,7 @@ func WrapResult(result interface{}) ([]byte, error) {
|
|||
return json.MarshalIndent(wrap, "", " ")
|
||||
}
|
||||
|
||||
func RunJsonQuery(query string, ses graph.HttpSession) (interface{}, error) {
|
||||
func RunJsonQuery(query string, ses query.HttpSession) (interface{}, error) {
|
||||
c := make(chan interface{}, 5)
|
||||
go ses.ExecInput(query, c, 100)
|
||||
for res := range c {
|
||||
|
|
@ -56,7 +56,7 @@ func RunJsonQuery(query string, ses graph.HttpSession) (interface{}, error) {
|
|||
return ses.GetJson()
|
||||
}
|
||||
|
||||
func GetQueryShape(query string, ses graph.HttpSession) ([]byte, error) {
|
||||
func GetQueryShape(query string, ses query.HttpSession) ([]byte, error) {
|
||||
c := make(chan map[string]interface{}, 5)
|
||||
go ses.GetQuery(query, c)
|
||||
var data map[string]interface{}
|
||||
|
|
@ -68,7 +68,7 @@ func GetQueryShape(query string, ses graph.HttpSession) ([]byte, error) {
|
|||
|
||||
// TODO(barakmich): Turn this into proper middleware.
|
||||
func (api *Api) ServeV1Query(w http.ResponseWriter, r *http.Request, params httprouter.Params) int {
|
||||
var ses graph.HttpSession
|
||||
var ses query.HttpSession
|
||||
switch params.ByName("query_lang") {
|
||||
case "gremlin":
|
||||
ses = gremlin.NewSession(api.ts, api.config.GremlinTimeout, false)
|
||||
|
|
@ -84,7 +84,7 @@ func (api *Api) ServeV1Query(w http.ResponseWriter, r *http.Request, params http
|
|||
code := string(bodyBytes)
|
||||
result, err := ses.InputParses(code)
|
||||
switch result {
|
||||
case graph.Parsed:
|
||||
case query.Parsed:
|
||||
var output interface{}
|
||||
var bytes []byte
|
||||
var err error
|
||||
|
|
@ -103,7 +103,7 @@ func (api *Api) ServeV1Query(w http.ResponseWriter, r *http.Request, params http
|
|||
fmt.Fprint(w, string(bytes))
|
||||
ses = nil
|
||||
return 200
|
||||
case graph.ParseFail:
|
||||
case query.ParseFail:
|
||||
ses = nil
|
||||
return FormatJson400(w, err)
|
||||
default:
|
||||
|
|
@ -116,7 +116,7 @@ func (api *Api) ServeV1Query(w http.ResponseWriter, r *http.Request, params http
|
|||
}
|
||||
|
||||
func (api *Api) ServeV1Shape(w http.ResponseWriter, r *http.Request, params httprouter.Params) int {
|
||||
var ses graph.HttpSession
|
||||
var ses query.HttpSession
|
||||
switch params.ByName("query_lang") {
|
||||
case "gremlin":
|
||||
ses = gremlin.NewSession(api.ts, api.config.GremlinTimeout, false)
|
||||
|
|
@ -132,7 +132,7 @@ func (api *Api) ServeV1Shape(w http.ResponseWriter, r *http.Request, params http
|
|||
code := string(bodyBytes)
|
||||
result, err := ses.InputParses(code)
|
||||
switch result {
|
||||
case graph.Parsed:
|
||||
case query.Parsed:
|
||||
var output []byte
|
||||
var err error
|
||||
output, err = GetQueryShape(code, ses)
|
||||
|
|
@ -141,7 +141,7 @@ func (api *Api) ServeV1Shape(w http.ResponseWriter, r *http.Request, params http
|
|||
}
|
||||
fmt.Fprint(w, string(output))
|
||||
return 200
|
||||
case graph.ParseFail:
|
||||
case query.ParseFail:
|
||||
return FormatJson400(w, err)
|
||||
default:
|
||||
return FormatJsonError(w, 500, "Incomplete data?")
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/robertkrimen/otto"
|
||||
|
||||
"github.com/google/cayley/graph"
|
||||
"github.com/google/cayley/query"
|
||||
)
|
||||
|
||||
type Session struct {
|
||||
|
|
@ -81,13 +82,13 @@ func (s *Session) GetQuery(input string, output_struct chan map[string]interface
|
|||
s.queryShape = nil
|
||||
}
|
||||
|
||||
func (s *Session) InputParses(input string) (graph.ParseResult, error) {
|
||||
func (s *Session) InputParses(input string) (query.ParseResult, error) {
|
||||
script, err := s.env.Compile("", input)
|
||||
if err != nil {
|
||||
return graph.ParseFail, err
|
||||
return query.ParseFail, err
|
||||
}
|
||||
s.script = script
|
||||
return graph.Parsed, nil
|
||||
return query.Parsed, nil
|
||||
}
|
||||
|
||||
func (s *Session) SendResult(result *GremlinResult) bool {
|
||||
|
|
@ -250,7 +251,7 @@ func (ses *Session) BuildJson(result interface{}) {
|
|||
|
||||
}
|
||||
|
||||
func (ses *Session) GetJson() (interface{}, error) {
|
||||
func (ses *Session) GetJson() ([]interface{}, error) {
|
||||
defer ses.ClearJson()
|
||||
if ses.err != nil {
|
||||
return nil, ses.err
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
"github.com/google/cayley/graph"
|
||||
"github.com/google/cayley/graph/iterator"
|
||||
"github.com/google/cayley/query"
|
||||
)
|
||||
|
||||
type Session struct {
|
||||
|
|
@ -62,13 +63,13 @@ func (m *Session) GetQuery(input string, output_struct chan map[string]interface
|
|||
output_struct <- output
|
||||
}
|
||||
|
||||
func (s *Session) InputParses(input string) (graph.ParseResult, error) {
|
||||
func (s *Session) InputParses(input string) (query.ParseResult, error) {
|
||||
var x interface{}
|
||||
err := json.Unmarshal([]byte(input), &x)
|
||||
if err != nil {
|
||||
return graph.ParseFail, err
|
||||
return query.ParseFail, err
|
||||
}
|
||||
return graph.Parsed, nil
|
||||
return query.Parsed, nil
|
||||
}
|
||||
|
||||
func (s *Session) ExecInput(input string, c chan interface{}, limit int) {
|
||||
|
|
@ -130,7 +131,7 @@ func (s *Session) BuildJson(result interface{}) {
|
|||
s.currentQuery.treeifyResult(result.(map[string]graph.Value))
|
||||
}
|
||||
|
||||
func (s *Session) GetJson() (interface{}, error) {
|
||||
func (s *Session) GetJson() ([]interface{}, error) {
|
||||
s.currentQuery.buildResults()
|
||||
if s.currentQuery.isError() {
|
||||
return nil, s.currentQuery.err
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package graph
|
||||
package query
|
||||
|
||||
// Defines the graph session interface general to all query languages.
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ type HttpSession interface {
|
|||
ExecInput(string, chan interface{}, int)
|
||||
GetQuery(string, chan map[string]interface{})
|
||||
BuildJson(interface{})
|
||||
GetJson() (interface{}, error)
|
||||
GetJson() ([]interface{}, error)
|
||||
ClearJson()
|
||||
ToggleDebug()
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@ import (
|
|||
"sort"
|
||||
|
||||
"github.com/google/cayley/graph"
|
||||
"github.com/google/cayley/query"
|
||||
)
|
||||
|
||||
type Session struct {
|
||||
|
|
@ -39,7 +40,7 @@ func (s *Session) ToggleDebug() {
|
|||
s.debug = !s.debug
|
||||
}
|
||||
|
||||
func (s *Session) InputParses(input string) (graph.ParseResult, error) {
|
||||
func (s *Session) InputParses(input string) (query.ParseResult, error) {
|
||||
var parenDepth int
|
||||
for i, x := range input {
|
||||
if x == '(' {
|
||||
|
|
@ -52,17 +53,17 @@ func (s *Session) InputParses(input string) (graph.ParseResult, error) {
|
|||
if (i - 10) > min {
|
||||
min = i - 10
|
||||
}
|
||||
return graph.ParseFail, errors.New(fmt.Sprintf("Too many close parens at char %d: %s", i, input[min:i]))
|
||||
return query.ParseFail, errors.New(fmt.Sprintf("Too many close parens at char %d: %s", i, input[min:i]))
|
||||
}
|
||||
}
|
||||
}
|
||||
if parenDepth > 0 {
|
||||
return graph.ParseMore, nil
|
||||
return query.ParseMore, nil
|
||||
}
|
||||
if len(ParseString(input)) > 0 {
|
||||
return graph.Parsed, nil
|
||||
return query.Parsed, nil
|
||||
}
|
||||
return graph.ParseFail, errors.New("Invalid Syntax")
|
||||
return query.ParseFail, errors.New("Invalid Syntax")
|
||||
}
|
||||
|
||||
func (s *Session) ExecInput(input string, out chan interface{}, limit int) {
|
||||
Loading…
Add table
Add a link
Reference in a new issue