博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
tree路径匹配抽象(2)
阅读量:6798 次
发布时间:2019-06-26

本文共 4589 字,大约阅读时间需要 15 分钟。

hot3.png

接着上一篇的 tree路径匹配抽象(1),我们开始看如何对tree进行索引,akka的路径匹配包含了远程节点的匹配,这样就得引入多个通信机制(akka采用消息),为了简化,我们先假设只在一个本地tree中进行索引:

object ActorSelection {//...省略  /**   * Construct an ActorSelection from the given string representing a path   * relative to the given target. This operation has to create all the   * matching magic, so it is preferable to cache its result if the   * intention is to send messages frequently.   */  def apply(anchorRef: ActorRef, path: String): ActorSelection = apply(anchorRef, path.split("/+"))//ActorRef可以被当作当前路径的引用  /**   * Construct an ActorSelection from the given string representing a path   * relative to the given target. This operation has to create all the   * matching magic, so it is preferable to cache its result if the   * intention is to send messages frequently.   */  def apply(anchorRef: ActorRef, elements: Iterable[String]): ActorSelection = {    val compiled: immutable.IndexedSeq[SelectionPathElement] = elements.collect({      case x if !x.isEmpty ⇒        if ((x.indexOf('?') != -1) || (x.indexOf('*') != -1)) SelectChildPattern(x)        else if (x == "..") SelectParent        else SelectChildName(x)    })(scala.collection.breakOut)//直接转换为immutable.IndexedSeq[SelectionPathElement]    new ActorSelection with ScalaActorSelection {      override val anchor = anchorRef      override val path = compiled    }  }//------上面是将字符串转化为SelectionPathElement,下面则是根据SelectionPathElement进行索引tree值  /**   * INTERNAL API   * The receive logic for ActorSelectionMessage. The idea is to recursively descend as far as possible   * with local refs and hand over to that “foreign” child when we encounter it.   */  private[akka] def deliverSelection(anchor: InternalActorRef, sender: ActorRef, sel: ActorSelectionMessage): Unit =    if (sel.elements.isEmpty)      anchor.tell(sel.msg, sender)//自己    else {      val iter = sel.elements.iterator      @tailrec def rec(ref: InternalActorRef): Unit = {        ref match {          case refWithCell: ActorRefWithCell ⇒            def emptyRef = new EmptyLocalActorRef(refWithCell.provider, anchor.path / sel.elements.map(_.toString),              refWithCell.underlying.system.eventStream)            iter.next() match {              case SelectParent ⇒                val parent = ref.getParent                if (iter.isEmpty)                  parent.tell(sel.msg, sender)                else                  rec(parent)              case SelectChildName(name) ⇒                val child = refWithCell.getSingleChild(name)                if (child == Nobody) {                  // don't send to emptyRef after wildcard fan-out                  if (!sel.wildcardFanOut) emptyRef.tell(sel, sender)                } else if (iter.isEmpty)                  child.tell(sel.msg, sender)                else                  rec(child)              case p: SelectChildPattern ⇒                // fan-out when there is a wildcard                val chldr = refWithCell.children                if (iter.isEmpty) {                  // leaf                  val matchingChildren = chldr.filter(c ⇒ p.pattern.matcher(c.path.name).matches)                  if (matchingChildren.isEmpty && !sel.wildcardFanOut)                    emptyRef.tell(sel, sender)                  else                    matchingChildren.foreach(_.tell(sel.msg, sender))                } else {                  val matchingChildren = chldr.filter(c ⇒ p.pattern.matcher(c.path.name).matches)                  // don't send to emptyRef after wildcard fan-out                   if (matchingChildren.isEmpty && !sel.wildcardFanOut)                    emptyRef.tell(sel, sender)                  else {                    val m = sel.copy(elements = iter.toVector,                      wildcardFanOut = sel.wildcardFanOut || matchingChildren.size > 1)                    matchingChildren.foreach(c ⇒ deliverSelection(c.asInstanceOf[InternalActorRef], sender, m))                  }                }            }          //case _ ⇒            // foreign ref, continue by sending ActorSelectionMessage to it with remaining elements            //ref.tell(sel.copy(elements = iter.toVector), sender)        }      }      rec(anchor)    }}

既然path允许正则索引,那么path最好有个命名规则,akka的命名规则为:

/**   * This Regular Expression is used to validate a path element (Actor Name).   * Since Actors form a tree, it is addressable using an URL, therefore an Actor Name has to conform to:   * http://www.ietf.org/rfc/rfc2396.txt   */  val ElementRegex = """(?:[-\w:@&=+,.!~*'_;]|%\p{XDigit}{2})(?:[-\w:@&=+,.!~*'$_;]|%\p{XDigit}{2})*""".r

转载于:https://my.oschina.net/myprogworld/blog/381197

你可能感兴趣的文章
RHEL6.3下配置简单Apache https
查看>>
利用Cocos2dx-3.0新物理特性模拟弹珠迷宫
查看>>
Office 365系列之三:Office365初体验
查看>>
VMware View client for iPad在医疗行业的应用
查看>>
Altiris 7.1 Agent
查看>>
独家爆料:创宇云与小鸟云的故事
查看>>
Windows Server 2012 RMS for Exchange Server 2013
查看>>
SUSE LINUX 10 NOVELL-ZMD错误解析
查看>>
Linux网络IP配置
查看>>
人工智能:智慧型手机的未来
查看>>
在EF中构建业务层小记
查看>>
PowerShell 学习笔记——使用帮助系统
查看>>
CentOS6.5+mysql5.1源码安装过程
查看>>
投篮游戏选择点——自我认可和责任测试
查看>>
Jar与外部文件的信息交互
查看>>
做企业不能有上帝的情怀
查看>>
FireEye:K3chang行动***欧洲外交部门
查看>>
Lync 小技巧-39-批量-设置-AD-分机-手机-启用-Lync-设置-Lync-分机
查看>>
关于Spring MVC 4,你需要知道的那些事
查看>>
如何远程调试Python代码
查看>>