/**
 * @file hv_drv_OsdRadix.h
 * @brief Osd driver layer slots manager interface.
 * @verbatim
 * ==============================================================================
 *                        ##### How to use this driver #####
 * ==============================================================================
 * (+) Use Hv_Drv_OsdRadix_BuildTree(...) to build slots manager
 * (+) Use Hv_Drv_OsdRadix_DestroyTree(...) to destruct slots manager
 * (+) Use Hv_Drv_OsdRadix_GetEmptySlots(...) to get current empty slots
 * (+) Use Hv_Drv_OsdRadix_ExpandTree(...) to append slots to slots manager
 * (+) Use Hv_Drv_OsdRadix_AllocSlot(...) to alloc one slot
 * (+) Use Hv_Drv_OsdRadix_FreeSlot(...) to free one slot
 * @endverbatim
 *
 * @author HiView SoC Software Team
 * @version 0.0.1
 * @date 2022-08-22
 */

#ifndef _HV_DRV_OSDRADIXTREE_H
#define _HV_DRV_OSDRADIXTREE_H

#include "hv_drv_OsdTypes.h"

/**
 * @brief check if left child has more empty slots than right child
 * @param[in] pstTree slots manager structure
 * @return HV_TRUE if left has more empty slots, HV_FALSE otherwise.
 */
BOOL Hv_Drv_OsdRadix_IsLeftLeaned(OsdRadixTree *pstTree);

/**
 * @brief alloc one empty slot
 * @param[in] pstTree slots manager structure
 * @param[in] bFromRightHalf determine if alloc from right tree, used when bank total slots larger than 512
 * @param[out] pusSlot slot allocated
 * @return HV_TRUE alloc success, HV_FALSE otherwise
 */
BOOL Hv_Drv_OsdRadix_AllocSlot(OsdRadixTree *pstTree, BOOL bFromRightHalf, USHORT16 *pusSlot);

/**
 * @brief get last allocated slot
 * @param[in] pstTree slots manager structure
 * @return last successfully allocated slot
 */
USHORT16 Hv_Drv_OsdRadix_GetLastAllocatedSlot(OsdRadixTree *pstTree);

/**
 * @brief get current empty slots
 * @param[in] pstTree slots manager structure
 * @return empty slots count
 */
USHORT16 Hv_Drv_OsdRadix_GetEmptySlots(OsdRadixTree *pstTree);

/**
 * @brief get empty slots of right child
 * @param[in] pstTree slots manager structure
 * @return empty slots count of right tree
 */
USHORT16 Hv_Drv_OsdRadix_GetRightEmptySlots(OsdRadixTree *pstTree);

/**
 * @brief get empty slots of left child
 * @param[in] pstTree slots manager structure
 * @return empty slots count of left tree
 */
USHORT16 Hv_Drv_OsdRadix_GetLeftEmptySlots(OsdRadixTree *pstTree);

/**
 * @brief get total slots count
 * @param[in] pstTree slots manager structure
 * @return total slots count
 */
USHORT16 Hv_Drv_OsdRadix_GetTotalSlots(OsdRadixTree *pstTree);

/**
 * @brief free one slot
 * @param[in] pstTree slots manager structure
 * @param[in] usOff slots index
 * @return VOID without return
 */
VOID Hv_Drv_OsdRadix_FreeSlot(OsdRadixTree *pstTree, USHORT16 usOff);

/**
 * @brief create slots manager
 * @param[in] usTotalSlots total slots count to manage
 * @return slots manager structure if success, otherwise NULL
 */
OsdRadixTree *Hv_Drv_OsdRadix_BuildTree(USHORT16 usTotalSlots);

/**
 * @brief append slots to slots manager
 * @param[in] pstTree slots manager structure
 * @param[in] usSlots slots count to append
 * @return new slots manager structure if success, otherwise NULL
 */
OsdRadixTree* Hv_Drv_OsdRadix_ExpandTree(OsdRadixTree *pstTree, USHORT16 usSlots);

/**
 * @brief mark the first usSlots slots as allocated
 * @param[in] pstTree slots manager structure
 * @param[in] usSlots slots count to mark
 * @return VOID without return
 */
VOID Hv_Drv_OsdRadix_MarkSlots(OsdRadixTree *pstTree, USHORT16 usSlots);

/**
 * @brief destroy tree and free memory used by slots manager
 * @param[in] pstTree slots manager structure
 * @return VOID without return
 */
VOID Hv_Drv_OsdRadix_DestroyTree(OsdRadixTree *pstTree);

/**
 * @brief print out current slots manager, used for DEBUG
 * @param[in] pstTree slots manager structure
 * @return VOID without return
 */
VOID Hv_Drv_OsdRadix_PrintTree(OsdRadixTree *pstTree);

#endif
