tree路径匹配抽象(2)

接着上一篇的 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
时间: 2024-10-16 13:49:11

tree路径匹配抽象(2)的相关文章

Struts 之 通配符 路径匹配 常量用法 配置默认值

Struts 框架学习 Action的开发的几种方式 方式1 : 继承ActionSupport     如果使用Struts校验功能,必须继承此类 方式2 : 实现Action接口 方式3 :不继承任何类,不实现任何接口 1.通配符: 在Struts中配置信息,可以用*与{1} 可以优化配置 public class UserAction { private String userName; public void setUserName(String userName) { this.use

nginx 的路径匹配

nginx 的路径匹配 = 精确匹配, 后面是文件名, 不能是文件夹 /image 精确匹配, 后面是文件夹, 如果这个匹配到了, 还可能会被正则替换掉 ^~ image 精确匹配, 后面是文件夹, 如果这个匹配到了, 不会继续匹配正则 ~ image 正则 ~* image 正则, 不区分大小写 匹配规则: 普通命中匹配命中最长的 location / { ... } location /image { ... } 正则表达式一旦匹配到就不会再匹配, 因此第二条永远不会被匹配 location

Spring MVC的路径匹配

Spring MVC中的路径匹配比起标准web.xml的servlet映射要灵活得多.路径匹配的默认策略是由org.springframework.util.AntPathMatcher实现的.顾名思义,路径模式是采用Apache Ant(http://ant.apache.org)风格路径来编写的.Ant风格路径有三种类型的通配符(列于表5-2中),能相互结合以创建多样灵活的路径模式.见表5-3中的模式例子. 表5-2  Ant通配符字符 通配符描述 ?  匹配一个字符 *  匹配零个或多个字

SpringMVC路径匹配规则AntPathMatcher(转)

SpringMVC的路径匹配规则是依照Ant的来的. 实际上不只是SpringMVC,整个Spring框架的路径解析都是按照Ant的风格来的. 在Spring中的具体实现,详情参见 org.springframework.util.AntPathMatcher. 具体规则如下(来自Spring AntPathMatcher源码注释): * {@link PathMatcher} implementation for Ant-style path patterns. * * <p>Part of

spring mvc路径匹配原则

在Spring MVC中经常要用到拦截器,在配置需要要拦截的路径时经常用到<mvc:mapping/>子标签,其有一个path属性,它就是用来指定需要拦截的路径的.例如: <mvc:interceptor>     <mvc:mapping path="/**" />         <bean class="com.test.interceptor.TestInterceptor" /> </mvc:inter

SpringMVC路径匹配规则AntPathMatcher

? 匹配1个字符 * 匹配0个或多个字符 ** 匹配路径中的0个或多个目录 {spring:[a-z]+} 将正则表达式[a-z]+匹配到的值,赋值给名为 spring 的路径变量.(PS:必须是完全匹配才行,在SpringMVC中只有完全匹配才会进入controller层的方法)

正则 路径匹配

最近一个项目需要正则匹配目录,以实现根据路径访问文件或者实现下载功能! path = r'(?P<path>[\w\d_ -/.]*)$'urlpatterns = [    #url(r'^admin/', include(admin.site.urls)),    url(r'^home/file'+path_end, view.file)] 正则表达式不常用的话容易遗忘,推荐一个参考教程 https://deerchao.net/tutorials/regex/regex.htm

AntPathMatcher做路径匹配

转发自: http://www.cnblogs.com/leftthen/p/5212221.html 需要看详细的请看上面的链接 这里以我这里的一个Filter 中需要对路径做例外处理,filter配置如下 <bean id="adminOnlineUserFilter" class="com.midea.finance.framework.authority.filter.AdminOnlineUserFilter"> <property na

Perl6 Bailador框架(3):路径匹配

use v6; use Bailador; =begin pod 注意的是, 当/:one设置时 虽然你有/admin或/about, 但这个/:one不会跟现有的匹配 只跟没有的匹配: 也就是说, 当你输入/admin或/about时, get '/:one'对应的匿名子例程不会运行 当你访问的不是/admin或/about时, get '/:one'发条会执行 还有一点要注意的就是 当你设置/admin时, 所有/admin或/admin*都会返回get '/admin'子例程 如果你要设置