类图

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 ,指向了用来存储元素的起始内存。
|
请发表评论