LRU_CACHE_HANDLE lru_cache_create()

in src/lru_cache.c [59:146]


LRU_CACHE_HANDLE lru_cache_create(COMPUTE_HASH_FUNC compute_hash, KEY_COMPARE_FUNC key_compare_func, uint32_t initial_bucket_size, CLDS_HAZARD_POINTERS_HANDLE clds_hazard_pointers, int64_t capacity, LRU_CACHE_ON_ERROR_CALLBACK_FUNC on_error_callback, void* on_error_context)
{
    LRU_CACHE_HANDLE result;

    if (
        /*Codes_SRS_LRU_CACHE_13_001: [ If compute_hash is NULL, lru_cache_create shall fail and return NULL. ]*/
        (compute_hash == NULL) ||
        /*Codes_SRS_LRU_CACHE_13_002: [ If key_compare_func is NULL, lru_cache_create shall fail and return NULL. ]*/
        (key_compare_func == NULL) ||
        /*Codes_SRS_LRU_CACHE_13_003: [ If initial_bucket_size is 0, lru_cache_create shall fail and return NULL. ]*/
        (initial_bucket_size == 0) ||
        /*Codes_SRS_LRU_CACHE_13_004: [ If clds_hazard_pointers is NULL, lru_cache_create shall fail and return NULL. ]*/
        (clds_hazard_pointers == NULL) ||
        /*Codes_SRS_LRU_CACHE_13_010: [ If capacity is less than or equals to 0, then lru_cache_create shall fail and return NULL. ]*/
        (capacity <= 0) || 
        /*Codes_SRS_LRU_CACHE_13_079: [ If on_error_callback is NULL then lru_cache_create shall fail and return NULL. ]*/
        on_error_callback == NULL
        )
    {
        LogError("Invalid arguments: COMPUTE_HASH_FUNC compute_hash=%p, KEY_COMPARE_FUNC key_compare_func=%p, uint32_t initial_bucket_size=%u, CLDS_HAZARD_POINTERS_HANDLE clds_hazard_pointers=%p, int64_t capacity=%" PRId64 ", LRU_CACHE_ON_ERROR_CALLBACK_FUNC on_error_callback=%p, void* on_error_context=%p",
            compute_hash, key_compare_func, initial_bucket_size, clds_hazard_pointers, capacity, on_error_callback, on_error_context);
        result = NULL;
    }
    else
    {
        /*Codes_SRS_LRU_CACHE_13_011: [ lru_cache_create shall allocate memory for LRU_CACHE_HANDLE. ]*/
        LRU_CACHE_HANDLE lru_cache = malloc(sizeof(LRU_CACHE));
        if (lru_cache == NULL)
        {
            /*Codes_SRS_LRU_CACHE_13_020: [ If there are any failures then lru_cache_create shall fail and return NULL. ]*/
            LogError("malloc failed for LRU_CACHE_HANDLE");
        }
        else
        {
            /*Codes_SRS_LRU_CACHE_13_013: [ lru_cache_create shall assign clds_hazard_pointers to LRU_CACHE_HANDLE. ]*/
            lru_cache->clds_hazard_pointers = clds_hazard_pointers;

            /*Codes_SRS_LRU_CACHE_13_014: [ lru_cache_create shall allocate CLDS_HAZARD_POINTERS_THREAD_HELPER_HANDLE by calling clds_hazard_pointers_thread_helper_create. ]*/
            lru_cache->clds_hazard_pointers_thread_helper = clds_hazard_pointers_thread_helper_create(lru_cache->clds_hazard_pointers);
            if (lru_cache->clds_hazard_pointers_thread_helper == NULL)
            {
                /*Codes_SRS_LRU_CACHE_13_020: [ If there are any failures then lru_cache_create shall fail and return NULL. ]*/
                LogError("clds_hazard_pointers_thread_helper_create failed");
            }
            else
            {
                /*Codes_SRS_LRU_CACHE_13_015: [ lru_cache_create shall allocate clds_hash_table by calling clds_hash_table_create. ]*/
                lru_cache->table = clds_hash_table_create(compute_hash, key_compare_func, initial_bucket_size, lru_cache->clds_hazard_pointers, NULL, NULL, NULL);
                if (lru_cache->table == NULL)
                {
                    /*Codes_SRS_LRU_CACHE_13_020: [ If there are any failures then lru_cache_create shall fail and return NULL. ]*/
                    LogError("Cannot create table, clds_hash_table_create failed");
                }
                else
                {
                    /*Codes_SRS_LRU_CACHE_13_016: [ lru_cache_create shall initialize SRW_LOCK_LL by calling srw_lock_ll_init. ]*/
                    if (srw_lock_ll_init(&lru_cache->srw_lock) != 0)
                    {
                        /*Codes_SRS_LRU_CACHE_13_020: [ If there are any failures then lru_cache_create shall fail and return NULL. ]*/
                        LogError("failure in srw_lock_ll_init(&lru_cache->srw_lock);");
                    }
                    else
                    {
                        /*Codes_SRS_LRU_CACHE_13_017: [ lru_cache_create shall initialize the doubly linked list by calling DList_InitializeListHead. ]*/
                        DList_InitializeListHead(&(lru_cache->head));

                        /*Codes_SRS_LRU_CACHE_13_018: [ lru_cache_create shall assign 0 to current_size and the capacity to capacity. ]*/
                        lru_cache->current_size = 0;
                        lru_cache->capacity = capacity;

                        lru_cache->on_error_callback = on_error_callback;
                        lru_cache->on_error_context = on_error_context;

                        /*Codes_SRS_LRU_CACHE_13_019: [ On success, lru_cache_create shall return LRU_CACHE_HANDLE. ]*/
                        result = lru_cache;
                        goto all_ok;
                    }
                    clds_hash_table_destroy(lru_cache->table);
                }
                clds_hazard_pointers_thread_helper_destroy(lru_cache->clds_hazard_pointers_thread_helper);
            }
            free(lru_cache);
        }
        result = NULL;
    }
all_ok:
    return result;
}