module Spark.Core.Internal.DAGStructures where
import qualified Data.Map.Strict as M
import qualified Data.Text as T
import Data.ByteString(ByteString)
import Data.Vector(Vector)
import Data.Foldable(toList)
import Data.Hashable(Hashable)
import GHC.Generics(Generic)
import Formatting
import Spark.Core.Internal.Utilities
newtype VertexId = VertexId { unVertexId :: ByteString } deriving (Eq, Ord, Generic)
data Edge e = Edge {
edgeFrom :: !VertexId,
edgeTo :: !VertexId,
edgeData :: !e
}
data Vertex v = Vertex {
vertexId :: !VertexId,
vertexData :: !v
}
data VertexEdge e v = VertexEdge {
veEndVertex :: !(Vertex v),
veEdge :: !(Edge e) }
type AdjacencyMap v e = M.Map VertexId (Vector (VertexEdge e v))
data Graph v e = Graph {
gEdges :: !(AdjacencyMap v e),
gVertices :: !(Vector (Vertex v))
}
class GraphVertexOperations v where
vertexToId :: v -> VertexId
expandVertexAsVertices :: v -> [v]
class (GraphVertexOperations v) => GraphOperations v e where
expandVertex :: v -> [(e,v)]
instance Functor Vertex where
fmap f vx = vx { vertexData = f (vertexData vx) }
instance Functor Edge where
fmap f ed = ed { edgeData = f (edgeData ed) }
instance (Show v) => Show (Vertex v) where
show vx = "Vertex(vId=" ++ show (vertexId vx) ++ " v=" ++ show (vertexData vx) ++ ")"
instance (Show e) => Show (Edge e) where
show ed = "Edge(from=" ++ show (edgeFrom ed) ++ " to=" ++ show (edgeTo ed) ++ " e=" ++ show (edgeData ed) ++ ")"
instance (Show v, Show e) => Show (VertexEdge e v) where
show (VertexEdge v e) = "(" ++ show v ++ ", " ++ show e ++ ")"
instance (Show v, Show e) => Show (Graph v e) where
show g =
let vxs = toList $ gVertices g <&> \(Vertex vid x) ->
sformat (sh%":"%sh) vid x
vedges = foldMap toList (M.elems (gEdges g))
edges = (veEdge <$> vedges) <&> \(Edge efrom eto x) ->
sformat (sh%"->"%sh%"->"%sh) efrom x eto
vxs' = T.intercalate "," vxs
eds' = T.intercalate " " edges
str = T.concat ["Graph{", vxs', ", ", eds', "}"]
in T.unpack str
instance Hashable VertexId
instance Show VertexId where
show (VertexId bs) = let s = show bs in
if length s > 9 then
(drop 1 . take 6) s ++ ".."
else
s