文档章节

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
烟台
深度优先遍历多叉树结构,输出叶子路径

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

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
学习File类,并教你写FileUtil

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

Wenyi_Feng
05/15
0
0
Trie Tree 实现中文分词器

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

大海之中
07/18
0
0
key-value数据库Kyoto Cabinet笔记

Kyoto Cabinet是一个key-value数据库管理程序的library ,key和value都可以使二进制或者字符串格式。数据存储存分hash和b+ tree模式。 Kyoto Cabinet非常快,在hash模式下,插入100万数据只要...

月下独酌100
2013/02/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

C++ gflags

###定义参数 gflags主要支持的参数类型包括bool,int32, int64, uint64, double, string等,定义参数通过DEFINE_type宏实现, 该宏的三个参数含义分别为命令行参数名,参数默认值,以及参数的...

SibylY
15分钟前
0
0
intellij IDEA Properties中文unicode转码问题

在IDEA中创建了properties文件,发现默认中文不会自动进行unicode转码。如下 在project settings - File Encoding,在标红的选项上打上勾,确定即可 效果图如下: unicode转码后效果...

muzi1994
16分钟前
0
0
Java IO类库之PipedWriter

一、PipedWriter介绍 PipedWriter是字符管道输出流,继承自Writer,功能与PipedOutputStream类似,通过与PipedReader组合使用实现类似管道的功能,在多线程环境下,一个线程使用PipedWriter...

老韭菜
20分钟前
0
0
精简分页组件(手写)

需要引入CSS(没错就是这4行) .pagelist { text-align: center; color: #666; width: 100%; clear: both; margin: 20px 0; padding-top: 20px }.pagelist a { color: #666; margin: 0 2px;......

AK灬
21分钟前
3
0
29 岁成为阿里巴巴 P8,工作前 5 年完成晋升 3 连跳,他如何做到?

泡泡是我的好朋友。今年 31 岁,毕业后就进了阿里巴巴,工作五年内从 P4 晋升至 P6、P7、P8。 和他很少聊到工作,但总觉得他有很棒的职场心得,应该分享出来,于是有了这次采访。希望对职场新...

Java填坑之路
23分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部