Skip to content

Commit

Permalink
[GraphProxy] refine implementation of LazyDetails (#2766)
Browse files Browse the repository at this point in the history
<!--
Thanks for your contribution! please review
https://github.com/alibaba/GraphScope/blob/main/CONTRIBUTING.md before
opening an issue.
-->

## What do these changes do?

<!-- Please give a short brief about these changes. -->

Refine implementation of `LazyDetails` to avoid memory leak.

Co-authored-by: Longbin Lai <longbin.lailb@alibaba-inc.com>
  • Loading branch information
BingqingLyu and longbinlai committed May 30, 2023
1 parent 4b24146 commit 7fd430b
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 297 deletions.
Expand Up @@ -15,7 +15,6 @@

use std::convert::TryFrom;
use std::fmt;
use std::sync::atomic::{AtomicPtr, Ordering};
use std::sync::Arc;

use ahash::HashMap;
Expand Down Expand Up @@ -255,24 +254,14 @@ struct LazyVertexDetails {
// Specifically, Some(vec![]) indicates we need all properties
// and None indicates we do not need any property
prop_keys: Option<Vec<NameOrId>>,
inner: AtomicPtr<LocalVertex<'static, DefaultId, DefaultId>>,
inner: LocalVertex<'static, DefaultId, DefaultId>,
}

impl_as_any!(LazyVertexDetails);

impl LazyVertexDetails {
pub fn new(v: LocalVertex<'static, DefaultId, DefaultId>, prop_keys: Option<Vec<NameOrId>>) -> Self {
let ptr = Box::into_raw(Box::new(v));
LazyVertexDetails { prop_keys, inner: AtomicPtr::new(ptr) }
}

fn get_vertex_ptr(&self) -> Option<*mut LocalVertex<'static, DefaultId, DefaultId>> {
let ptr = self.inner.load(Ordering::SeqCst);
if ptr.is_null() {
None
} else {
Some(ptr)
}
LazyVertexDetails { prop_keys, inner: v }
}
}

Expand All @@ -288,20 +277,14 @@ impl fmt::Debug for LazyVertexDetails {
impl Details for LazyVertexDetails {
fn get_property(&self, key: &NameOrId) -> Option<PropertyValue> {
if let NameOrId::Str(key) = key {
if let Some(ptr) = self.get_vertex_ptr() {
unsafe {
if key == "id" {
let mask = (1_usize << LABEL_SHIFT_BITS) - 1;
let original_id = ((*ptr).get_id() & mask) as i64;
Some(PropertyValue::Owned(Object::Primitive(Primitives::Long(original_id))))
} else {
(*ptr)
.get_property(key)
.map(|prop| PropertyValue::Borrowed(to_borrow_object(prop)))
}
}
if key == "id" {
let mask = (1_usize << LABEL_SHIFT_BITS) - 1;
let original_id = (self.inner.get_id() & mask) as i64;
Some(PropertyValue::Owned(Object::Primitive(Primitives::Long(original_id))))
} else {
None
self.inner
.get_property(key)
.map(|prop| PropertyValue::Borrowed(to_borrow_object(prop)))
}
} else {
info!("Have not support getting property by prop_id in exp_store yet");
Expand All @@ -311,46 +294,26 @@ impl Details for LazyVertexDetails {

fn get_all_properties(&self) -> Option<HashMap<NameOrId, Object>> {
// the case of get_all_properties from vertex;
let props = if let Some(ptr) = self.get_vertex_ptr() {
unsafe {
if let Some(prop_key_vals) = (*ptr).get_all_properties() {
let mut all_props: HashMap<NameOrId, Object> = prop_key_vals
.into_iter()
.map(|(prop_key, prop_val)| (prop_key.into(), to_object(prop_val)))
.collect();
let mask = (1_usize << LABEL_SHIFT_BITS) - 1;
let original_id = ((*ptr).get_id() & mask) as i64;
all_props.insert(
NameOrId::Str("id".to_string()),
Object::Primitive(Primitives::Long(original_id)),
);
Some(all_props)
} else {
None
}
}
if let Some(prop_key_vals) = self.inner.get_all_properties() {
let mut all_props: HashMap<NameOrId, Object> = prop_key_vals
.into_iter()
.map(|(prop_key, prop_val)| (prop_key.into(), to_object(prop_val)))
.collect();
let mask = (1_usize << LABEL_SHIFT_BITS) - 1;
let original_id = (self.inner.get_id() & mask) as i64;
all_props
.insert(NameOrId::Str("id".to_string()), Object::Primitive(Primitives::Long(original_id)));
Some(all_props)
} else {
None
};
props
}
}

fn get_property_keys(&self) -> Option<Vec<NameOrId>> {
self.prop_keys.clone()
}
}

impl Drop for LazyVertexDetails {
fn drop(&mut self) {
let ptr = self.inner.load(Ordering::SeqCst);
if !ptr.is_null() {
unsafe {
std::ptr::drop_in_place(ptr);
}
}
}
}

/// LazyEdgeDetails is used for local property fetching optimization.
/// That is, the required properties will not be materialized until LazyEdgeDetails need to be shuffled.
#[allow(dead_code)]
Expand All @@ -360,91 +323,55 @@ struct LazyEdgeDetails {
// Specifically, Some(vec![]) indicates we need all properties
// and None indicates we do not need any property,
prop_keys: Option<Vec<NameOrId>>,
inner: AtomicPtr<LocalEdge<'static, DefaultId, DefaultId>>,
inner: LocalEdge<'static, DefaultId, DefaultId>,
}

impl_as_any!(LazyEdgeDetails);

impl LazyEdgeDetails {
pub fn new(e: LocalEdge<'static, DefaultId, DefaultId>, prop_keys: Option<Vec<NameOrId>>) -> Self {
let ptr = Box::into_raw(Box::new(e));
LazyEdgeDetails { prop_keys, inner: AtomicPtr::new(ptr) }
}

fn get_edge_ptr(&self) -> Option<*mut LocalEdge<'static, DefaultId, DefaultId>> {
let ptr = self.inner.load(Ordering::SeqCst);
if ptr.is_null() {
None
} else {
Some(ptr)
}
LazyEdgeDetails { prop_keys, inner: e }
}
}

impl fmt::Debug for LazyEdgeDetails {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("LazyEdgeDetails")
.field("prop_keys", &self.prop_keys)
.field("inner", &self.inner)
// .field("inner", &self.inner)
.finish()
}
}

impl Details for LazyEdgeDetails {
fn get_property(&self, key: &NameOrId) -> Option<PropertyValue> {
if let NameOrId::Str(key) = key {
let ptr = self.get_edge_ptr();
if let Some(ptr) = ptr {
unsafe {
(*ptr)
.get_property(key)
.map(|prop| PropertyValue::Borrowed(to_borrow_object(prop)))
}
} else {
None
}
self.inner
.get_property(key)
.map(|prop| PropertyValue::Borrowed(to_borrow_object(prop)))
} else {
info!("Have not support getting property by prop_id in experiments store yet");
None
}
}

fn get_all_properties(&self) -> Option<HashMap<NameOrId, Object>> {
// the case of get_all_properties from vertex;
let props = if let Some(ptr) = self.get_edge_ptr() {
unsafe {
if let Some(prop_key_vals) = (*ptr).get_all_properties() {
let all_props: HashMap<NameOrId, Object> = prop_key_vals
.into_iter()
.map(|(prop_key, prop_val)| (prop_key.into(), to_object(prop_val)))
.collect();
Some(all_props)
} else {
None
}
}
if let Some(prop_key_vals) = self.inner.get_all_properties() {
let all_props: HashMap<NameOrId, Object> = prop_key_vals
.into_iter()
.map(|(prop_key, prop_val)| (prop_key.into(), to_object(prop_val)))
.collect();
Some(all_props)
} else {
None
};
props
}
}

fn get_property_keys(&self) -> Option<Vec<NameOrId>> {
self.prop_keys.clone()
}
}

impl Drop for LazyEdgeDetails {
fn drop(&mut self) {
let ptr = self.inner.load(Ordering::SeqCst);
if !ptr.is_null() {
unsafe {
std::ptr::drop_in_place(ptr);
}
}
}
}

#[inline]
fn to_object<'a>(ref_item: RefItem<'a>) -> Object {
match ref_item {
Expand Down

0 comments on commit 7fd430b

Please sign in to comment.