LRU_CACHE_EVICT_RESULT lru_cache_evict()

in src/lru_cache.c [477:555]


LRU_CACHE_EVICT_RESULT lru_cache_evict(LRU_CACHE_HANDLE lru_cache, void* key)
{
    LRU_CACHE_EVICT_RESULT result;

    if (
        /*Codes_SRS_LRU_CACHE_13_085: [ If lru_cache is NULL, then lru_cache_evict shall fail and return LRU_CACHE_EVICT_ERROR. ]*/
        lru_cache == NULL ||
        /*Codes_SRS_LRU_CACHE_13_086: [ If key is NULL, then lru_cache_evict shall fail and return LRU_CACHE_EVICT_ERROR. ]*/
        key == NULL)
    {
        LogError("Invalid arguments: LRU_CACHE_HANDLE lru_cache=%p, void* key=%p", lru_cache, key);
        result = LRU_CACHE_EVICT_ERROR;
    }
    else
    {
        /*Codes_SRS_LRU_CACHE_13_087: [ lru_cache_evict shall get CLDS_HAZARD_POINTERS_THREAD_HANDLE by calling clds_hazard_pointers_thread_helper_get_thread. ]*/
        CLDS_HAZARD_POINTERS_THREAD_HANDLE hazard_pointers_thread = clds_hazard_pointers_thread_helper_get_thread(lru_cache->clds_hazard_pointers_thread_helper);
        if (hazard_pointers_thread == NULL)
        {
            /*Codes_SRS_LRU_CACHE_13_095: [ If there are any failures, lru_cache_get shall return LRU_CACHE_EVICT_ERROR. ]*/
            LogError("clds_hazard_pointers_thread_helper_get_thread failed");
            result = LRU_CACHE_EVICT_ERROR;
        }
        else
        {
            /*Codes_SRS_LRU_CACHE_13_088: [ lru_cache_evict shall acquire the lock in exclusive mode. ]*/
            srw_lock_ll_acquire_exclusive(&lru_cache->srw_lock);

            CLDS_HASH_TABLE_ITEM* old_item = NULL;

            /*Codes_SRS_LRU_CACHE_13_089: [ lru_cache_evict shall remove the key by calling clds_hash_table_remove on the key. ]*/
            CLDS_HASH_TABLE_REMOVE_RESULT remove_result = clds_hash_table_remove(lru_cache->table, hazard_pointers_thread, key, &old_item, NULL);

            if (remove_result == CLDS_HASH_TABLE_REMOVE_NOT_FOUND)
            {
                /*Codes_SRS_LRU_CACHE_13_093: [ If key is not found, lru_cache_evict shall return LRU_CACHE_EVICT_NOT_FOUND. ]*/
                result = LRU_CACHE_EVICT_NOT_FOUND;
                LogError("clds_hash_table_remove returned (%" PRI_MU_ENUM ") for key = %p.", MU_ENUM_VALUE(CLDS_HASH_TABLE_REMOVE_RESULT, remove_result), key);
            }
            else if (remove_result != CLDS_HASH_TABLE_REMOVE_OK)
            {
                result = LRU_CACHE_EVICT_ERROR;
                /*Codes_SRS_LRU_CACHE_13_095: [ If there are any failures, lru_cache_get shall return LRU_CACHE_EVICT_ERROR. ]*/
                LogError("clds_hash_table_delete_key_value returned (%" PRI_MU_ENUM ").", MU_ENUM_VALUE(CLDS_HASH_TABLE_REMOVE_RESULT, remove_result));
            }
            else
            {
                if (old_item != NULL)
                {
                    /*Codes_SRS_LRU_CACHE_13_090: [ If the key is removed: ]*/

                    LRU_NODE* current_item = CLDS_HASH_TABLE_GET_VALUE(LRU_NODE, old_item);
                    PDLIST_ENTRY node = &(current_item->node);

                    /*Codes_SRS_LRU_CACHE_13_096: [ lru_cache_evict shall update the current_size by subtracting the removed old value size. ]*/
                    (void)interlocked_add_64(&lru_cache->current_size, -current_item->size);

                    /*Codes_SRS_LRU_CACHE_13_091: [ lru_cache_evict shall remove the old value node from doubly_linked_list by calling DList_RemoveEntryList. ]*/
                    DList_RemoveEntryList(node);

                    CLDS_HASH_TABLE_NODE_RELEASE(LRU_NODE, old_item);

                    /*Codes_SRS_LRU_CACHE_13_092: [ On success, lru_cache_evict shall return LRU_CACHE_EVICT_OK. ]*/
                    result = LRU_CACHE_EVICT_OK;
                }
                else
                {
                    LogError("something went wrong. clds_hash_table_remove returned (%" PRI_MU_ENUM ") but old_item is NULL.", MU_ENUM_VALUE(CLDS_HASH_TABLE_REMOVE_RESULT, remove_result));
                    /*Codes_SRS_LRU_CACHE_13_095: [ If there are any failures, lru_cache_get shall return LRU_CACHE_EVICT_ERROR. ]*/
                    result = LRU_CACHE_EVICT_ERROR;
                }
            }
            /*Codes_SRS_LRU_CACHE_13_094: [ lru_cache_evict shall release the lock in exclusive mode. ]*/
            srw_lock_ll_release_exclusive(&lru_cache->srw_lock);
        }
    }

    return result;
}