* @brief insert an object into the cache, * update the hash table and cache metadata * this function assumes the cache has enough space * eviction should be * performed before calling this function * * @param cache * @param req * @return the inserted object */
| 226 | * @return the inserted object |
| 227 | */ |
| 228 | static cache_obj_t *SR_LRU_insert(cache_t *cache, const request_t *req) { |
| 229 | // SR_LRU_insert covers the cases where hit in history or does not hit. |
| 230 | SR_LRU_params_t *params = (SR_LRU_params_t *)(cache->eviction_params); |
| 231 | |
| 232 | cache_obj_t *obj = NULL; |
| 233 | cache_t *R = params->R_list; |
| 234 | cache_t *SR = params->SR_list; |
| 235 | cache_t *H = params->H_list; |
| 236 | |
| 237 | bool ck_hist = H->find(H, req, false) != NULL; |
| 238 | |
| 239 | // If history hit |
| 240 | if (ck_hist) { |
| 241 | // Used to carry-over the new_obj flag |
| 242 | bool was_new = H->find(H, req, false)->SR_LRU.new_obj; |
| 243 | |
| 244 | // On a cache miss where x is in H, x is moved to the MRU position of R. |
| 245 | H->remove(H, req->obj_id); |
| 246 | |
| 247 | // If R list is full, move obj from R to SR. |
| 248 | while (R->get_occupied_byte(R) + req->obj_size + cache->obj_md_size > |
| 249 | R->cache_size) { |
| 250 | DEBUG_ASSERT(R->get_occupied_byte(R) != 0); |
| 251 | |
| 252 | cache_obj_t *evicted_obj = R->to_evict(R, req); |
| 253 | copy_cache_obj_to_request(params->req_local, evicted_obj); |
| 254 | SR->insert(SR, params->req_local); |
| 255 | |
| 256 | // Mark the obj as demoted |
| 257 | if (!evicted_obj->SR_LRU.demoted) { |
| 258 | params->C_demoted += 1; |
| 259 | // evicted_obj.SR_LRU.demoted = true; |
| 260 | SR->find(SR, params->req_local, false)->SR_LRU.demoted = true; |
| 261 | } |
| 262 | R->evict(R, req); |
| 263 | } |
| 264 | |
| 265 | R->insert(R, req); |
| 266 | obj = R->find(R, req, false); |
| 267 | obj->SR_LRU.new_obj = was_new; |
| 268 | |
| 269 | // Dynamic size adjustment |
| 270 | // If an obj is moved from H to R |
| 271 | // This means that SR cache size is too small and needs to be increases; |
| 272 | if (obj->SR_LRU.new_obj) { |
| 273 | DEBUG_ASSERT(params->C_new >= 1); |
| 274 | double delta; |
| 275 | if (1.0 > (int)(params->C_demoted / params->C_new) + 0.5) |
| 276 | delta = 1.0; |
| 277 | else |
| 278 | delta = (int)(params->C_demoted / params->C_new) + 0.5; |
| 279 | |
| 280 | if (SR->cache_size + delta > SR_LRU_get_occupied_byte(cache) - 1) |
| 281 | SR->cache_size = SR_LRU_get_occupied_byte(cache) - 1; |
| 282 | else |
| 283 | SR->cache_size += delta; |
| 284 | |
| 285 | R->cache_size = H->cache_size - SR->cache_size; |
no test coverage detected