| 204 | } |
| 205 | |
| 206 | private void removeAt(int index) { |
| 207 | if (index < 0) { |
| 208 | int from = -index - 1; |
| 209 | erase(from); |
| 210 | free++; |
| 211 | |
| 212 | // after we have freed up a slot |
| 213 | // consider non-empty keys directly below |
| 214 | // they may have been a direct hit but because |
| 215 | // directly hit slot wasn't empty these keys would |
| 216 | // have moved. |
| 217 | // |
| 218 | // After slot if freed these keys require re-hash |
| 219 | from = (from + 1) & mask; |
| 220 | for ( |
| 221 | T key = keys[from]; |
| 222 | key != noEntryKey; |
| 223 | from = (from + 1) & mask, key = keys[from] |
| 224 | ) { |
| 225 | int idealHit = Hash.spread(key.hashCode()) & mask; |
| 226 | if (idealHit != from) { |
| 227 | int to; |
| 228 | if (keys[idealHit] != noEntryKey) { |
| 229 | to = probe(key, idealHit); |
| 230 | } else { |
| 231 | to = idealHit; |
| 232 | } |
| 233 | |
| 234 | if (to > -1) { |
| 235 | move(from, to); |
| 236 | } |
| 237 | } |
| 238 | } |
| 239 | } |
| 240 | } |
| 241 | } |