All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scalax.collection.constrained.mutable.AdjacencyListGraph.scala Maven / Gradle / Ivy

The newest version!
package scalax.collection.constrained
package mutable

import scala.language.higherKinds
import scala.collection.Set

import scalax.collection.GraphPredef.EdgeLikeIn
import scalax.collection.mutable.{AdjacencyListGraph => SimpleAdjacencyListGraph}
import scalax.collection.config.{AdjacencyListArrayConfig, GraphConfig}

import PreCheckFollowUp._
import config.GenConstrainedConfig

/** Implements an adjacency list based graph representation.
  *
  * An adjacency list based representation speeds up traversing a graph along its paths
  * by storing the list of connecting edges to each node.
  *
  * @author Peter Empen
  */
trait AdjacencyListGraph[
    N, E[X] <: EdgeLikeIn[X], +This[X, Y[X] <: EdgeLikeIn[X]] <: AdjacencyListGraph[X, Y, This] with Graph[X, Y]]
    extends SimpleAdjacencyListGraph[N, E, This]
    with GraphLike[N, E, This] {
  selfGraph: This[N, E] =>

  protected type Config <: GraphConfig with GenConstrainedConfig with AdjacencyListArrayConfig

  override protected def initialize(nodes: Traversable[N], edges: Traversable[E[N]]): Unit = withoutChecks {
    super.initialize(nodes, edges)
  }

  type NodeSetT = NodeSet
  @SerialVersionUID(8083L)
  final class NodeSet extends super[AdjacencyListGraph].NodeSet with super.NodeSet {

    override def add(node: NodeT): Boolean = add_?(node) getOrElse false

    def add_?(node: NodeT): Either[ConstraintViolation, Boolean] = {
      def doAdd = { coll += node; true }
      if (coll.contains(node)) Right(false)
      else if (checkSuspended) Right(doAdd)
      else {
        val preCheckResult = preAdd(node)
        preCheckResult.followUp match {
          case Complete => Right(doAdd)
          case PostCheck =>
            doAdd
            postAdd(AdjacencyListGraph.this, Set(node.value), Set.empty, preCheckResult).fold(
              { failure =>
                withoutChecks(coll -= node)
                Left(failure)
              },
              _ => Right(true)
            )
          case Abort => Left(preCheckResult)
        }
      }
    }
  }

  type EdgeSetT = EdgeSet
  @SerialVersionUID(8084L)
  final class EdgeSet extends super.EdgeSet {

    override def add(edge: EdgeT): Boolean = add_?(edge) getOrElse false

    def add_?(edge: EdgeT): Either[ConstraintViolation, Boolean] = {
      def added = super.add(edge)
      if (checkSuspended) Right(added)
      else {
        val preCheckResult = preAdd(edge.toOuter)
        preCheckResult.followUp match {
          case Complete => Right(added)
          case PostCheck =>
            if (added)
              postAdd(selfGraph, Set.empty[N], Set(edge.toOuter), preCheckResult).fold(
                failure => {
                  remove(edge)
                  (edge.nodes filterNot contains) foreach nodes.remove
                  Left(failure)
                },
                _ => Right(true)
              )
            else Right(false)
          case Abort => Left(preCheckResult)
        }
      }
    }

    protected def checkedRemove(edge: EdgeT,
                                forced: Boolean,
                                remove: EdgeT => Boolean): Either[ConstraintViolation, Boolean] =
      if (checkSuspended) Right(remove(edge))
      else {
        val preCheckResult = preSubtract(edge.asInstanceOf[self.EdgeT], !forced)
        preCheckResult.followUp match {
          case Complete => Right(remove(edge))
          case PostCheck =>
            if (remove(edge))
              postSubtract(selfGraph, Set.empty[N], Set(edge.toOuter), preCheckResult).fold(
                failure => { selfGraph += edge; Left(failure) },
                _ => Right(true)
              )
            else Right(false)
          case Abort => Left(preCheckResult)
        }
      }

    override def remove(edge: EdgeT): Boolean                       = remove_?(edge) getOrElse false
    def remove_?(edge: EdgeT): Either[ConstraintViolation, Boolean] = checkedRemove(edge, forced = false, super.remove)

    override def removeWithNodes(edge: EdgeT): Boolean = removeWithNodes_?(edge) getOrElse false
    def removeWithNodes_?(edge: EdgeT): Either[ConstraintViolation, Boolean] =
      checkedRemove(edge, forced = true, (e: EdgeT) => withoutChecks(super.removeWithNodes(e)))
  }

  def add_?(node: N): Either[ConstraintViolation, Boolean]    = nodes add_? Node(node)
  def add_?(edge: E[N]): Either[ConstraintViolation, Boolean] = edges add_? Edge(edge)

  def remove_?(node: N): Either[ConstraintViolation, Boolean]    = nodes remove_? Node(node)
  def remove_?(edge: E[N]): Either[ConstraintViolation, Boolean] = edges remove_? Edge(edge)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy