* Ensure that the PrivateRefCountArray has sufficient space to store one more * entry. This has to be called before using NewPrivateRefCountEntry() to fill * a new entry - but it's perfectly fine to not use a reserved entry. */
| 228 | * a new entry - but it's perfectly fine to not use a reserved entry. |
| 229 | */ |
| 230 | static void |
| 231 | ReservePrivateRefCountEntry(void) |
| 232 | { |
| 233 | /* Already reserved (or freed), nothing to do */ |
| 234 | if (ReservedRefCountEntry != NULL) |
| 235 | return; |
| 236 | |
| 237 | /* |
| 238 | * First search for a free entry the array, that'll be sufficient in the |
| 239 | * majority of cases. |
| 240 | */ |
| 241 | { |
| 242 | int i; |
| 243 | |
| 244 | for (i = 0; i < REFCOUNT_ARRAY_ENTRIES; i++) |
| 245 | { |
| 246 | PrivateRefCountEntry *res; |
| 247 | |
| 248 | res = &PrivateRefCountArray[i]; |
| 249 | |
| 250 | if (res->buffer == InvalidBuffer) |
| 251 | { |
| 252 | ReservedRefCountEntry = res; |
| 253 | return; |
| 254 | } |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | /* |
| 259 | * No luck. All array entries are full. Move one array entry into the hash |
| 260 | * table. |
| 261 | */ |
| 262 | { |
| 263 | /* |
| 264 | * Move entry from the current clock position in the array into the |
| 265 | * hashtable. Use that slot. |
| 266 | */ |
| 267 | PrivateRefCountEntry *hashent; |
| 268 | bool found; |
| 269 | |
| 270 | /* select victim slot */ |
| 271 | ReservedRefCountEntry = |
| 272 | &PrivateRefCountArray[PrivateRefCountClock++ % REFCOUNT_ARRAY_ENTRIES]; |
| 273 | |
| 274 | /* Better be used, otherwise we shouldn't get here. */ |
| 275 | Assert(ReservedRefCountEntry->buffer != InvalidBuffer); |
| 276 | |
| 277 | /* enter victim array entry into hashtable */ |
| 278 | hashent = hash_search(PrivateRefCountHash, |
| 279 | (void *) &(ReservedRefCountEntry->buffer), |
| 280 | HASH_ENTER, |
| 281 | &found); |
| 282 | Assert(!found); |
| 283 | hashent->refcount = ReservedRefCountEntry->refcount; |
| 284 | |
| 285 | /* clear the now free array slot */ |
| 286 | ReservedRefCountEntry->buffer = InvalidBuffer; |
| 287 | ReservedRefCountEntry->refcount = 0; |
no test coverage detected