IOS – SideTable
Understand hashTables
A hash table is also a hash table
It’s the same as binary trees, linked lists, things like that. It is a data structure designed to hold data
What basic knowledge is needed
- Pointers and arrays
- The list
- Modular arithmetic
Hash table construction method
An array of | Pointer to the | Pointer to the | Pointer to the | Pointer to the | |||
---|---|---|---|---|---|---|---|
The subscript | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
Why is it called a Hash table, because it has a Hash function
Key words: X -> F (x) -> subscript
The key of a hash table is an array, which obtains a hash function f(key) based on the key, then obtains the index, and then obtains the value in the index
The hash function
Hash function is based on the keyword design, there are many kinds of functions, the main principle is based on the size of the array modular operation.
(Keyword) % (array size)
Example: 20048157%7 (results in 0-16)
The size of an array is generally designed to be a bit prime because it needs to be evenly spread
What about conflicts?
Linked list solution
Add a next pointer when writing a structure (like a linked list)
Data | | next – > data next
In case of conflict, write the data to the next location
eg:
Array size 7
Hash function: subscript = keyword mod 7
The subscript | data | List to solve |
---|---|---|
0 | ||
1 | 15 | 22(list while loop query) |
2 | 16 | |
3 | 24 | |
4 | ||
5 | ||
6 |
Open address (this piece needs to find by yourself)
Instead of using the next pointer, open all other subscripts to the public
Methods of opening addresses:
- Linear detection method
- Square detection
- Double hash
Why do you design hash tables
Because hash table lookup is fast, it is faster than searching binary trees
Disadvantages of hash tables
The more full the table, the more conflicts and the worse the performance.
SideTable
SideTable is just a hash table
The SideTable serves as a container for memory management information and stores multiple memory management information in the system. The system binds the hash value of the instance object to the SideTable.
An instance object corresponds to a SideTable, and a SideTable can be shared by multiple instance objects
Source structure
struct SideTable {
/** spin lock */
spinlock_t slock;
// Reference count
RefcountMap refcnts;
// Weak reference table, hash table
weak_table_t weak_table;
SideTable() {
memset(&weak_table, 0.sizeof(weak_table));
}
~SideTable() {
// Can't delete SideTable
_objc_fatal("Do not delete SideTable.");
}
/ / lock
void lock(a) { slock.lock(a); }void unlock(a) { slock.unlock(a); }// Reset the lock
void forceReset(a) { slock.forceReset(); }
// Address-ordered lock discipline for a pair of side tables.
template<HaveOld, HaveNew>
static void lockTwo(SideTable *lock1, SideTable *lock2);
template<HaveOld, HaveNew>
static void unlockTwo(SideTable *lock1, SideTable *lock2);
};
// Returns a SideTable pointer with memory aligned
alignas(StripedMap<SideTable>) static uint8_t
SideTableBuf[sizeof(StripedMap<SideTable>)];
// Initialize SideTable
static void SideTableInit(a) {
new (SideTableBuf) StripedMap<SideTable>();
}
// Get the SideTable array
static StripedMap<SideTable>& SideTables(a) {
return *reinterpret_cast<StripedMap<SideTable>*>(SideTableBuf);
}
Copy the code
Libc calls SideTable before C++ initializes the object and does not use a global pointer. Therefore, this method is used for initialization.
SideTables is a pointer to an instance of the StripedMap template class initialized with the SideTable structure. StripedMap is a class implemented using a split lock, with an array of internal members indexed by a hash algorithm. Its algorithm is as follows:
enum { StripeCount = 8 };
static unsigned int indexForPointer(const void *p) {
uintptr_t addr = reinterpret_cast<uintptr_t>(p);
return ((addr >> 4) ^ (addr >> 9)) % StripeCount;
}
Copy the code
SideTable hash hash hash hash hash hash hash hash hash hash hash hash hash hash hash hash hash hash hash hash