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

Graph #42

Merged
merged 5 commits into from
May 2, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 203 additions & 0 deletions src/graph.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use error::Result;
use rusqlite::Connection;
use storage;

pub struct UnitProps {
pub unit: String,
Expand Down Expand Up @@ -223,3 +224,205 @@ pub fn compare_unit_props(

return Ok(Some(result_if_found));
}

pub fn determine_if_included(
db: &Connection,
earlier_unit: &String,
later_units: &[&String],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be &[String] or you have construct a ref vec which is unnecessary

) -> Result<bool> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should prefix unused variables with _ to remove warnings

if storage::is_genesis_unit(&earlier_unit) {
return Ok(true);
}

let (earlier_unit_props, later_units_props) =
storage::read_props_of_units(db, &earlier_unit, later_units)?;

if earlier_unit_props.is_free == 1 {
return Ok(false);
}

ensure!(later_units_props.len() > 0, "no later unit props were read");

//spec::UnitProps.latest_included_mc_index and spec::UnitProps.main_chain_index is not Option
let max_later_limci = later_units_props
.iter()
.max_by_key(|props| props.latest_included_mc_index)
.unwrap()
.latest_included_mc_index;
if
/*earlier_unit_props.main_chain_index.is_some()
&&*/
max_later_limci >= earlier_unit_props.main_chain_index {
return Ok(true);
}

let max_later_level = later_units_props
.iter()
.max_by_key(|props| props.level)
.unwrap()
.level;
if max_later_level < earlier_unit_props.level {
return Ok(false);
}

let mut start_units = later_units
.iter()
.map(|s| format!("'{}'", s))
.collect::<Vec<_>>();

'go_up: loop {
let start_unit_list = start_units
.iter()
.map(|s| format!("'{}'", s))
.collect::<Vec<_>>()
.join(", ");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you construct start_unit_list from star_unit which seems wrong, should be construct from later_units, or you have wrongly initialized start unit.


let sql = format!(
"SELECT unit, level, latest_included_mc_index, main_chain_index, is_on_main_chain \
FROM parenthoods JOIN units ON parent_unit=unit \
WHERE child_unit IN({})",
start_unit_list
);

let mut stmt = db.prepare(&sql)?;
let rows = stmt.query_map(&[], |row| UnitProps {
unit: row.get(0),
level: row.get(1),
latest_included_mc_index: row.get(2),
main_chain_index: row.get(3),
is_on_main_chain: row.get(4),
is_free: 0, //is_free is not queried
})?;

let mut new_start_units = Vec::new();
for row in rows {
let unit = row?;
if unit.unit == *earlier_unit {
return Ok(true);
}

if unit.is_on_main_chain == Some(0) && unit.level > earlier_unit_props.level {
new_start_units.push(unit.unit.clone());
}
}

if new_start_units.len() > 0 {
new_start_units.sort();
new_start_units.dedup();
start_units = new_start_units;
} else {
break 'go_up;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here should be break with no label or return Ok(false). break 'go_up' we will have a infinite loop!

}
}

Ok(false)
}

pub fn determine_if_included_or_equal(
db: &Connection,
earlier_unit: &String,
later_units: &[&String],
) -> Result<bool> {
if later_units.contains(&earlier_unit) {
return Ok(true);
}

determine_if_included(db, earlier_unit, later_units)
}

pub fn read_descendant_units_by_authors_before_mc_index(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

recheck the issues in determineIfIncluded

db: &Connection,
earlier_unit: &UnitProps,
author_addresses: &[&String],
to_main_chain_index: u32,
) -> Result<Vec<String>> {
let mut units = Vec::new();

let author_address_list = author_addresses
.iter()
.map(|s| format!("'{}'", s))
.collect::<Vec<_>>()
.join(", ");

ensure!(
earlier_unit.main_chain_index.is_some(),
"earlier unit has no main chain index"
);
let earlier_unit_mci = earlier_unit.main_chain_index.unwrap();

//Missing db.forceIndex("byMcIndex") from original js
let sql = format!(
"SELECT unit FROM units \"
LEFT JOIN unit_authors USING(unit) \
WHERE latest_included_mc_index>={} AND main_chain_index>{} \
AND main_chain_index<={} AND latest_included_mc_index<{} \
AND address IN({})",
earlier_unit_mci,
earlier_unit_mci,
to_main_chain_index,
to_main_chain_index,
author_address_list
);

let mut stmt = db.prepare(&sql)?;
let rows = stmt.query_map(&[], |row| row.get::<_, String>(0))?;

for row in rows {
units.push(row?)
}

let mut start_units = Vec::new();
start_units.push(earlier_unit.unit.clone());

'go_down: loop {
let start_unit_list = start_units
.iter()
.map(|s| format!("'{}'", s))
.collect::<Vec<_>>()
.join(", ");

let sql = format!(
"SELECT units.unit, unit_authors.address AS author_in_list \
FROM parenthoods \
JOIN units ON child_unit=units.unit \
LEFT JOIN unit_authors ON unit_authors.unit=units.unit \
AND address IN({}) \
WHERE parent_unit IN({}) \
AND latest_included_mc_index<{} \
AND main_chain_index<={}",
author_address_list, start_unit_list, earlier_unit_mci, to_main_chain_index
);

//The query fields have different structures
struct UnitProps {
unit: String,
author_in_list: Option<String>,
}

let mut stmt = db.prepare(&sql)?;
let rows = stmt.query_map(&[], |row| UnitProps {
unit: row.get(0),
author_in_list: row.get(1),
})?;

let mut new_start_units = Vec::new();

for row in rows {
let unit = row?;

new_start_units.push(unit.unit.clone());

if unit.author_in_list.is_some() {
units.push(unit.unit.clone());
}
}

if new_start_units.len() > 0 {
start_units = new_start_units;
} else {
break 'go_down;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change this, find all the break with a label, and correct them

}
}

Ok(units)
}
8 changes: 8 additions & 0 deletions src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ pub fn read_unit_props(db: &Connection, unit_hash: &String) -> Result<UnitProps>
Ok(ret)
}

pub fn read_props_of_units(
db: &Connection,
unit_hash: &String,
later_unit_hashes: &[&String],
) -> Result<(UnitProps, Vec<UnitProps>)> {
unimplemented!();
}

// TODO: need to cache in memory
pub fn read_static_unit_property(
db: &Connection,
Expand Down