include/cc_array.h (95 lines of code) (raw):
/*
* ccommon - a cache common library.
* Copyright (C) 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <cc_define.h>
#include <cc_debug.h>
#include <cc_option.h>
#include <stdint.h>
#include <stddef.h>
#define NELEM_DELTA 16
/* name type default description */
#define ARRAY_OPTION(ACTION) \
ACTION( array_nelem_delta, OPTION_TYPE_UINT, NELEM_DELTA, "max nelem delta during expansion" )
typedef struct {
ARRAY_OPTION(OPTION_DECLARE)
} array_options_st;
typedef int (*array_compare_fn)(const void *, const void *);
typedef rstatus_i (*array_each_fn)(void *, void *);
struct array {
size_t size; /* element size */
uint32_t nalloc; /* # allocated element */
uint32_t nelem; /* # element */
uint8_t *data; /* elements */
};
static inline size_t
array_size(const struct array *arr)
{
return arr->size;
}
static inline uint32_t
array_nalloc(const struct array *arr)
{
return arr->nalloc;
}
static inline uint32_t
array_nelem(const struct array *arr)
{
return arr->nelem;
}
static inline size_t
array_nfree(const struct array *arr)
{
return arr->nalloc - arr->nelem;
}
/* resets all fields in array to zero w/o freeing up any memory */
static inline void
array_reset(struct array *arr)
{
arr->size = 0;
arr->nalloc = 0;
arr->nelem = 0;
arr->data = NULL;
}
/* initialize arry of given size parameters and allocated data memory */
static inline void
array_data_assign(struct array *arr, uint32_t nalloc, size_t size, void *data)
{
arr->size = size;
arr->nalloc = nalloc;
arr->nelem = 0;
arr->data = data;
}
/**
* return the offset of element in terms of index in the whole array, if the
* element is out of bounds, return -1.
*/
static inline int
array_locate(struct array *arr, uint8_t *elem) {
int idx;
idx = (elem - arr->data) / arr->size;
if (idx < 0 || arr->data + idx * arr->size != elem) {
return -1;
} else {
return idx;
}
}
/* return the idx-th element by address */
static inline void *
array_get(struct array *arr, uint32_t idx) {
ASSERT(arr->nelem != 0 && idx < arr->nelem);
return arr->data + arr->size * idx;
}
static inline void *
array_first(struct array *arr) {
return array_get(arr, 0);
}
static inline void *
array_last(struct array *arr) {
return array_get(arr, arr->nelem - 1);
}
rstatus_i array_data_create(struct array *arr, uint32_t nalloc, size_t size);
void array_data_destroy(struct array *arr);
rstatus_i array_create(struct array **arr, uint32_t nalloc, size_t size);
void array_destroy(struct array **arr);
void *array_push(struct array *arr);
void *array_pop(struct array *arr);
void array_sort(struct array *arr, array_compare_fn compare);
uint32_t array_each(struct array *arr, array_each_fn func, void *arg, err_i *err);
/* TODO(yao): refactor to use better arg names */
void array_setup(array_options_st *options);
void array_teardown(void);
#ifdef __cplusplus
}
#endif