Swift 里 Set(二)概览

类图

Set 是一个结构体,持有另一个结构体_Variant
最终所有的元素存储在一个叫做__RawSetStorage的类里。

内存布局

结构体分配在栈上,和__RawSetStorage相关的变量分配在堆里。
__RawSetStorage 只有一些基本的属性,比如countcapacity等。
在初始化__RawSetStorage时,会在类的尾部继续分配内存,真正的存储Set里的对象。

  static internal func allocate(
    scale: Int8,
    age: Int32?,
    seed: Int?
  ) -> _SetStorage {
    // The entry count must be representable by an Int value; hence the scale's
    // peculiar upper bound.
    _internalInvariant(scale >= 0 && scale < Int.bitWidth - 1)

    let bucketCount = (1 as Int) &<< scale
    let wordCount = _UnsafeBitset.wordCount(forCapacity: bucketCount)
    let storage = Builtin.allocWithTailElems_2(
      _SetStorage<Element>.self,
      wordCount._builtinWordValue, _HashTable.Word.self,
      bucketCount._builtinWordValue, Element.self)

    let metadataAddr = Builtin.projectTailElems(storage, _HashTable.Word.self)
    let elementsAddr = Builtin.getTailAddr_Word(
      metadataAddr, wordCount._builtinWordValue, _HashTable.Word.self,
      Element.self)
    storage._count = 0
    storage._capacity = _HashTable.capacity(forScale: scale)
    storage._scale = scale
    storage._reservedScale = 0
    storage._extra = 0

    if let age = age {
      storage._age = age
    } else {
      // The default mutation count is simply a scrambled version of the storage
      // address.
      storage._age = Int32(
        truncatingIfNeeded: ObjectIdentifier(storage).hashValue)
    }

    storage._seed = seed ?? _HashTable.hashSeed(for: storage, scale: scale)
    storage._rawElements = UnsafeMutableRawPointer(elementsAddr)

    // Initialize hash table metadata.
    storage._hashTable.clear()
    return storage
  }

其中metadata实际上是若干的 UInt,用来指示对应位置有没有被占用,以及用来解决哈希冲突。
_rawElements,指向了用来存储元素的起始内存。

猜你喜欢

转载自www.cnblogs.com/huahuahu/p/Swift-li-Set-er-gai-lan.html