Skip to content

feat: path compaction - #865

Open
SemyonSinchenko wants to merge 5 commits into
graphframes:mainfrom
SemyonSinchenko:827-path-compaction
Open

feat: path compaction#865
SemyonSinchenko wants to merge 5 commits into
graphframes:mainfrom
SemyonSinchenko:827-path-compaction

Conversation

@SemyonSinchenko

Copy link
Copy Markdown
Collaborator

What changes were proposed in this pull request?

The new paths compaction API; only core -- public API will follow after pre-approve

Why are the changes needed?

Close #827

@james-willis

Copy link
Copy Markdown
Collaborator

I'm not sure that the 'indegree == outdegree == 1' is quite the right rule depending on the graph.

like an undirected graph should have 2 distinct undirected edges. so a <-> b <-> c should be compacted to a<->c but wouldnt b be considered to have an in-degree of 2 here?

This is still true in a directed graph: a <-> b <-> c -> d I would say the correct result would be a<->c->d.

@james-willis

Copy link
Copy Markdown
Collaborator

Similarly I think dead ends would be incorrectly eliminated: ...a<->b should not eliminate b even though it has one in and one out in the directed graph.

@james-willis james-willis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

initial quick review with AI. will come back later for a more complete review

Comment on lines +95 to +97
def requiredVertexAttributes(value: Seq[String]): this.type = {
requiredVertexAttributes = value.filter(_ != GraphFrame.ID).toSeq
this

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

you need to provide these columns for always remove/always keep filters as well

/**
* Register a named aggregation expression to be evaluated over the interior vertices of each
* compacted path. The expression is applied inside a `groupBy(component).agg(...)`; it may
* reference any vertex attribute column of the original graph as well as `orig_src` and

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think it needs to be a column saved by requiredVertexAttributes

.join(
persistedBaseEdges.select(col(GraphFrame.SRC), col(GraphFrame.DST).as("orig_dst")),
col(GraphFrame.SRC) === col(GraphFrame.ID),
"inner")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

should we drop the src and dst from the join here? I think theyre dupes of the id

Comment on lines +66 to +67
* The returned `DataFrame` has columns `src`, `dst`, `count`, followed by one column per
* additionally registered aggregation expression.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I dont think the Map will give us the ordering semantics youre claiming here. need some kind of order map implementation for this

GraphFrame.DST,
when(col("is_cycle"), array_min(col("inner_ids")))
.otherwise(element_at(col("compacted_dst"), 1)))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We need to do count = count - 1 if is_cycle because we keep one of the candidates


/**
* If `true` (default), cycles of candidates are not compacted: they are absent from the set of
* compacted edges, so their original edges survive unchanged in the output. If `false`, each

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

dont we drop all columns other than src,dst?

compactedInteriorIds.unpersist(blocking = true)

resultIsPersistent()
allEdges

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

should we return a graphframe instead?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Please no 😂

There is one API (old PageRank) that returns GraphFrame and I have no idea what do with it. It is (almost) impossible to support anything that returns GraphFrame in Spark-Connect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: non-branching paths compaction

2 participants