| 163 | /////////////////////////////////////////////////////////////////////////////// |
| 164 | |
| 165 | void PairManagerData::removePair(PxU32 /*id0*/, PxU32 /*id1*/, PxU32 hashValue, PxU32 pairIndex) |
| 166 | { |
| 167 | // Walk the hash table to fix mNext |
| 168 | { |
| 169 | PxU32 offset = mHashTable[hashValue]; |
| 170 | PX_ASSERT(offset!=INVALID_ID); |
| 171 | |
| 172 | PxU32 previous=INVALID_ID; |
| 173 | while(offset!=pairIndex) |
| 174 | { |
| 175 | previous = offset; |
| 176 | offset = mNext[offset]; |
| 177 | } |
| 178 | |
| 179 | // Let us go/jump us |
| 180 | if(previous!=INVALID_ID) |
| 181 | { |
| 182 | PX_ASSERT(mNext[previous]==pairIndex); |
| 183 | mNext[previous] = mNext[pairIndex]; |
| 184 | } |
| 185 | // else we were the first |
| 186 | else mHashTable[hashValue] = mNext[pairIndex]; |
| 187 | // we're now free to reuse mNext[pairIndex] without breaking the list |
| 188 | } |
| 189 | #if PX_DEBUG |
| 190 | mNext[pairIndex]=INVALID_ID; |
| 191 | #endif |
| 192 | // Invalidate entry |
| 193 | |
| 194 | // Fill holes |
| 195 | { |
| 196 | // 1) Remove last pair |
| 197 | const PxU32 lastPairIndex = mNbActivePairs-1; |
| 198 | if(lastPairIndex==pairIndex) |
| 199 | { |
| 200 | mNbActivePairs--; |
| 201 | } |
| 202 | else |
| 203 | { |
| 204 | const InternalPair* last = &mActivePairs[lastPairIndex]; |
| 205 | const PxU32 lastHashValue = hash(last->getId0(), last->getId1()) & mMask; |
| 206 | |
| 207 | // Walk the hash table to fix mNext |
| 208 | PxU32 offset = mHashTable[lastHashValue]; |
| 209 | PX_ASSERT(offset!=INVALID_ID); |
| 210 | |
| 211 | PxU32 previous=INVALID_ID; |
| 212 | while(offset!=lastPairIndex) |
| 213 | { |
| 214 | previous = offset; |
| 215 | offset = mNext[offset]; |
| 216 | } |
| 217 | |
| 218 | // Let us go/jump us |
| 219 | if(previous!=INVALID_ID) |
| 220 | { |
| 221 | PX_ASSERT(mNext[previous]==lastPairIndex); |
| 222 | mNext[previous] = mNext[lastPairIndex]; |
no test coverage detected