Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GIE/Runtime] Support Entry Trait in GIE/Runtime #2300

Merged
merged 12 commits into from
Jan 19, 2023
4 changes: 4 additions & 0 deletions interactive_engine/executor/common/dyn_type/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
//! limitations under the License.

use core::any::TypeId;
use pegasus_common::downcast::*;
use pegasus_common::impl_as_any;
use std::any::Any;
use std::borrow::Cow;
use std::cmp::Ordering;
Expand Down Expand Up @@ -418,6 +420,8 @@ pub enum Object {
None,
}

impl_as_any!(Object);

impl ToString for Object {
fn to_string(&self) -> String {
match self {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ use ir_common::{KeyId, LabelId, NameOrId};
use pegasus::configure_with_default;
use pegasus_common::downcast::*;
use pegasus_common::impl_as_any;
use rand::prelude::StdRng;
use rand::{Rng, SeedableRng};

use crate::apis::graph::PKV;
use crate::apis::{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ use global_query::{
};
use graph_store::utils::IterList;
use ir_common::{KeyId, LabelId, NameOrId, OneOrMany};
use rand::prelude::StdRng;
use rand::{Rng, SeedableRng};

use super::details::{HybridEdgeDetails, HybridVertexDetails, LazyEdgeDetails, LazyVertexDetails};
use crate::apis::graph::PKV;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//! See the License for the specific language governing permissions and
//! limitations under the License.

use std::any::Any;
use std::cmp::Ordering;
use std::convert::{TryFrom, TryInto};
use std::hash::{Hash, Hasher};
Expand All @@ -23,6 +24,8 @@ use ir_common::error::ParsePbError;
use ir_common::generated::results as result_pb;
use ir_common::{LabelId, NameOrId};
use pegasus_common::codec::{Decode, Encode, ReadExt, WriteExt};
use pegasus_common::downcast::*;
use pegasus_common::impl_as_any;

use crate::apis::{read_id, write_id, DynDetails, Element, GraphElement, ID};
use crate::utils::expr::eval::Context;
Expand All @@ -40,6 +43,8 @@ pub struct Edge {
details: DynDetails,
}

impl_as_any!(Edge);

impl Element for Edge {
fn as_graph_element(&self) -> Option<&dyn GraphElement> {
Some(self)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use dyn_type::{BorrowObject, Object};
pub use edge::Edge;
use ir_common::LabelId;
pub use path::GraphPath;
pub use path::VertexOrEdge;
pub use property::{Details, DynDetails, PropKey, PropertyValue};
pub use vertex::Vertex;

Expand All @@ -42,6 +41,7 @@ pub trait Element {
}

/// `GraphElement` is a special `Element` with extra properties of `id` and `label`.
/// In common case, `GraphElement` refers to `Vertex` and `Edge`
pub trait GraphElement: Element {
fn id(&self) -> ID;
fn label(&self) -> Option<LabelId>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
//! See the License for the specific language governing permissions and
//! limitations under the License.

use std::any::Any;
use std::cmp::Ordering;
use std::collections::hash_map::DefaultHasher;
use std::convert::{TryFrom, TryInto};
use std::hash::{Hash, Hasher};

Expand All @@ -23,64 +23,47 @@ use ir_common::error::ParsePbError;
use ir_common::generated::algebra::path_expand::PathOpt;
use ir_common::generated::algebra::path_expand::ResultOpt;
use ir_common::generated::results as result_pb;
use ir_common::LabelId;
use pegasus::codec::{Decode, Encode, ReadExt, WriteExt};
use pegasus_common::downcast::*;
use pegasus_common::impl_as_any;

use crate::apis::{DynDetails, Edge, Element, GraphElement, Vertex, ID};

#[derive(Clone, Debug, Hash, PartialEq, PartialOrd)]
pub enum VertexOrEdge {
V(Vertex),
E(Edge),
}

impl From<Vertex> for VertexOrEdge {
fn from(v: Vertex) -> Self {
Self::V(v)
}
}

impl From<Edge> for VertexOrEdge {
fn from(e: Edge) -> Self {
Self::E(e)
}
}
use crate::apis::{Element, GraphElement, Vertex, ID};

#[derive(Clone, Debug)]
pub enum GraphPath {
AllV(Vec<VertexOrEdge>),
SimpleAllV(Vec<VertexOrEdge>),
EndV((VertexOrEdge, usize)),
SimpleEndV((VertexOrEdge, Vec<ID>)),
AllV(Vec<Vertex>),
SimpleAllV(Vec<Vertex>),
EndV((Vertex, usize)),
SimpleEndV((Vertex, Vec<ID>)),
}

impl_as_any!(GraphPath);

impl GraphPath {
pub fn new<E: Into<VertexOrEdge>>(entry: E, path_opt: PathOpt, result_opt: ResultOpt) -> Self {
pub fn new(entry: Vertex, path_opt: PathOpt, result_opt: ResultOpt) -> Self {
match result_opt {
ResultOpt::EndV => match path_opt {
PathOpt::Arbitrary => GraphPath::EndV((entry.into(), 1)),
PathOpt::Arbitrary => GraphPath::EndV((entry, 1)),
PathOpt::Simple => {
let entry = entry.into();
let id = entry.id();
GraphPath::SimpleEndV((entry, vec![id]))
}
},
ResultOpt::AllV => match path_opt {
PathOpt::Arbitrary => GraphPath::AllV(vec![entry.into()]),
PathOpt::Simple => GraphPath::SimpleAllV(vec![entry.into()]),
PathOpt::Arbitrary => GraphPath::AllV(vec![entry]),
PathOpt::Simple => GraphPath::SimpleAllV(vec![entry]),
},
}
}

// append an entry and return the flag of whether the entry has been appended or not.
pub fn append<E: Into<VertexOrEdge>>(&mut self, entry: E) -> bool {
pub fn append(&mut self, entry: Vertex) -> bool {
match self {
GraphPath::AllV(ref mut path) => {
path.push(entry.into());
path.push(entry);
true
}
GraphPath::SimpleAllV(ref mut path) => {
let entry = entry.into();
if path.contains(&entry) {
false
} else {
Expand All @@ -89,86 +72,40 @@ impl GraphPath {
}
}
GraphPath::EndV((ref mut e, ref mut weight)) => {
*e = entry.into();
*e = entry;
*weight += 1;
true
}
GraphPath::SimpleEndV((ref mut e, ref mut path)) => {
let entry = entry.into();
if path.contains(&entry.id()) {
false
} else {
path.push(entry.id());
*e = entry.into();
*e = entry;
true
}
}
}
}

pub fn get_path_end(&self) -> Option<&VertexOrEdge> {
pub fn get_path_end(&self) -> Option<&Vertex> {
match self {
GraphPath::AllV(ref p) | GraphPath::SimpleAllV(ref p) => p.last(),
GraphPath::EndV((ref e, _)) | GraphPath::SimpleEndV((ref e, _)) => Some(e),
}
}

pub fn take_path(self) -> Option<Vec<VertexOrEdge>> {
pub fn take_path(self) -> Option<Vec<Vertex>> {
match self {
GraphPath::AllV(p) | GraphPath::SimpleAllV(p) => Some(p),
GraphPath::EndV(_) | GraphPath::SimpleEndV(_) => None,
}
}
}

impl Element for VertexOrEdge {
fn as_graph_element(&self) -> Option<&dyn GraphElement> {
match self {
VertexOrEdge::V(v) => v.as_graph_element(),
VertexOrEdge::E(e) => e.as_graph_element(),
}
}

fn len(&self) -> usize {
match self {
VertexOrEdge::V(v) => v.len(),
VertexOrEdge::E(e) => e.len(),
}
}

fn as_borrow_object(&self) -> BorrowObject {
match self {
VertexOrEdge::V(v) => v.as_borrow_object(),
VertexOrEdge::E(e) => e.as_borrow_object(),
}
}
}

impl GraphElement for VertexOrEdge {
fn id(&self) -> ID {
match self {
VertexOrEdge::V(v) => v.id(),
VertexOrEdge::E(e) => e.id(),
}
}

fn label(&self) -> Option<LabelId> {
match self {
VertexOrEdge::V(v) => v.label(),
VertexOrEdge::E(e) => e.label(),
}
}
fn details(&self) -> Option<&DynDetails> {
match self {
VertexOrEdge::V(v) => v.details(),
VertexOrEdge::E(e) => e.details(),
}
}
}

impl Element for GraphPath {
fn as_graph_element(&self) -> Option<&dyn GraphElement> {
Some(self)
None
}

// the path len is the number of edges in the path;
Expand All @@ -185,24 +122,6 @@ impl Element for GraphPath {
}
}

impl GraphElement for GraphPath {
fn id(&self) -> ID {
match self {
GraphPath::AllV(path) | GraphPath::SimpleAllV(path) => {
let ids: Vec<ID> = path.iter().map(|v| v.id()).collect();
let mut hasher = DefaultHasher::new();
ids.hash(&mut hasher);
hasher.finish() as ID
}
GraphPath::EndV((path_end, _)) | GraphPath::SimpleEndV((path_end, _)) => path_end.id(),
}
}

fn label(&self) -> Option<LabelId> {
None
}
}

impl PartialEq for GraphPath {
fn eq(&self, other: &Self) -> bool {
// We define eq by structure, ignoring path weight
Expand All @@ -219,6 +138,7 @@ impl PartialEq for GraphPath {
}
}
}

impl PartialOrd for GraphPath {
// We define partial_cmp by structure, ignoring path weight
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Expand All @@ -236,39 +156,6 @@ impl PartialOrd for GraphPath {
}
}

impl Encode for VertexOrEdge {
fn write_to<W: WriteExt>(&self, writer: &mut W) -> std::io::Result<()> {
match self {
VertexOrEdge::V(v) => {
writer.write_u8(0)?;
v.write_to(writer)?;
}
VertexOrEdge::E(e) => {
writer.write_u8(1)?;
e.write_to(writer)?;
}
}
Ok(())
}
}

impl Decode for VertexOrEdge {
fn read_from<R: ReadExt>(reader: &mut R) -> std::io::Result<Self> {
let e = reader.read_u8()?;
match e {
0 => {
let v = <Vertex>::read_from(reader)?;
Ok(VertexOrEdge::V(v))
}
1 => {
let e = <Edge>::read_from(reader)?;
Ok(VertexOrEdge::E(e))
}
_ => Err(std::io::Error::new(std::io::ErrorKind::Other, "unreachable")),
}
}
}

impl Encode for GraphPath {
fn write_to<W: WriteExt>(&self, writer: &mut W) -> std::io::Result<()> {
match self {
Expand Down Expand Up @@ -300,20 +187,20 @@ impl Decode for GraphPath {
let opt = reader.read_u8()?;
match opt {
0 => {
let path = <Vec<VertexOrEdge>>::read_from(reader)?;
let path = <Vec<Vertex>>::read_from(reader)?;
Ok(GraphPath::AllV(path))
}
1 => {
let vertex_or_edge = <VertexOrEdge>::read_from(reader)?;
let vertex_or_edge = <Vertex>::read_from(reader)?;
let weight = <u64>::read_from(reader)? as usize;
Ok(GraphPath::EndV((vertex_or_edge, weight)))
}
2 => {
let path = <Vec<VertexOrEdge>>::read_from(reader)?;
let path = <Vec<Vertex>>::read_from(reader)?;
Ok(GraphPath::SimpleAllV(path))
}
3 => {
let vertex_or_edge = <VertexOrEdge>::read_from(reader)?;
let vertex_or_edge = <Vertex>::read_from(reader)?;
let path = <Vec<ID>>::read_from(reader)?;
Ok(GraphPath::SimpleEndV((vertex_or_edge, path)))
}
Expand All @@ -322,7 +209,7 @@ impl Decode for GraphPath {
}
}

impl TryFrom<result_pb::graph_path::VertexOrEdge> for VertexOrEdge {
impl TryFrom<result_pb::graph_path::VertexOrEdge> for Vertex {
type Error = ParsePbError;
fn try_from(e: result_pb::graph_path::VertexOrEdge) -> Result<Self, Self::Error> {
let vertex_or_edge = e
Expand All @@ -331,11 +218,10 @@ impl TryFrom<result_pb::graph_path::VertexOrEdge> for VertexOrEdge {
match vertex_or_edge {
result_pb::graph_path::vertex_or_edge::Inner::Vertex(v) => {
let vertex = v.try_into()?;
Ok(VertexOrEdge::V(vertex))
Ok(vertex)
}
result_pb::graph_path::vertex_or_edge::Inner::Edge(e) => {
let edge = e.try_into()?;
Ok(VertexOrEdge::E(edge))
result_pb::graph_path::vertex_or_edge::Inner::Edge(_) => {
Err(ParsePbError::Unsupported("Path with edges".to_string()))
}
}
}
Expand Down