/* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA"). * All rights reserved. * * This software is supplied "AS IS" without any warranties. * RDA assumes no responsibility or liability for the use of the software, * conveys no license or title under any patent, copyright, or mask work * right to the product. RDA reserves the right to make changes in the * software without notification. RDA also make no representation or * warranty that such application will be suitable for the specified use * without further testing or modification. */ #ifndef _OSI_ORDER_LIST_H_ #define _OSI_ORDER_LIST_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif /** * \brief opaque data struct for order list * * order list is a generic data struct for: * - Fixed memory size, allocated at creation. * - Use contiguous memory. So, the pointer of first can be casted into array. * - Record will be sorted at insert (similar to \p std::map). * - Record is unique (similar to \p std::map). * - User shall provide \p compar function (similar to \p bsearch) for sort. * - Provide API similar to \p std::lower_bound and \p std::upper_bound. * - Provide API to find EQ, LT, GT. * - Optionally replace smallest record on full. * * Typical usage is to keep a sorted history, and it is needed to search from * the history. */ typedef struct osiOrderList osiOrderList_t; /** * \brief create order list * * Signature of \p compar is the same as \p bsearch and \p qsort. * * \param size size of each record * \param compar record comparison function, return -1, 0, 1 * \param max_count maximum record count, can't be zero * \param replace whether to replace smallest on full * \return * - the created order list * - NULL if out of memory, or invalid parameter */ osiOrderList_t *osiOrderListCreate(unsigned size, int (*compar)(const void *, const void *), unsigned max_count, bool replace); /** * \brief delete the order list * * \param d the order list instance */ void osiOrderListDelete(osiOrderList_t *d); /** * \brief clear all records in order list * * \param d the order list instance */ void osiOrderListClear(osiOrderList_t *d); /** * \brief record count of order list * * \param d the order list instance * \return * - the record count */ unsigned osiOrderListCount(osiOrderList_t *d); /** * \brief insert a record into order list * * When there exists a record which will match \p val, that is \p compar * will return 0, the existed record will be updated, and the existed * record will be returned. * * When record count reaches \p max_count, there are 2 strategies at * inserting new record: * - When \p replace is true, the smallest one will be dropped; * - When \p replace is false, return false; * * \param d the order list instance * \param val value to be inserted * \return * - the inserted record * - NULL at full */ const void *osiOrderListInsert(osiOrderList_t *d, const void *val); /** * \brief the fist record in order list * * \param d the order list instance * \return * - the first (smallest) record * - NULL if the order list is empty */ const void *osiOrderListFirst(osiOrderList_t *d); /** * \brief the last record in order list * * \param d the order list instance * \return * - the last (largest) record * - NULL if the order list is empty */ const void *osiOrderListLast(osiOrderList_t *d); /** * \brief find record in order list * * Find the record: record >= key. When all records are less than * \p val, the last record will be return. In this case, * record < key. * * Refer to std::lower_bound. * * \param d the order list instance * \param val record for find * \return * - the lower bound record * - NULL if the order list is empty */ const void *osiOrderListLowerBound(osiOrderList_t *d, const void *val); /** * \brief find record in order list * * Find the record: record > key. When all records are less than * \p val, the last record will be return. In this case, * record <= key. * * Refer to std::upper_bound. * * \param d the order list instance * \param val key for find * \return * - the upper bound record * - NULL if the order list is empty */ const void *osiOrderListUpperBound(osiOrderList_t *d, const void *val); /** * \brief find record in order list * * Find the record: record == key. * * \param d the order list instance * \param val key for find * \return * - the match record * - NULL if the order list is empty, or no record matches */ const void *osiOrderListFind(osiOrderList_t *d, const void *val); /** * \brief find record in order list * * Find the record: record < key. When all records are greater or * equal than \p val, return NULL. * * \param d the order list instance * \param val key for find * \return * - the upper bound record * - NULL if the order list is empty, or no record matches */ const void *osiOrderListFindLT(osiOrderList_t *d, const void *val); /** * \brief find record in order list * * Find the record: record > key. When all records are smaller or * equal than \p val, return NULL. * * \param d the order list instance * \param val key for find * \return * - the upper bound record * - NULL if the order list is empty, or no record matches */ const void *osiOrderListFindGT(osiOrderList_t *d, const void *val); /** * \brief find record in order list * * Find the record: record <= key. When all records are greater or * equal than \p val, return NULL. * * \param d the order list instance * \param val key for find * \return * - the upper bound record * - NULL if the order list is empty, or no record matches */ const void *osiOrderListFindLE(osiOrderList_t *d, const void *val); /** * \brief find record in order list * * Find the record: record >= key. When all records are smaller or * equal than \p val, return NULL. * * \param d the order list instance * \param val key for find * \return * - the upper bound record * - NULL if the order list is empty, or no record matches */ const void *osiOrderListFindGE(osiOrderList_t *d, const void *val); /** * \brief helper function for unsigned integer compare * * Both \p a and \p b should be able to be casted into pointer of \p uint32_t, * and return the comparition of \p uint32_t. * * \param a comparison parameter * \param b comparison parameter * \return * - 1 if *(const uint32_t *)a > *(const uint32_t *)b * - 0 if *(const uint32_t *)a == *(const uint32_t *)b * - -1 if *(const uint32_t *)a < *(const uint32_t *)b */ int osiUintCompare(const void *a, const void *b); /** * \brief helper function for signed integer compare * * Both \p a and \p b should be able to be casted into pointer of \p int32_t, * and return the comparition of \p int32_t. * * \param a comparison parameter * \param b comparison parameter * \return * - 1 if *(const int32_t *)a > *(const int32_t *)b * - 0 if *(const int32_t *)a == *(const int32_t *)b * - -1 if *(const int32_t *)a < *(const int32_t *)b */ int osiIntCompare(const void *a, const void *b); #ifdef __cplusplus } #endif #endif