* @brief find an object in the cache * * @param cache * @param req * @param update_cache whether to update the cache, * if true, the object is promoted * and if the object is expired, it is removed from the cache * @return the object or NULL if not found */
| 217 | * @return the object or NULL if not found |
| 218 | */ |
| 219 | static cache_obj_t *ARC_find(cache_t *cache, const request_t *req, |
| 220 | const bool update_cache) { |
| 221 | ARC_params_t *params = (ARC_params_t *)(cache->eviction_params); |
| 222 | |
| 223 | cache_obj_t *obj = cache_find_base(cache, req, update_cache); |
| 224 | |
| 225 | if (!update_cache) { |
| 226 | return obj->ARC.ghost ? NULL : obj; |
| 227 | } |
| 228 | |
| 229 | if (obj == NULL) { |
| 230 | return NULL; |
| 231 | } |
| 232 | |
| 233 | params->curr_obj_in_L1_ghost = false; |
| 234 | params->curr_obj_in_L2_ghost = false; |
| 235 | |
| 236 | int lru_id = obj->ARC.lru_id; |
| 237 | cache_obj_t *ret = obj; |
| 238 | |
| 239 | if (obj->ARC.ghost) { |
| 240 | // ghost hit |
| 241 | ret = NULL; |
| 242 | params->vtime_last_req_in_ghost = cache->n_req; |
| 243 | // cache miss, but hit on thost |
| 244 | if (obj->ARC.lru_id == 1) { |
| 245 | params->curr_obj_in_L1_ghost = true; |
| 246 | // case II: x in L1_ghost |
| 247 | DEBUG_ASSERT(params->L1_ghost_size >= 1); |
| 248 | double delta = |
| 249 | MAX((double)params->L2_ghost_size / params->L1_ghost_size, 1); |
| 250 | params->p = MIN(params->p + delta, cache->cache_size); |
| 251 | params->L1_ghost_size -= obj->obj_size + cache->obj_md_size; |
| 252 | remove_obj_from_list(¶ms->L1_ghost_head, ¶ms->L1_ghost_tail, obj); |
| 253 | } else { |
| 254 | params->curr_obj_in_L2_ghost = true; |
| 255 | // case III: x in L2_ghost |
| 256 | DEBUG_ASSERT(params->L2_ghost_size >= 1); |
| 257 | double delta = |
| 258 | MAX((double)params->L1_ghost_size / params->L2_ghost_size, 1); |
| 259 | params->p = MAX(params->p - delta, 0); |
| 260 | params->L2_ghost_size -= obj->obj_size + cache->obj_md_size; |
| 261 | remove_obj_from_list(¶ms->L2_ghost_head, ¶ms->L2_ghost_tail, obj); |
| 262 | } |
| 263 | |
| 264 | hashtable_delete(cache->hashtable, obj); |
| 265 | } else { |
| 266 | // cache hit, case I: x in L1_data or L2_data |
| 267 | #ifdef USE_BELADY |
| 268 | if (obj->next_access_vtime == INT64_MAX) { |
| 269 | return ret; |
| 270 | } |
| 271 | #endif |
| 272 | |
| 273 | if (lru_id == 1) { |
| 274 | // move to LRU2 |
| 275 | obj->ARC.lru_id = 2; |
| 276 | remove_obj_from_list(¶ms->L1_data_head, ¶ms->L1_data_tail, obj); |
nothing calls this directly
no test coverage detected