This unique id generation is pretty cool, but I am not sure if it's worth reusing RankedRDD. The whole thing can be implemented in 8 lines of code:
```scala
def assignUniqueIds[T: ClassTag](): RDD[(Long, T)] = {
  val n = rdd.partitions.size
  this.mapPartitionsWithIndex { case (k, iter) =>
    iter.zipWithIndex.map { case (item, i) =>
      (i * n + k, item
    }
  }
}
```

If you don't have to consider the case of assignUniqueIds, you can simplify RankedRDD itself by removing the startRanks field in RankedRDD and merge assignRanks into its constructor.