• Rocket


    https://mp.weixin.qq.com/s/9nikweQUGG5FO3Z8t6feaw

    介绍Parameters中定义的fastProperty的实现。(使用最近的新版本,差别不大)
     
     
    1. groupByIntoSeq
     
    用于把列表中的每个元素,使用键值(key value)函数f进行分组,然后返回分组结果。
     
    1) 两个参数列表:
    a. (xs: Seq[A]): A为列表元素的类型,xs为待分组元素的序列;
    b. (f: A => K): K为键值的类型,f为计算每个元素(A)键值(K)的函数;可以理解为对每个元素计算哈希值,以方便归入某一个类别。
     
    2) 返回值:Seq[(K, immutable.Seq[A])]
    a. 元组:(K, immutable.Seq[A]),二元组的第一个元素为键值,第二个为归为此类的元素,这些元素来自于输入参数xs;
    b. 键值不止一个,所以返回的是一个二元组的序列。这个序列构成了分组结果;
     
    3) 实现
     
    a. 创建一个空的有连接的哈希映射:
    val map = mutable.LinkedHashMap.empty[K, mutable.ListBuffer[A]]
    所谓有连接,即是记录键值对加入Map中的先后顺序,后续遍历时根据这个顺序进行。
     
    b. 计算键值:val key = f(x)
    c. 如果这个键值当前没有映射任何元素,则创建一个空的ListBuffer:
    val l = map.getOrElseUpdate(key, mutable.ListBuffer.empty[A])
    d. 如果有,则取出key映射的ListBuffer:
    val l = map.getOrElseUpdate(key, mutable.ListBuffer.empty[A])
    e. 把x加入到l中:l += x
    f. 逐个循环每一个输入元素,进行分组:for (x <- xs) {}
    g. 把映射表中的映射,转换为二元组:case (k, vs) => k -> vs.toList }
    h. 因为使用的容器是LinkedHashMap,所以转换产生的二元组链表的顺序,跟键值对加入到Map中的顺序一致:map.view.map(...).toList
     
    2. fastPropertyGroup
     
    基于groupByIntoSeq,使用manager的属性进行分组:
     
    1) 使用groupByIntoSeq
     
    两个参数列表:
    a. 元素列表xs:managers.map(m => (p(m), m.address)),每个元素是一个二元组。
     
    二元组第一个元素为p(m)计算得出的键值(K),第二个元素为manager的地址集合。
    p是一个函数,他使用参数TLManagerParameters,返回一个K类型的键值。
     
    b. 计算键值函数f:_._1
     
    这是一个函数,展开形式为:(tuple: Tuple2[K, Seq[AddressSet]]) => tuple._1
     
    c. 返回值:二元组序列
     
    二元组第一个元素:K,第二个元素为K分组中各个m的address(m.address)的序列。
     
    2) 把分组中各个manager的地址集合序列组成一个大的序列:
    其中:vs的类型
     
    3) 找出区分各个分组的最少的比特位
     
    Seq[AddressSet]为一个分组支持的全部地址集合,在AddressDecoder中被成为Port;
    Seq[Seq[AddressSet]]为各个分组支持的地址集合,在AddressDecoder中被称为Ports;
     
    AddressDecoder的作用是找出区分各个Port的地址的最少的比特集合;
     
    4) 尽量合并每个分组的地址集合
     
    5) 返回值:Seq[(K, Seq[AddressSet])]
     
    返回的是分组之后,需要处理的每个分组的地址集合序列。如注释中所说:Compute the simplest AddressSets that decide a key。
     
    3. fastProperty
     
    选择一个属性进行分组,然后判断地址属于哪一个分组:
     
    1) 待判断的地址:address;
    2) 选择熟悉并计算键值的函数:p: TLManagerParameters => K
    3) 通过分组键值,转换为输出的函数:d: K => D
    4) 判断地址集合序列是否包含待判断地址:a.map(_.contains(address)).reduce(_||_)
    5) 把键值转换为输出:d(v)
    6) 独热码输出分组键值转换后结果:Mux1H((a.map(_.contains(address)).reduce(_||_), d(v))*)
     
    4. findFifoIdFast
     
    这是一个使用fifoId进行分组的实例。查找地址属于哪一个fifoId:
     
    1) 选择属性并计算键值的函数p:_.fifoId.map(_+1).getOrElse(0)
     
    这里选择的熟悉为fifoId。计算出的键值为整数类型。
     
    2) 函数d把分组键值转换为可使用的逻辑:(i:Int) => UInt(i)
     
    键值i是实际的fifoId+1,如果没有fifoId则为0。函数d把键值直接存入UInt变量,供其他逻辑使用。
     
    5. hasFifoIdFast
     
    又一个实例:
     
    1) 使用属性fifoId是否定义,把所有managers分成两组:_.fifoId.isDefined
    2) 根据address所属分组,判断address是否属于一个fifoId:(b:Boolean) => Bool(b)
  • 相关阅读:
    aop 注解 开启spring自带的事务
    springmvc异常统一处理
    ZeroMQ接口函数之 :zmq_ctx_get
    ZeroMQ接口函数之 :zmq_ctx_destroy
    ZeroMQ接口函数之 :zmq_connect
    ZeroMQ接口函数之 :zmq_close
    ZeroMQ接口函数之 :zmq_bind
    ZeroMQ接口函数之 :zmq
    nmap的script参数列表
    一个不错的安卓下ssh客户端
  • 原文地址:https://www.cnblogs.com/wjcdx/p/11198621.html
Copyright © 2020-2023  润新知