Files
2026-07-13 12:32:21 +08:00

74 lines
1.5 KiB
Lua

local insert = table.insert
local _M = {}
local function visit(current, neighbors_map, visited, marked, sorted)
if visited[current] then
return true
end
if marked[current] then
return nil, "Cycle detected, cannot sort topologically"
end
marked[current] = true
local schemas_pointing_to_current = neighbors_map[current]
if schemas_pointing_to_current then
local neighbor, ok, err
for i = 1, #schemas_pointing_to_current do
neighbor = schemas_pointing_to_current[i]
ok, err = visit(neighbor, neighbors_map, visited, marked, sorted)
if not ok then
return nil, err
end
end
end
marked[current] = false
visited[current] = true
insert(sorted, 1, current)
return true
end
function _M.topological_sort(items, get_neighbors)
local neighbors_map = {}
local source, destination
local neighbors
for i = 1, #items do
source = items[i] -- services
neighbors = get_neighbors(source)
for j = 1, #neighbors do
destination = neighbors[j] --routes
neighbors_map[destination] = neighbors_map[destination] or {}
insert(neighbors_map[destination], source)
end
end
local sorted = {}
local visited = {}
local marked = {}
local current, ok, err
for i = 1, #items do
current = items[i]
if not visited[current] and not marked[current] then
ok, err = visit(current, neighbors_map, visited, marked, sorted)
if not ok then
return nil, err
end
end
end
return sorted
end
return _M