文档章节

tree路径匹配抽象(2)

lost_o0
 lost_o0
发布于 2015/03/02 10:50
字数 554
阅读 31
收藏 0

接着上一篇的 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


© 著作权归作者所有

共有 人打赏支持
lost_o0
粉丝 10
博文 37
码字总数 31139
作品 0
烟台
关于SQL解析,为何编程语言解析器ANTLR更胜一筹?

作者介绍 杜红军,京东数科软件工程师,多年中间件开发及系统设计经验,对Spring、MyBatis等相关开源技术有深入了解。目前在Sharding-Sphere团队负责SQL解析开发工作。 相对于其他编程语言来...

DBAplus社群
10/20
0
0
深度优先遍历多叉树结构,输出叶子路径

树结构的深度优先遍历是应用中常见的问题 在实际项目中,多叉树出现的比较普遍,常用来存储类似字典词条的路径信息。 多叉树对于在一个序列中找到前缀匹配的所有路径是可行的选择,例如找到一...

xnhcx
2015/02/08
0
2
数据可视化(三)基于 Graphviz 实现程序化绘图

摘要 OmniGraffle 和 Graphviz Why draw when you can code? Graphviz 简介 最佳 Graphviz 实践(一):流程图、数据结构图、网络路径 Trace Route 最佳 Graphviz 实践(二):复杂社会关系链分析...

RiboseYim
2017/09/21
0
0
Trie Tree 实现中文分词器

Trie Tree 简介 Trie Tree,又称单词字典树、查找树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频...

大海之中
07/18
0
0
学习File类,并教你写FileUtil

写在前面的话 程序包括代码、数据、文档。在当今,数据对我们来说,尤为重要。或存数据库或写入文件。这样对于File类的学习,就显得十分必要。 编码 1、用什么编码写,就用什么编码读 2、掌握...

Wenyi_Feng
05/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

原型模式

1、原型模式-定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 克隆(浅度克隆->拷贝值类型或者引用,深度克隆->创建新的对象,开辟新的内存) 例如客户端知道抽象Pro...

阿元
今天
32
0
awk命令扩展使用操作

awk 中使用外部shell变量 示例1 [root@centos01 t1022]# A=888[root@centos01 t1022]# echo "" | awk -v GET_A=$A '{print GET_A}'888[root@centos01 t1022]# echo "aaaaaaaaaaaaa" | aw......

野雪球
今天
28
0
深入解析MySQL视图VIEW

Q:什么是视图?视图是干什么用的? A:视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。   通过视图,可以展现基表的部分数据;...

IT--小哥
今天
37
0
虚拟机学习之二:垃圾收集器和内存分配策略

1.对象是否可回收 1.1引用计数算法 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时候计数器值为0的对象就是不可能...

贾峰uk
今天
24
0
smart-doc功能使用介绍

smart-doc从8月份底开始开源发布到目前为止已经迭代了几个版本。在这里非常感谢那些敢于用smart-doc去做尝试并积极提出建议的社区用户。因此决定在本博客中重要说明下smart-doc的功能,包括使...

上官胡闹
昨天
36
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部