Files
obsidian-mcp/internal/domain/graph.go
Andrey Epifancev da289d4a7e feat: Implement foundation layer with domain entities and repository interfaces
- Add complete domain layer: Note, Vault, WikiLink, Tag, Frontmatter, Graph entities
- Implement repository interfaces for data access abstraction
- Create comprehensive configuration system with YAML and env support
- Add CLI entry point with signal handling and graceful shutdown
- Fix mermaid diagram syntax in design.md (array notation)
- Add CLAUDE.md for development guidance

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-08 10:22:28 +04:00

117 lines
2.1 KiB
Go

package domain
import "sync"
type Graph struct {
adjacencyList map[string]map[string]bool
mutex sync.RWMutex
}
func NewGraph() *Graph {
return &Graph{
adjacencyList: make(map[string]map[string]bool),
}
}
func (g *Graph) AddEdge(from, to string) {
g.mutex.Lock()
defer g.mutex.Unlock()
if g.adjacencyList[from] == nil {
g.adjacencyList[from] = make(map[string]bool)
}
g.adjacencyList[from][to] = true
}
func (g *Graph) RemoveEdge(from, to string) {
g.mutex.Lock()
defer g.mutex.Unlock()
if g.adjacencyList[from] != nil {
delete(g.adjacencyList[from], to)
if len(g.adjacencyList[from]) == 0 {
delete(g.adjacencyList, from)
}
}
}
func (g *Graph) GetOutlinks(path string) []string {
g.mutex.RLock()
defer g.mutex.RUnlock()
var outlinks []string
if targets, exists := g.adjacencyList[path]; exists {
for target := range targets {
outlinks = append(outlinks, target)
}
}
return outlinks
}
func (g *Graph) GetBacklinks(path string) []string {
g.mutex.RLock()
defer g.mutex.RUnlock()
var backlinks []string
for source, targets := range g.adjacencyList {
if targets[path] {
backlinks = append(backlinks, source)
}
}
return backlinks
}
func (g *Graph) HasEdge(from, to string) bool {
g.mutex.RLock()
defer g.mutex.RUnlock()
if targets, exists := g.adjacencyList[from]; exists {
return targets[to]
}
return false
}
func (g *Graph) RemoveNode(path string) {
g.mutex.Lock()
defer g.mutex.Unlock()
delete(g.adjacencyList, path)
for source, targets := range g.adjacencyList {
delete(targets, path)
if len(targets) == 0 {
delete(g.adjacencyList, source)
}
}
}
func (g *Graph) GetAllNodes() []string {
g.mutex.RLock()
defer g.mutex.RUnlock()
nodeSet := make(map[string]bool)
for source := range g.adjacencyList {
nodeSet[source] = true
}
for _, targets := range g.adjacencyList {
for target := range targets {
nodeSet[target] = true
}
}
var nodes []string
for node := range nodeSet {
nodes = append(nodes, node)
}
return nodes
}
func (g *Graph) Clear() {
g.mutex.Lock()
defer g.mutex.Unlock()
g.adjacencyList = make(map[string]map[string]bool)
}