/** * Returns a new empty deque based on the specified DequeConf object. * * The deque is allocated using the allocators specified the DequeConf object * The allocation may fail if the underlying allocator fails. * * @param[in] conf Deque configuration object. All fields must be initialized * appropriate values. * * @return a new deque if the allocation was successful, or NULL if not. */ Deque *deque_new_conf(DequeConf *conf) { Deque *deque = conf->mem_calloc(1, sizeof(Deque)); if (deque == NULL) return NULL; deque->mem_alloc = conf->mem_alloc; deque->mem_calloc = conf->mem_calloc; deque->mem_free = conf->mem_free; deque->capacity = upper_pow_two(conf->capacity); deque->first = 0; deque->last = 0; deque->size = 0; deque->buffer = deque->mem_alloc(deque->capacity * sizeof(void*)); return deque; }
/** * Trims the capacity of the deque to a power of 2 that is the nearest to * the number of elements in the deque. * * @param[in] deque the deque on which this operation is being performed */ void deque_trim_capacity(Deque *deque) { if (deque->capacity == deque->size) return; size_t new_size = upper_pow_two(deque->size); if (new_size == deque->capacity) return; void **new_buff = deque->mem_alloc(sizeof(void*) * new_size); copy_buffer(deque, new_buff, NULL); deque->buffer = new_buff; deque->first = 0; deque->last = deque->size; deque->capacity = new_size; }
/** * Creates a new empty Deque based on the specified DequeConf object and * returns a status code. * * The Deque is allocated using the allocators specified in the DequeConf struct. * The allocation may fail if the underlying allocator fails. * * @param[in] conf Deque configuration structure. All fields must be initialized * with appropriate values. * @param[out] out Pointer to where the newly created Deque is to be stored * * @return CC_OK if the creation was successful, CC_ERR_INVALID_CAPACITY if * the above mentioned condition is not met, or CC_ERR_ALLOC if the memory * allocation for the new Deque structure failed. */ enum cc_stat deque_new_conf(DequeConf const * const conf, Deque **d) { Deque *deque = conf->mem_calloc(1, sizeof(Deque)); if (!deque) return CC_ERR_ALLOC; if (!(deque->buffer = conf->mem_alloc(conf->capacity * sizeof(void*)))) { conf->mem_free(deque); return CC_ERR_ALLOC; } deque->mem_alloc = conf->mem_alloc; deque->mem_calloc = conf->mem_calloc; deque->mem_free = conf->mem_free; deque->capacity = upper_pow_two(conf->capacity); deque->first = 0; deque->last = 0; deque->size = 0; *d = deque; return CC_OK; }
/** * Trims the capacity of the deque to a power of 2 that is the nearest * upper power of 2 to the number of elements in the deque. * * @param[in] deque Deque whose capacity is being trimmed * * @return CC_OK if the capacity was trimmed successfully, or CC_ERR_ALLOC if * the reallocation failed. */ enum cc_stat deque_trim_capacity(Deque *deque) { if (deque->capacity == deque->size) return CC_OK; size_t new_size = upper_pow_two(deque->size); if (new_size == deque->capacity) return CC_OK; void **new_buff = deque->mem_alloc(sizeof(void*) * new_size); if (!new_buff) return CC_ERR_ALLOC; copy_buffer(deque, new_buff, NULL); deque->mem_free(deque->buffer); deque->buffer = new_buff; deque->first = 0; deque->last = deque->size; deque->capacity = new_size; return CC_OK; }