• Rocket


    https://mp.weixin.qq.com/s/qqL2XWqAhVcnGSxs6kxhLg

     
    介绍IdRange的实现
     
     
    1. 基本定义
     
    A non-empty half-open range; [start, end)
     
    非空,半闭合区间。
     
    限定条件如下:
    a. start >= 0;
    b. start <= end;
     
    2. compare
     
    比较方法。用于排序。
     
    3. overlaps
     
    判断是否重叠。
     
    4. contains
     
    this contains x,x的区间完全处在this的区间范围内。
     
    电路生成器:
    a. 如果this.size == 0,那么this不可能包含x;
    b. 如果this.size == 1,那么只需要判断x是否等于start即可;
    c. 把this分成两部分进行比较:高位一直不变的部分和低位变化的部分。
    首先,this的有效部分即从start到end-1的过程中,高位始终保持不变的位,与x相应的高位进行比较;
    其次,低位变化的位数进行比较,即:LowPartOf(start) <= LowPartOf(x) <= LowPartOf(end-1);
    其中:
    LowPartOf(start) = start & uncommonMask;
    LowPartOf(end-1) = (end-1) & uncommonMask;
    LowPartOf(x) = uncommonBits,其计算使用位截取;
     
    PS. 这里有一个有意思的地方:(x >> smallestCommonBit) === UInt(start >> smallestCommonBit)
    因为x和start的类型不同,所以这里的两个移位符号并不是同一个方法。
    虽然在构建时,第一个移位和第二个移位都会执行,但第一个移位方法只是添加一个针对x的移位命令,用于构建一个移位逻辑,真正的移位动作发生在硬件中。而第二个针对start的移位方法,是切切实实直接执行的移位动作,当时就发生了移位(在软件中)。
     
    5. shift
     
    区间平移。
     
    6. size
     
    区间包含整数的个数。
     
    7. isEmpty
     
    区间是否为空。
     
    8. range
     
    返回一个Range对象。
     
    9. 伴生对象
     
    检查IdRange序列s中的区间是否存在重叠。
     
    10. 附录
     
    IdRange:
    // A non-empty half-open range; [start, end)
    case class IdRange(start: Int, end: Int) extends Ordered[IdRange]
    {
    require (start >= 0, s"Ids cannot be negative, but got: $start.")
    require (start <= end, "Id ranges cannot be negative.")
     
    def compare(x: IdRange) = {
    val primary = (this.start - x.start).signum
    val secondary = (x.end - this.end).signum
    if (primary != 0) primary else secondary
    }
     
    def overlaps(x: IdRange) = start < x.end && x.start < end
    def contains(x: IdRange) = start <= x.start && x.end <= end
     
    def contains(x: Int) = start <= x && x < end
    def contains(x: UInt) =
    if (size == 0) {
    Bool(false)
    } else if (size == 1) { // simple comparison
    x === UInt(start)
    } else {
    // find index of largest different bit
    val largestDeltaBit = log2Floor(start ^ (end-1))
    val smallestCommonBit = largestDeltaBit + 1 // may not exist in x
    val uncommonMask = (1 << smallestCommonBit) - 1
    val uncommonBits = (x | UInt(0, width=smallestCommonBit))(largestDeltaBit, 0)
    // the prefix must match exactly (note: may shift ALL bits away)
    (x >> smallestCommonBit) === UInt(start >> smallestCommonBit) &&
    // firrtl constant prop range analysis can eliminate these two:
    UInt(start & uncommonMask) <= uncommonBits &&
    uncommonBits <= UInt((end-1) & uncommonMask)
    }
     
    def shift(x: Int) = IdRange(start+x, end+x)
    def size = end - start
    def isEmpty = end == start
     
    def range = start until end
    }
     
    object IdRange
    {
    def overlaps(s: Seq[IdRange]): Option[(IdRange, IdRange)] = if (s.isEmpty) None else {
    val ranges = s.sorted
    (ranges.tail zip ranges.init) find { case (a, b) => a overlaps b }
    }
    }
     
     
  • 相关阅读:
    sqlite3.6.10的vs2005 编译错误
    .NET网络编程学习(二)
    Lucene的使用(一)
    .NET网络编程学习(三)
    深入学习Heritrix解析Frontier(链接工厂)
    .NET网络编程学习(一)
    Subversion的Windows服务配置
    深入学习Heritrix解析处理器(Processor)
    log4net的使用
    深入学习Heritrix解析CrawlController
  • 原文地址:https://www.cnblogs.com/wjcdx/p/10660410.html
Copyright © 2020-2023  润新知