Swift 里 Set(二)概览
类图

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

结构体分配在栈上,和__RawSetStorage
相关的变量分配在堆里。
__RawSetStorage
只有一些基本的属性,比如count
、capacity
等。
在初始化__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
,指向了用来存储元素的起始内存。
下起雨,也要勇敢前行