Skip to content

Commit

Permalink
Feat/support multi level association (#39)
Browse files Browse the repository at this point in the history
* refactor: extract association logic to file

* refactor: extract tag logic to file

* feat: add dag

* feat: support multi level association

* test: correct testing

* test: correct testing at mysqlf

* test: correct testing at postgresf

* test: correct testing at gormf

* refactor: remove unnecessary comment

---------

Co-authored-by: Eyo Chen <[email protected]>
  • Loading branch information
eyo-chen and Eyo Chen authored Sep 28, 2024
1 parent 819105d commit db0476c
Show file tree
Hide file tree
Showing 13 changed files with 2,722 additions and 943 deletions.
427 changes: 427 additions & 0 deletions association.go

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions dag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package gofacto

type dag struct {
nodes map[string]assocNode
edges map[string][]string
}

func newDAG() *dag {
return &dag{
nodes: make(map[string]assocNode),
edges: make(map[string][]string),
}
}

func (d *dag) addNode(node assocNode) {
d.nodes[node.name] = node
}

func (d *dag) addEdge(from, to string) {
d.edges[from] = append(d.edges[from], to)
}

// topologicalSort returns the topological sort of the DAG
func (d *dag) topologicalSort() []assocNode {
visited := make(map[string]bool)
result := make([]assocNode, len(d.nodes))
i := len(result) - 1

var dfs func(node string)
dfs = func(node string) {
if visited[node] {
return
}

visited[node] = true
for _, neighbor := range d.edges[node] {
dfs(neighbor)
}

result[i] = d.nodes[node]
i--
}

for node := range d.nodes {
dfs(node)
}

return result
}

// hasCycle returns true if the DAG has a cycle
func (d *dag) hasCycle() bool {
visited := make(map[string]bool)
recursionStack := make(map[string]bool)

var dfs func(node string) bool
dfs = func(node string) bool {
if recursionStack[node] {
return true
}

if visited[node] {
return false
}

visited[node] = true
recursionStack[node] = true
for _, neighbor := range d.edges[node] {
if dfs(neighbor) {
return true
}
}

recursionStack[node] = false
return false
}

for node := range d.nodes {
if dfs(node) {
return true
}
}

return false
}
Loading

0 comments on commit db0476c

Please sign in to comment.