Skip to content

Commit

Permalink
[Bug Fix] Fix bug in index_scan on Groot/Vineyard (#2129)
Browse files Browse the repository at this point in the history
* [BugFix] fix the bug in index_scan of GraphScopeStore
* [CI Test] add tests of index_scan on Groot/Vineyard
  • Loading branch information
BingqingLyu committed Oct 13, 2022
1 parent d4d942c commit 6d94c3f
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public abstract class IrGremlinQueryTest extends AbstractGremlinProcessTest {

public abstract Traversal<Vertex, Object> get_g_VX4X_bothE_as_otherV();

public abstract Traversal<Vertex, Object> get_g_V_hasLabel_hasId_values();

@Test
public void g_V_group_by_by_dedup_count_test() {
Traversal<Vertex, Map<Object, Long>> traversal =
Expand Down Expand Up @@ -95,6 +97,23 @@ public void g_VX4X_bothE_as_otherV() {
Assert.assertEquals(expected.size(), counter);
}

@Test
public void g_V_hasLabel_hasId_values() {
Traversal<Vertex, Object> traversal = this.get_g_V_hasLabel_hasId_values();
this.printTraversalForm(traversal);
int counter = 0;

String expected = "marko";

while (traversal.hasNext()) {
Object result = traversal.next();
Assert.assertTrue(expected.contains(result.toString()));
++counter;
}

Assert.assertEquals(1, counter);
}

public static class Traversals extends IrGremlinQueryTest {

@Override
Expand All @@ -117,5 +136,10 @@ public Traversal<Vertex, Map<Object, List>> get_g_V_group_by_outE_count_order_by
public Traversal<Vertex, Object> get_g_VX4X_bothE_as_otherV() {
return g.V().has("id", 4).bothE().as("a").otherV().values("id");
}

@Override
public Traversal<Vertex, Object> get_g_V_hasLabel_hasId_values() {
return g.V().hasLabel("person").has("id", 1).values("name");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use crate::{GraphProxyError, GraphProxyResult};
// Should be identical to the param_name given by compiler
const SNAPSHOT_ID: &str = "SID";
// This will refer to the latest graph
const DEFAULT_SNAPSHOT_ID: SnapshotId = SnapshotId::max_value() - 1;
const DEFAULT_SNAPSHOT_ID: SnapshotId = SnapshotId::MAX - 1;
// This represents the primary key of GraphScopeStore
const GS_STORE_PK: KeyId = 0;

Expand Down Expand Up @@ -162,28 +162,37 @@ where
}

fn index_scan_vertex(
&self, label_id: LabelId, primary_key: &PKV, _params: &QueryParams,
&self, label_id: LabelId, primary_key: &PKV, params: &QueryParams,
) -> GraphProxyResult<Option<Vertex>> {
// get_vertex_id_by_primary_keys() is a global query function, that is,
// you can query vertices (with only vertex id) by pks on any graph partitions (not matter locally or remotely).
// To guarantee the correctness (i.e., avoid duplication results), only worker 0 is assigned for query.
if pegasus::get_current_worker().index == 0 {
let store_label_id = encode_storage_label(label_id)?;
let store_indexed_values = match primary_key {
OneOrMany::One(pkv) => {
vec![encode_store_prop_val(pkv[0].1.clone())]
}
OneOrMany::Many(pkvs) => pkvs
.iter()
.map(|(_pk, value)| encode_store_prop_val(value.clone()))
.collect(),
};
// To guarantee the correctness (i.e., avoid duplication results), we pre-assign partitions for workers,
// and only the worker responsible for this vertex (i.e., contains the vertex in its partitions) is going to search for it.

let store_label_id = encode_storage_label(label_id)?;
let store_indexed_values = match primary_key {
OneOrMany::One(pkv) => {
vec![encode_store_prop_val(pkv[0].1.clone())]
}
OneOrMany::Many(pkvs) => pkvs
.iter()
.map(|(_pk, value)| encode_store_prop_val(value.clone()))
.collect(),
};

if let Some(vid) = self
.partition_manager
.get_vertex_id_by_primary_keys(store_label_id, store_indexed_values.as_ref())
{
Ok(Some(Vertex::new(vid as ID, Some(label_id.clone()), DynDetails::default())))
if let Some(vid) = self
.partition_manager
.get_vertex_id_by_primary_keys(store_label_id, store_indexed_values.as_ref())
{
if let Some(worker_partitions) = params.partitions.as_ref() {
// only the one responsible for vid is going to search for the vertex
let vertex_partition = self.partition_manager.get_partition_id(vid) as u64;
if worker_partitions.contains(&vertex_partition) {
self.get_vertex(&[vid as ID], params)
.map(|mut v_iter| v_iter.next())
} else {
Ok(None)
}
} else {
Ok(None)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ impl SourceOperator {
// query by indexed_scan
let primary_key_values = <Vec<(NameOrId, Object)>>::try_from(ip2)?;
source_op.primary_key_values = Some(PKV::from(primary_key_values));
source_op.set_partitions(job_workers, worker_index, partitioner)?;
debug!("Runtime source op of indexed scan {:?}", source_op);
}
Ok(source_op)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public abstract class IrGremlinQueryTest extends AbstractGremlinProcessTest {

public abstract Traversal<Vertex, Object> get_g_VX4X_bothE_as_otherV();

public abstract Traversal<Vertex, Object> get_g_V_hasLabel_hasId_values();

@Test
public void g_VX4X_bothE_as_otherV() {
Traversal<Vertex, Object> traversal = this.get_g_VX4X_bothE_as_otherV();
Expand All @@ -46,11 +48,33 @@ public void g_VX4X_bothE_as_otherV() {
Assert.assertEquals(expected.size(), counter);
}

@Test
public void g_V_hasLabel_hasId_values() {
Traversal<Vertex, Object> traversal = this.get_g_V_hasLabel_hasId_values();
this.printTraversalForm(traversal);
int counter = 0;

String expected = "marko";

while (traversal.hasNext()) {
Object result = traversal.next();
Assert.assertTrue(expected.contains(result.toString()));
++counter;
}

Assert.assertEquals(1, counter);
}

public static class Traversals extends IrGremlinQueryTest {

@Override
public Traversal<Vertex, Object> get_g_VX4X_bothE_as_otherV() {
return g.V().has("id", 4).bothE().as("a").otherV().values("id");
}

@Override
public Traversal<Vertex, Object> get_g_V_hasLabel_hasId_values() {
return g.V().hasLabel("person").has("id", 1).values("name");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ public class GremlinStandardTestSuite extends AbstractGremlinSuite {

// match
MatchTest.CountMatchTraversals.class,

// others
IrGremlinQueryTest.Traversals.class,
};

/**
Expand Down Expand Up @@ -106,6 +109,9 @@ public class GremlinStandardTestSuite extends AbstractGremlinSuite {

// match
MatchTest.CountMatchTraversals.class,

// others
IrGremlinQueryTest.Traversals.class,
};

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright 2022 Alibaba Group Holding Limited.
*
* 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 com.alibaba.maxgraph.function.test.gremlin;

import org.apache.tinkerpop.gremlin.LoadGraphWith;
import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.junit.Assert;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;

public abstract class IrGremlinQueryTest extends AbstractGremlinProcessTest {

public abstract Traversal<Vertex, Object> get_g_VX4X_bothE_as_otherV();

public abstract Traversal<Vertex, Object> get_g_V_hasLabel_hasId_values();

@Test
@LoadGraphWith(LoadGraphWith.GraphData.MODERN)
public void g_VX4X_bothE_as_otherV() {
Traversal<Vertex, Object> traversal = this.get_g_VX4X_bothE_as_otherV();
this.printTraversalForm(traversal);
int counter = 0;

List<String> expected = Arrays.asList("1", "3", "5");

while (traversal.hasNext()) {
Object result = traversal.next();
Assert.assertTrue(expected.contains(result.toString()));
++counter;
}

Assert.assertEquals(expected.size(), counter);
}

@Test
@LoadGraphWith(LoadGraphWith.GraphData.MODERN)
public void g_V_hasLabel_hasId_values() {
Traversal<Vertex, Object> traversal = this.get_g_V_hasLabel_hasId_values();
this.printTraversalForm(traversal);
int counter = 0;

String expected = "marko";

while (traversal.hasNext()) {
Object result = traversal.next();
Assert.assertTrue(expected.contains(result.toString()));
++counter;
}

Assert.assertEquals(1, counter);
}

public static class Traversals extends IrGremlinQueryTest {

@Override
public Traversal<Vertex, Object> get_g_VX4X_bothE_as_otherV() {
return g.V().has("id", 4).bothE().as("a").otherV().values("id");
}

@Override
public Traversal<Vertex, Object> get_g_V_hasLabel_hasId_values() {
return g.V().hasLabel("person").has("id", 1).values("name");
}
}
}

0 comments on commit 6d94c3f

Please sign in to comment.